-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1965 from vega/next
Release
- Loading branch information
Showing
27 changed files
with
931 additions
and
475 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
/*.ts | ||
coverage/ | ||
dist/ | ||
cjs/ | ||
node_modules/ | ||
!auto.config.ts | ||
/.idea/ | ||
|
||
# local config for auto | ||
.env | ||
|
||
# Other package managers | ||
pnpm-lock.yaml | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import ts from "typescript"; | ||
import { Context, type NodeParser } from "../NodeParser.js"; | ||
import type { SubNodeParser } from "../SubNodeParser.js"; | ||
import { AliasType } from "../Type/AliasType.js"; | ||
import type { BaseType } from "../Type/BaseType.js"; | ||
import { DefinitionType } from "../Type/DefinitionType.js"; | ||
import { getKey } from "../Utils/nodeKey.js"; | ||
|
||
/** | ||
* Needs to be registered before 261, 260, 230, 262 node kinds | ||
*/ | ||
export class PromiseNodeParser implements SubNodeParser { | ||
public constructor( | ||
protected typeChecker: ts.TypeChecker, | ||
protected childNodeParser: NodeParser, | ||
) {} | ||
|
||
public supportsNode(node: ts.Node): boolean { | ||
if ( | ||
// 261 interface PromiseInterface extends Promise<T> | ||
!ts.isInterfaceDeclaration(node) && | ||
// 260 class PromiseClass implements Promise<T> | ||
!ts.isClassDeclaration(node) && | ||
// 230 Promise<T> | ||
!ts.isExpressionWithTypeArguments(node) && | ||
// 262 type PromiseAlias = Promise<T>; | ||
!ts.isTypeAliasDeclaration(node) | ||
) { | ||
return false; | ||
} | ||
|
||
const type = this.typeChecker.getTypeAtLocation(node); | ||
|
||
const awaitedType = this.typeChecker.getAwaitedType(type); | ||
|
||
// ignores non awaitable types | ||
if (!awaitedType) { | ||
return false; | ||
} | ||
|
||
// If the awaited type differs from the original type, the type extends promise | ||
// Awaited<Promise<T>> -> T (Promise<T> !== T) | ||
// Awaited<Y> -> Y (Y === Y) | ||
if (awaitedType === type) { | ||
return false; | ||
} | ||
|
||
// In types like: A<T> = T, type C = A<1>, C has the same type as A<1> and 1, | ||
// the awaitedType is NOT the same reference as the type, so a assignability | ||
// check is needed | ||
return ( | ||
!this.typeChecker.isTypeAssignableTo(type, awaitedType) && | ||
!this.typeChecker.isTypeAssignableTo(awaitedType, type) | ||
); | ||
} | ||
|
||
public createType( | ||
node: ts.InterfaceDeclaration | ts.ClassDeclaration | ts.ExpressionWithTypeArguments | ts.TypeAliasDeclaration, | ||
context: Context, | ||
): BaseType { | ||
const type = this.typeChecker.getTypeAtLocation(node); | ||
const awaitedType = this.typeChecker.getAwaitedType(type)!; // supportsNode ensures this | ||
const awaitedNode = this.typeChecker.typeToTypeNode(awaitedType, undefined, ts.NodeBuilderFlags.IgnoreErrors); | ||
|
||
if (!awaitedNode) { | ||
throw new Error( | ||
`Could not find awaited node for type ${node.pos === -1 ? "<unresolved>" : node.getText()}`, | ||
); | ||
} | ||
|
||
const baseNode = this.childNodeParser.createType(awaitedNode, new Context(node)); | ||
|
||
const name = this.getNodeName(node); | ||
|
||
// Nodes without name should just be their awaited type | ||
// export class extends Promise<T> {} -> T | ||
// export class A extends Promise<T> {} -> A (ref to T) | ||
if (!name) { | ||
return baseNode; | ||
} | ||
|
||
return new DefinitionType(name, new AliasType(`promise-${getKey(node, context)}`, baseNode)); | ||
} | ||
|
||
private getNodeName( | ||
node: ts.InterfaceDeclaration | ts.ClassDeclaration | ts.ExpressionWithTypeArguments | ts.TypeAliasDeclaration, | ||
) { | ||
if (ts.isExpressionWithTypeArguments(node)) { | ||
if (!ts.isHeritageClause(node.parent)) { | ||
throw new Error("Expected ExpressionWithTypeArguments to have a HeritageClause parent"); | ||
} | ||
|
||
return node.parent.parent.name?.getText(); | ||
} | ||
|
||
return node.name?.getText(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.