Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract node type printer #59282

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,158 changes: 335 additions & 823 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

1,057 changes: 917 additions & 140 deletions src/compiler/expressionToTypeNode.ts

Large diffs are not rendered by default.

128 changes: 44 additions & 84 deletions src/compiler/transformers/declarations.ts

Large diffs are not rendered by default.

45 changes: 39 additions & 6 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5376,7 +5376,6 @@ export const enum NodeBuilderFlags {
AllowUniqueESSymbolType = 1 << 20,
AllowEmptyIndexInfoType = 1 << 21,
/** @internal */ WriteComputedProps = 1 << 30, // { [E.A]: 1 }
/** @internal */ NoSyntacticPrinter = 1 << 31,
// Errors (cont.)
AllowNodeModulesRelativePaths = 1 << 26,
/** @internal */ DoNotIncludeSymbolChain = 1 << 27, // Skip looking up and printing an accessible symbol chain
Expand Down Expand Up @@ -5723,9 +5722,9 @@ export interface EmitResolver {
requiresAddingImplicitUndefined(node: ParameterDeclaration): boolean;
isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean;
getPropertiesOfContainerFunction(node: Declaration): Symbol[];
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createTypeOfDeclaration(declaration: HasInferredType, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression;
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags | undefined, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
Expand Down Expand Up @@ -10249,6 +10248,7 @@ export interface EvaluationResolver {
/** @internal */
export type HasInferredType =
| PropertyAssignment
| ShorthandPropertyAssignment
| PropertyAccessExpression
| BinaryExpression
| ElementAccessExpression
Expand All @@ -10257,20 +10257,53 @@ export type HasInferredType =
| BindingElement
| PropertyDeclaration
| PropertySignature
| ExportAssignment;
| ExportAssignment
| JSDocPropertyTag
| JSDocParameterTag;

/** @internal */
export interface SyntacticTypeNodeBuilderContext {
flags: NodeBuilderFlags;
tracker: Required<Pick<SymbolTracker, "reportInferenceFallback">>;
enclosingFile: SourceFile | undefined;
enclosingDeclaration: Node | undefined;
approximateLength: number;
noInferenceFallback?: boolean;
}

/** @internal */
export interface SyntacticTypeNodeBuilderResolver {
isOptionalParameter(p: ParameterDeclaration): boolean;
isUndefinedIdentifierExpression(name: Identifier): boolean;
isExpandoFunctionDeclaration(name: FunctionDeclaration | VariableDeclaration): boolean;
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node, shouldComputeAliasToMakeVisible?: boolean): SymbolVisibilityResult;
requiresAddingImplicitUndefined(parameter: ParameterDeclaration | JSDocParameterTag): boolean;
isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean;
}
isEntityNameVisible(context: SyntacticTypeNodeBuilderContext, entityName: EntityNameOrEntityNameExpression, shouldComputeAliasToMakeVisible?: boolean): SymbolVisibilityResult;
serializeExistingTypeNode(context: SyntacticTypeNodeBuilderContext, node: TypeNode, addUndefined?: boolean): TypeNode | undefined;
serializeReturnTypeForSignature(context: SyntacticTypeNodeBuilderContext, signatureDeclaration: SignatureDeclaration | JSDocSignature): TypeNode | undefined;
serializeTypeOfExpression(context: SyntacticTypeNodeBuilderContext, expr: Expression): TypeNode;
serializeTypeOfDeclaration(context: SyntacticTypeNodeBuilderContext, node: HasInferredType): TypeNode | undefined;
serializeNameOfParameter(context: SyntacticTypeNodeBuilderContext, parameter: ParameterDeclaration): BindingName | string;
serializeTypeName(context: SyntacticTypeNodeBuilderContext, node: EntityName, isTypeOf?: boolean, typeArguments?: readonly TypeNode[]): TypeNode | undefined;
serializeEntityName(context: SyntacticTypeNodeBuilderContext, node: EntityNameExpression): Expression | undefined;
getJsDocPropertyOverride(context: SyntacticTypeNodeBuilderContext, jsDocTypeLiteral: JSDocTypeLiteral, jsDocProperty: JSDocPropertyLikeTag): TypeNode | undefined;
enterNewScope(context: SyntacticTypeNodeBuilderContext, node: IntroducesNewScopeNode | ConditionalTypeNode): () => void;
markNodeReuse<T extends Node>(context: SyntacticTypeNodeBuilderContext, range: T, location: Node | undefined): T;
trackExistingEntityName<T extends EntityNameOrEntityNameExpression>(context: SyntacticTypeNodeBuilderContext, node: T): { introducesError: boolean; node: T; };
trackComputedName(context: SyntacticTypeNodeBuilderContext, accessExpression: EntityNameOrEntityNameExpression): void;
evaluateEntityNameExpression(expression: EntityNameExpression): EvaluatorResult;
getModuleSpecifierOverride(context: SyntacticTypeNodeBuilderContext, parent: ImportTypeNode, lit: StringLiteral): string | undefined;
canReuseTypeNode(context: SyntacticTypeNodeBuilderContext, existing: TypeNode): boolean;
shouldRemoveDeclaration(context: SyntacticTypeNodeBuilderContext, node: DynamicNamedDeclaration): boolean;
hasLateBindableName(node: Declaration): node is LateBoundDeclaration | LateBoundBinaryExpressionDeclaration;
createRecoveryBoundary(context: SyntacticTypeNodeBuilderContext): {
startRecoveryScope(): () => void;
finalizeBoundary(): boolean;
markError(): void;
hadError(): boolean;
};
}

/** @internal */
export type IntroducesNewScopeNode = SignatureDeclaration | JSDocSignature | MappedTypeNode;
11 changes: 11 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ import {
InterfaceDeclaration,
InternalEmitFlags,
InternalSymbolName,
IntroducesNewScopeNode,
isAccessor,
isAnyDirectorySeparator,
isArray,
Expand Down Expand Up @@ -315,6 +316,7 @@ import {
isLeftHandSideExpression,
isLineBreak,
isLiteralTypeNode,
isMappedTypeNode,
isMemberName,
isMetaProperty,
isMethodDeclaration,
Expand Down Expand Up @@ -11680,9 +11682,18 @@ export function hasInferredType(node: Node): node is HasInferredType {
case SyntaxKind.VariableDeclaration:
case SyntaxKind.ExportAssignment:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.JSDocParameterTag:
case SyntaxKind.JSDocPropertyTag:
return true;
default:
assertType<never>(node);
return false;
}
}
/** @internal */
export function isNewScopeNode(node: Node): node is IntroducesNewScopeNode {
return isFunctionLike(node)
|| isJSDocSignature(node)
|| isMappedTypeNode(node);
}
4 changes: 2 additions & 2 deletions tests/baselines/reference/ambientConstLiterals.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ declare const c9: {
declare const c10: number[];
declare const c11: string;
declare const c12: number;
declare const c13: string;
declare const c14: number;
declare const c13: "abc" | "def";
declare const c14: 123 | 456;
Comment on lines +77 to +78
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to reintroduce the widening problem we've previously discussed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did notice this, but I think this is actually a bug. Hovering over those variables in the playground shows the union on hover while the declarations show string and number.

Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ var a = () => <Error>{ name: "foo", message: "bar" };

var b = () => (<Error>{ name: "foo", message: "bar" });
>b : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>() => (<Error>{ name: "foo", message: "bar" }) : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>(<Error>{ name: "foo", message: "bar" }) : Error
> : ^^^^^
><Error>{ name: "foo", message: "bar" } : Error
Expand Down Expand Up @@ -59,9 +59,9 @@ var c = () => ({ name: "foo", message: "bar" });

var d = () => ((<Error>({ name: "foo", message: "bar" })));
>d : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>() => ((<Error>({ name: "foo", message: "bar" }))) : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>((<Error>({ name: "foo", message: "bar" }))) : Error
> : ^^^^^
>(<Error>({ name: "foo", message: "bar" })) : Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ var a = () => <Error>{ name: "foo", message: "bar" };

var b = () => (<Error>{ name: "foo", message: "bar" });
>b : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>() => (<Error>{ name: "foo", message: "bar" }) : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>(<Error>{ name: "foo", message: "bar" }) : Error
> : ^^^^^
><Error>{ name: "foo", message: "bar" } : Error
Expand Down Expand Up @@ -59,9 +59,9 @@ var c = () => ({ name: "foo", message: "bar" });

var d = () => ((<Error>({ name: "foo", message: "bar" })));
>d : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>() => ((<Error>({ name: "foo", message: "bar" }))) : () => Error
> : ^^^^^^^^^^^
> : ^^^^^^
>((<Error>({ name: "foo", message: "bar" }))) : Error
> : ^^^^^
>(<Error>({ name: "foo", message: "bar" })) : Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ assignmentCompatWithCallSignatures3.ts(77,1): error TS2322: Type '(x: { foo: str
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
Property 'bar' is missing in type 'Base' but required in type '{ foo: string; bar: string; }'.
assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Array<Base>>(x: Base[], y: T) => Derived[]'.
assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type '<T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>'.
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Array<Derived>>(x: Base[], y: T) => T'.
assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Array<Base>, y: Array<Derived>) => Array<Derived>' is not assignable to type '<T extends Array<Derived>>(x: Array<Base>, y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
assignmentCompatWithCallSignatures3.ts(85,1): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => Object'.
Expand Down Expand Up @@ -204,7 +204,7 @@ assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: strin
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Array<Base>>(x: Base[], y: T) => Derived[]'.
!!! error TS2322: Type '(x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type '<T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
Expand All @@ -213,7 +213,7 @@ assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: strin
a13 = b13; // ok
b13 = a13; // ok
~~~
!!! error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Array<Derived>>(x: Base[], y: T) => T'.
!!! error TS2322: Type '(x: Array<Base>, y: Array<Derived>) => Array<Derived>' is not assignable to type '<T extends Array<Derived>>(x: Array<Base>, y: T) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
!!! error TS2322: 'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
var b14: <T>(x: { a: T; b: T }) => T;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ assignmentCompatWithCallSignatures4.ts(58,9): error TS2322: Type '(...x: Base[])
assignmentCompatWithCallSignatures4.ts(62,9): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Derived>(x: T, y: T) => T'.
Type 'Base' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.
assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Array<Derived2>>(x: Base[], y: Base[]) => T'.
assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type '<T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T'.
Type 'Derived[]' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Derived[]'.
assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
Expand Down Expand Up @@ -163,7 +163,7 @@ assignmentCompatWithCallSignatures4.ts(96,9): error TS2322: Type '<T>(x: T) => s
a12 = b12;
b12 = a12;
~~~
!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Array<Derived2>>(x: Base[], y: Base[]) => T'.
!!! error TS2322: Type '(x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type '<T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Derived[]'.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ assignmentCompatWithConstructSignatures3.ts(77,1): error TS2322: Type 'new (x: {
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
Property 'bar' is missing in type 'Base' but required in type '{ foo: string; bar: string; }'.
assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Array<Base>>(x: Base[], y: T) => Derived[]'.
assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type 'new <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>'.
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is missing the following properties from type 'Derived2': baz, bar
assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Array<Derived>>(x: Base[], y: T) => T'.
assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Array<Base>, y: Array<Derived>) => Array<Derived>' is not assignable to type 'new <T extends Array<Derived>>(x: Array<Base>, y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
assignmentCompatWithConstructSignatures3.ts(85,1): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => Object'.
Expand Down Expand Up @@ -204,7 +204,7 @@ assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: {
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Array<Base>>(x: Base[], y: T) => Derived[]'.
!!! error TS2322: Type 'new (x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type 'new <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
Expand All @@ -213,7 +213,7 @@ assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: {
a13 = b13; // ok
b13 = a13; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Array<Derived>>(x: Base[], y: T) => T'.
!!! error TS2322: Type 'new (x: Array<Base>, y: Array<Derived>) => Array<Derived>' is not assignable to type 'new <T extends Array<Derived>>(x: Array<Base>, y: T) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
!!! error TS2322: 'Derived[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived[]'.
var b14: new <T>(x: { a: T; b: T }) => T;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ assignmentCompatWithConstructSignatures4.ts(58,9): error TS2322: Type 'new (...x
assignmentCompatWithConstructSignatures4.ts(62,9): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Derived>(x: T, y: T) => T'.
Type 'Base' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.
assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Array<Derived2>>(x: Base[], y: Base[]) => T'.
assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type 'new <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T'.
Type 'Derived[]' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Derived[]'.
assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Expand Down Expand Up @@ -179,7 +179,7 @@ assignmentCompatWithConstructSignatures4.ts(96,9): error TS2322: Type 'new <T>(x
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Array<Derived2>>(x: Base[], y: Base[]) => T'.
!!! error TS2322: Type 'new (x: Array<Base>, y: Array<Derived2>) => Array<Derived>' is not assignable to type 'new <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Derived[]'.

Expand Down
Loading
Loading