Skip to content

Commit adb2ab4

Browse files
Copilotjakebailey
andauthored
Fix declaration emit renaming a method's shadowed type parameter to the outer generic (#3761)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
1 parent 2879671 commit adb2ab4

177 files changed

Lines changed: 579 additions & 4259 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

internal/binder/nameresolver.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,18 @@ loop:
5656
// - Type parameters of a function are in scope in the entire function declaration, including the parameter
5757
// list and return type. However, local types are only in scope in the function body.
5858
// - parameters are only in the scope of function body
59-
if meaning&result.Flags&ast.SymbolFlagsType != 0 {
60-
useResult = result.Flags&ast.SymbolFlagsTypeParameter != 0 && (lastLocation == location.Type() || ast.IsParameterLike(lastLocation))
59+
// This restriction does not apply to JSDoc comment types because they are parented
60+
// at a higher level than type parameters would normally be
61+
if meaning&result.Flags&ast.SymbolFlagsType != 0 && lastLocation.Kind != ast.KindJSDoc {
62+
// type parameters are visible in parameter list, return type and type parameter list.
63+
// Synthetic fake scopes are added for signatures so type parameters are accessible from them.
64+
useResult = result.Flags&ast.SymbolFlagsTypeParameter != 0 &&
65+
(lastLocation.Flags&ast.NodeFlagsSynthesized != 0 ||
66+
lastLocation == location.Type() ||
67+
lastLocation.Kind == ast.KindParameter ||
68+
lastLocation.Kind == ast.KindJSDocParameterTag ||
69+
lastLocation.Kind == ast.KindJSDocReturnTag ||
70+
lastLocation.Kind == ast.KindTypeParameter)
6171
}
6272
if meaning&result.Flags&ast.SymbolFlagsVariable != 0 {
6373
// expression inside parameter will lookup as normal variable scope when targeting es2015+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [tests/cases/compiler/declarationEmitMethodShadowsClassTypeParameter.ts] ////
2+
3+
//// [declarationEmitMethodShadowsClassTypeParameter.ts]
4+
export class Outer<Table> {
5+
method<Table, R>(r: R) {
6+
return null as Table | null;
7+
}
8+
}
9+
10+
11+
//// [declarationEmitMethodShadowsClassTypeParameter.js]
12+
export class Outer {
13+
method(r) {
14+
return null;
15+
}
16+
}
17+
18+
19+
//// [declarationEmitMethodShadowsClassTypeParameter.d.ts]
20+
export declare class Outer<Table> {
21+
method<Table, R>(r: R): Table | null;
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/compiler/declarationEmitMethodShadowsClassTypeParameter.ts] ////
2+
3+
=== declarationEmitMethodShadowsClassTypeParameter.ts ===
4+
export class Outer<Table> {
5+
>Outer : Symbol(Outer, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 0, 0))
6+
>Table : Symbol(Table, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 0, 19))
7+
8+
method<Table, R>(r: R) {
9+
>method : Symbol(Outer.method, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 0, 27))
10+
>Table : Symbol(Table, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 1, 11))
11+
>R : Symbol(R, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 1, 17))
12+
>r : Symbol(r, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 1, 21))
13+
>R : Symbol(R, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 1, 17))
14+
15+
return null as Table | null;
16+
>Table : Symbol(Table, Decl(declarationEmitMethodShadowsClassTypeParameter.ts, 1, 11))
17+
}
18+
}
19+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/compiler/declarationEmitMethodShadowsClassTypeParameter.ts] ////
2+
3+
=== declarationEmitMethodShadowsClassTypeParameter.ts ===
4+
export class Outer<Table> {
5+
>Outer : Outer<Table>
6+
7+
method<Table, R>(r: R) {
8+
>method : <Table, R>(r: R) => Table | null
9+
>r : R
10+
11+
return null as Table | null;
12+
>null as Table | null : Table | null
13+
}
14+
}
15+

testdata/baselines/reference/compiler/jsExportsImportedIntoTsxLosesTypeInfo.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ export function compose<F extends Function>(f: F): F;
124124
>f : F
125125

126126
export function compose<A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C;
127-
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
127+
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A_1, B_1, C_1, D>(f1: (c: C_1) => D, f2: (b: B_1) => C_1, f3: (a: A_1) => B_1): (a: A_1) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
128128
>f1 : (b: B) => C
129129
>b : B
130130
>f2 : (a: A) => B
131131
>a : A
132132
>a : A
133133

134134
export function compose<A, B, C, D>(
135-
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
135+
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A_1, B_1, C_1>(f1: (b: B_1) => C_1, f2: (a: A_1) => B_1): (a: A_1) => C_1; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
136136

137137
f1: (c: C) => D,
138138
>f1 : (c: C) => D
@@ -150,14 +150,14 @@ export function compose<A, B, C, D>(
150150
>a : A
151151

152152
export function compose<R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R;
153-
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
153+
>compose : { (): <R_1>(a: R_1) => R_1; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R_1>(...funcs: Function[]): (...args: any[]) => R_1; }
154154
>f1 : (a: any) => R
155155
>a : any
156156
>funcs : Function[]
157157
>args : any[]
158158

159159
export function compose<R>(...funcs: Function[]): (...args: any[]) => R;
160-
>compose : { (): <R>(a: R) => R; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R>(f1: (a: any) => R, ...funcs: Function[]): (...args: any[]) => R; <R>(...funcs: Function[]): (...args: any[]) => R; }
160+
>compose : { (): <R_1>(a: R_1) => R_1; <F extends Function>(f: F): F; <A, B, C>(f1: (b: B) => C, f2: (a: A) => B): (a: A) => C; <A, B, C, D>(f1: (c: C) => D, f2: (b: B) => C, f3: (a: A) => B): (a: A) => D; <R_1>(f1: (a: any) => R_1, ...funcs: Function[]): (...args: any[]) => R_1; <R>(...funcs: Function[]): (...args: any[]) => R; }
161161
>funcs : Function[]
162162
>args : any[]
163163

testdata/baselines/reference/submodule/compiler/asyncFunctionsAndStrictNullChecks.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
declare namespace Windows.Foundation {
55
interface IPromise<TResult> {
66
then<U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>;
7-
>then : { <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; }
7+
>then : { <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; }
88
>success : ((value: TResult) => IPromise<U>) | undefined
99
>value : TResult
1010
>error : ((error: any) => IPromise<U>) | undefined
@@ -13,7 +13,7 @@ declare namespace Windows.Foundation {
1313
>progress : any
1414

1515
then<U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>;
16-
>then : { <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; }
16+
>then : { <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; }
1717
>success : ((value: TResult) => IPromise<U>) | undefined
1818
>value : TResult
1919
>error : ((error: any) => U) | undefined
@@ -22,7 +22,7 @@ declare namespace Windows.Foundation {
2222
>progress : any
2323

2424
then<U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>;
25-
>then : { <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; }
25+
>then : { <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; <U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; }
2626
>success : ((value: TResult) => U) | undefined
2727
>value : TResult
2828
>error : ((error: any) => IPromise<U>) | undefined
@@ -31,7 +31,7 @@ declare namespace Windows.Foundation {
3131
>progress : any
3232

3333
then<U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>;
34-
>then : { <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => IPromise<U>, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => IPromise<U>, progress?: (progress: any) => void): IPromise<U>; <U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; }
34+
>then : { <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => IPromise<U_1>, error?: (error: any) => U_1, progress?: (progress: any) => void): IPromise<U_1>; <U_1>(success?: (value: TResult) => U_1, error?: (error: any) => IPromise<U_1>, progress?: (progress: any) => void): IPromise<U_1>; <U>(success?: (value: TResult) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise<U>; }
3535
>success : ((value: TResult) => U) | undefined
3636
>value : TResult
3737
>error : ((error: any) => U) | undefined

0 commit comments

Comments
 (0)