Skip to content

Commit

Permalink
Extract node type printer (#59282)
Browse files Browse the repository at this point in the history
  • Loading branch information
dragomirtitian authored Sep 30, 2024
1 parent 2c23bea commit 476e9ee
Show file tree
Hide file tree
Showing 96 changed files with 1,984 additions and 1,504 deletions.
1,189 changes: 380 additions & 809 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -6998,7 +6998,7 @@
"category": "Error",
"code": 9008
},
"At least one accessor must have an explicit return type annotation with --isolatedDeclarations.": {
"At least one accessor must have an explicit type annotation with --isolatedDeclarations.": {
"category": "Error",
"code": 9009
},
Expand Down
1,136 changes: 982 additions & 154 deletions src/compiler/expressionToTypeNode.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,7 @@ export function createAccessorPropertySetRedirector(factory: NodeFactory, node:
}

/** @internal */
export function findComputedPropertyNameCacheAssignment(name: ComputedPropertyName) {
export function findComputedPropertyNameCacheAssignment(name: ComputedPropertyName): AssignmentExpression<EqualsToken> & { readonly left: GeneratedIdentifier; } | undefined {
let node = name.expression;
while (true) {
node = skipOuterExpressions(node);
Expand Down
126 changes: 43 additions & 83 deletions src/compiler/transformers/declarations.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/compiler/transformers/declarations/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,8 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver): (nod
[SyntaxKind.ArrowFunction]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
[SyntaxKind.MethodDeclaration]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
[SyntaxKind.ConstructSignature]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
[SyntaxKind.GetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
[SyntaxKind.SetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
[SyntaxKind.GetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
[SyntaxKind.SetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
[SyntaxKind.Parameter]: Diagnostics.Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
[SyntaxKind.VariableDeclaration]: Diagnostics.Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
[SyntaxKind.PropertyDeclaration]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
Expand Down
57 changes: 43 additions & 14 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5849,7 +5849,7 @@ export interface EmitResolver {
requiresAddingImplicitUndefined(node: ParameterDeclaration, enclosingDeclaration: Node | undefined): boolean;
isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean;
getPropertiesOfContainerFunction(node: Declaration): Symbol[];
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createTypeOfDeclaration(declaration: HasInferredType, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression;
Expand Down Expand Up @@ -10504,37 +10504,66 @@ export interface EvaluationResolver {

/** @internal */
export type HasInferredType =
| PropertyAssignment
| Exclude<VariableLikeDeclaration, JsxAttribute | EnumMember>
| PropertyAccessExpression
| BinaryExpression
| ElementAccessExpression
| VariableDeclaration
| ParameterDeclaration
| BindingElement
| PropertyDeclaration
| PropertySignature
| BinaryExpression
| ExportAssignment;

/** @internal */
export interface SyntacticTypeNodeBuilderContext {
flags: NodeBuilderFlags;
tracker: Required<Pick<SymbolTracker, "reportInferenceFallback">>;
enclosingFile: SourceFile | undefined;
enclosingDeclaration: Node | undefined;
approximateLength: number;
noInferenceFallback?: boolean;
suppressReportInferenceFallback: 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, enclosingDeclaration: Node | undefined): boolean;
requiresAddingImplicitUndefined(declaration: ParameterDeclaration | PropertySignature | JSDocParameterTag | JSDocPropertyTag | PropertyDeclaration, symbol: Symbol | undefined, enclosingDeclaration: Node | undefined): 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 | GetAccessorDeclaration | SetAccessorDeclaration, symbol: Symbol | undefined): 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;
canReuseTypeNodeAnnotation(context: SyntacticTypeNodeBuilderContext, node: Declaration, existing: TypeNode, symbol: Symbol | undefined, requiresAddingUndefined?: boolean): 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 interface SyntacticNodeBuilder {
typeFromExpression: (node: Expression, context: SyntacticTypeNodeBuilderContext, isConstContext?: boolean, requiresAddingUndefined?: boolean, preserveLiterals?: boolean) => boolean | undefined;
serializeTypeOfDeclaration: (node: HasInferredType, context: SyntacticTypeNodeBuilderContext) => boolean | undefined;
serializeReturnTypeForSignature: (node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext) => boolean | undefined;
serializeTypeOfExpression: (expr: Expression, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) => boolean;
serializeTypeOfDeclaration: (node: HasInferredType, symbol: Symbol, context: SyntacticTypeNodeBuilderContext) => TypeNode | undefined;
serializeReturnTypeForSignature: (signature: SignatureDeclaration | JSDocSignature, symbol: Symbol, context: SyntacticTypeNodeBuilderContext) => TypeNode | undefined;
serializeTypeOfExpression: (expr: Expression | JsxAttributeValue, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) => TypeNode;
tryReuseExistingTypeNode: (context: SyntacticTypeNodeBuilderContext, existing: TypeNode) => TypeNode | undefined;
serializeTypeOfAccessor: (accessor: AccessorDeclaration, symbol: Symbol, context: SyntacticTypeNodeBuilderContext) => TypeNode | undefined;
}

/** @internal */
export type IntroducesNewScopeNode = SignatureDeclaration | JSDocSignature | MappedTypeNode;
16 changes: 11 additions & 5 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ import {
InterfaceDeclaration,
InternalEmitFlags,
InternalSymbolName,
IntroducesNewScopeNode,
isAccessor,
isAnyDirectorySeparator,
isArray,
Expand Down Expand Up @@ -322,6 +323,7 @@ import {
isLeftHandSideExpression,
isLineBreak,
isLiteralTypeNode,
isMappedTypeNode,
isMemberName,
isMetaProperty,
isMethodDeclaration,
Expand Down Expand Up @@ -2920,11 +2922,6 @@ export function isVariableLike(node: Node): node is VariableLikeDeclaration {
return false;
}

/** @internal */
export function isVariableLikeOrAccessor(node: Node): node is AccessorDeclaration | VariableLikeDeclaration {
return isVariableLike(node) || isAccessor(node);
}

/** @internal */
export function isVariableDeclarationInVariableStatement(node: VariableDeclaration): boolean {
return node.parent.kind === SyntaxKind.VariableDeclarationList
Expand Down Expand Up @@ -11938,6 +11935,9 @@ 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);
Expand Down Expand Up @@ -12077,3 +12077,9 @@ function getNodeAtPosition(sourceFile: SourceFile, position: number, includeJSDo
current = child;
}
}
/** @internal */
export function isNewScopeNode(node: Node): node is IntroducesNewScopeNode {
return isFunctionLike(node)
|| isJSDocSignature(node)
|| isMappedTypeNode(node);
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const extractExpression = "extract-expression";
const errorCodes = [
Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations.code,
Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations.code,
Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations.code,
Diagnostics.At_least_one_accessor_must_have_an_explicit_type_annotation_with_isolatedDeclarations.code,
Diagnostics.Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations.code,
Diagnostics.Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations.code,
Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations.code,
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 @@ -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
20 changes: 10 additions & 10 deletions tests/baselines/reference/circularAccessorAnnotations.types
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

=== circularAccessorAnnotations.ts ===
declare const c1: {
>c1 : { readonly foo: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^
>c1 : { readonly foo: typeof c1.foo; }
> : ^^^^^^^^^^^^^^^^ ^^^

get foo(): typeof c1.foo;
>foo : any
> : ^^^
>c1.foo : any
> : ^^^
>c1 : { readonly foo: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^
>c1 : { readonly foo: typeof c1.foo; }
> : ^^^^^^^^^^^^^^^^ ^^^
>foo : any
> : ^^^
}

declare const c2: {
>c2 : { foo: any; }
> : ^^^^^^^^^^^^^
>c2 : { foo: typeof c2.foo; }
> : ^^^^^^^ ^^^

set foo(value: typeof c2.foo);
>foo : any
Expand All @@ -27,15 +27,15 @@ declare const c2: {
> : ^^^
>c2.foo : any
> : ^^^
>c2 : { foo: any; }
> : ^^^^^^^^^^^^^
>c2 : { foo: typeof c2.foo; }
> : ^^^^^^^ ^^^
>foo : any
> : ^^^
}

declare const c3: {
>c3 : { foo: string; }
> : ^^^^^^^^^^^^^^^^
> : ^^^^^^^ ^^^

get foo(): string;
>foo : string
Expand All @@ -49,7 +49,7 @@ declare const c3: {
>c3.foo : string
> : ^^^^^^
>c3 : { foo: string; }
> : ^^^^^^^^^^^^^^^^
> : ^^^^^^^ ^^^
>foo : string
> : ^^^^^^
}
Expand Down
12 changes: 6 additions & 6 deletions tests/baselines/reference/circularObjectLiteralAccessors.types
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

const a = {
>a : { b: { foo: string; }; foo: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
>{ b: { get foo(): string { return a.foo; }, set foo(value: string) { a.foo = value; } }, foo: ''} : { b: { foo: string; }; foo: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

b: {
>b : { foo: string; }
> : ^^^^^^^^^^^^^^^^
> : ^^^^^^^ ^^^
>{ get foo(): string { return a.foo; }, set foo(value: string) { a.foo = value; } } : { foo: string; }
> : ^^^^^^^^^^^^^^^^
> : ^^^^^^^ ^^^

get foo(): string {
>foo : string
Expand All @@ -23,7 +23,7 @@ const a = {
>a.foo : string
> : ^^^^^^
>a : { b: { foo: string; }; foo: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
>foo : string
> : ^^^^^^

Expand All @@ -40,7 +40,7 @@ const a = {
>a.foo : string
> : ^^^^^^
>a : { b: { foo: string; }; foo: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
>foo : string
> : ^^^^^^
>value : string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
=== collisionArgumentsArrowFunctions.ts ===
var f1 = (i: number, ...arguments) => { //arguments is error
>f1 : (i: number, ...arguments: any[]) => void
> : ^ ^^ ^^^^^ ^^ ^^^^^^^^^
> : ^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^
>(i: number, ...arguments) => { //arguments is error var arguments: any[]; // no error} : (i: number, ...arguments: any[]) => void
> : ^ ^^ ^^^^^ ^^ ^^^^^^^^^
> : ^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^
>i : number
> : ^^^^^^
>arguments : any[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class c1 {

public foo(i: number, ...arguments) { //arguments is error
>foo : (i: number, ...arguments: any[]) => void
> : ^ ^^ ^^^^^ ^^ ^^^^^^^^^
> : ^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^
>i : number
> : ^^^^^^
>arguments : any[]
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/collisionArgumentsFunction.types
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function f1(arguments: number, ...restParameters) { //arguments is error
}
function f12(i: number, ...arguments) { //arguments is error
>f12 : (i: number, ...arguments: any[]) => void
> : ^ ^^ ^^^^^ ^^ ^^^^^^^^^
> : ^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^
>i : number
> : ^^^^^^
>arguments : any[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function foo() {
}
function f12(i: number, ...arguments) { //arguments is error
>f12 : (i: number, ...arguments: any[]) => void
> : ^ ^^ ^^^^^ ^^ ^^^^^^^^^
> : ^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^
>i : number
> : ^^^^^^
>arguments : any[]
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/commentsOnObjectLiteral4.types
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
=== commentsOnObjectLiteral4.ts ===
var v = {
>v : { readonly bar: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^^^^^ ^^^
>{ /** * @type {number} */ get bar(): number { return 12; }} : { readonly bar: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
> : ^^^^^^^^^^^^^^^^ ^^^

/**
* @type {number}
Expand Down
Loading

0 comments on commit 476e9ee

Please sign in to comment.