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

Isolated declarations fix signature serialization scoping #58409

Merged
Merged
246 changes: 145 additions & 101 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11068,7 +11068,8 @@ export function createNameResolver({
if (meaning & result.flags & SymbolFlags.Type && lastLocation.kind !== SyntaxKind.JSDoc) {
useResult = result.flags & SymbolFlags.TypeParameter
// type parameters are visible in parameter list, return type and type parameter list
? lastLocation === (location as FunctionLikeDeclaration).type ||
? nodeIsSynthesized(lastLocation) || // Synthetic fake scopes are added for signatures so type parameters are accessible from them
dragomirtitian marked this conversation as resolved.
Show resolved Hide resolved
lastLocation === (location as FunctionLikeDeclaration).type ||
lastLocation.kind === SyntaxKind.Parameter ||
lastLocation.kind === SyntaxKind.JSDocParameterTag ||
lastLocation.kind === SyntaxKind.JSDocReturnTag ||
Expand All @@ -11087,6 +11088,7 @@ export function createNameResolver({
// however it is detected separately when checking initializers of parameters
// to make sure that they reference no variables declared after them.
useResult = lastLocation.kind === SyntaxKind.Parameter ||
nodeIsSynthesized(lastLocation) || // Synthetic fake scopes are added for signatures so parameters are accessible from them
(
lastLocation === (location as FunctionLikeDeclaration).type &&
!!findAncestor(result.valueDeclaration, isParameter)
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/utilitiesPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2320,7 +2320,8 @@ function isDeclarationKind(kind: SyntaxKind) {
|| kind === SyntaxKind.VariableDeclaration
|| kind === SyntaxKind.JSDocTypedefTag
|| kind === SyntaxKind.JSDocCallbackTag
|| kind === SyntaxKind.JSDocPropertyTag;
|| kind === SyntaxKind.JSDocPropertyTag
|| kind === SyntaxKind.NamedTupleMember;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NamedTupleMember seemed to be missing here. This meant that tuple member names were being funneled through trackExistingEntityName even when other declaration names were not.

                if (isEntityName(node) || isEntityNameExpression(node)) {
                    if (isDeclarationName(node)) {
                        return node;
                    }
                    const { introducesError, node: result } = trackExistingEntityName(node, context);
                    hadError = hadError || introducesError;
                    // We should not go to child nodes of the entity name, they will not be accessible
                    return result;
                }

}

function isDeclarationStatementKind(kind: SyntaxKind) {
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/1.0lib-noErrors.types
Original file line number Diff line number Diff line change
Expand Up @@ -2411,8 +2411,8 @@ interface Array<T> {
> : ^^^^^^
}
declare var Array: {
>Array : { (arrayLength?: number): any[]; <T>(arrayLength: number): T[]; <T_1>(...items: T_1[]): T_1[]; new (arrayLength?: number): any[]; new <T_2>(arrayLength: number): T_2[]; new <T_3>(...items: T_3[]): T_3[]; isArray(arg: any): boolean; prototype: Array<any>; }
> : ^^^ ^^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^^^^^ ^^^ ^^^ ^^^^^^^ ^^ ^^ ^^^ ^^^^^^^ ^^^^^ ^^ ^^^ ^^^^^^^^^^ ^^ ^^^ ^^^^^^^^^^^^^ ^^^
>Array : { (arrayLength?: number): any[]; <T>(arrayLength: number): T[]; <T>(...items: T[]): T[]; new (arrayLength?: number): any[]; new <T>(arrayLength: number): T[]; new <T>(...items: T[]): T[]; isArray(arg: any): boolean; prototype: Array<any>; }
> : ^^^ ^^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^^^^^ ^^^ ^^^ ^^^^^^^ ^^ ^^ ^^^ ^^^^^^^ ^^^^^ ^^ ^^^ ^^^^^^^^^^ ^^ ^^^ ^^^^^^^^^^^^^ ^^^

new (arrayLength?: number): any[];
>arrayLength : number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ const debuglog = function() {
return format.apply(null, arguments);
>format.apply(null, arguments) : string
> : ^^^^^^
>format.apply : { <T, R>(this: (this: T) => R, thisArg: T): R; <T_1, A extends any[], R_1>(this: (this: T_1, ...args: A) => R_1, thisArg: T_1, args: A): R_1; }
> : ^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
>format.apply : { <T, R>(this: (this: T) => R, thisArg: T): R; <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R; }
> : ^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^
>format : (f: any, ...args: any[]) => string
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>apply : { <T, R>(this: (this: T) => R, thisArg: T): R; <T_1, A extends any[], R_1>(this: (this: T_1, ...args: A) => R_1, thisArg: T_1, args: A): R_1; }
> : ^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
>apply : { <T, R>(this: (this: T) => R, thisArg: T): R; <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R; }
> : ^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^
>arguments : IArguments
> : ^^^^^^^^^^

Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/arrayDestructuringInSwitch1.types
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ export function evaluate(expression: Expression): boolean {
return operands.every((child) => evaluate(child));
>operands.every((child) => evaluate(child)) : boolean
> : ^^^^^^^
>operands.every : { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; } | { <S_1 extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S_1, thisArg?: any): this is S_1[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^
>operands.every : { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; } | { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^
>operands : Expression[] | [Expression]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>every : { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; } | { <S_1 extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S_1, thisArg?: any): this is S_1[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^
>every : { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; } | { <S extends Expression>(predicate: (value: Expression, index: number, array: Expression[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Expression, index: number, array: Expression[]) => unknown, thisArg?: any): boolean; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^
>(child) => evaluate(child) : (child: Expression) => boolean
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^
>child : Expression
Expand Down