Skip to content

Commit fc78839

Browse files
Merge pull request microsoft#26810 from Kingwl/fix_lookup_regression_again_and_again
fix lookup regression again and again
2 parents 07966dc + 20054d9 commit fc78839

File tree

4 files changed

+36
-38
lines changed

4 files changed

+36
-38
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,17 +1238,25 @@ namespace ts {
12381238
// local types not visible outside the function body
12391239
: false;
12401240
}
1241-
if (meaning & result.flags & SymbolFlags.FunctionScopedVariable) {
1242-
// parameters are visible only inside function body, parameter list and return type
1243-
// technically for parameter list case here we might mix parameters and variables declared in function,
1244-
// however it is detected separately when checking initializers of parameters
1245-
// to make sure that they reference no variables declared after them.
1246-
useResult =
1247-
lastLocation.kind === SyntaxKind.Parameter ||
1248-
(
1249-
lastLocation === (<FunctionLikeDeclaration>location).type &&
1250-
!!findAncestor(result.valueDeclaration, isParameter)
1251-
);
1241+
if (meaning & result.flags & SymbolFlags.Variable) {
1242+
// expression inside parameter will lookup as normal variable scope when targeting es2015+
1243+
const functionLocation = <FunctionLikeDeclaration>location;
1244+
if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) &&
1245+
functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
1246+
useResult = false;
1247+
}
1248+
else if (result.flags & SymbolFlags.FunctionScopedVariable) {
1249+
// parameters are visible only inside function body, parameter list and return type
1250+
// technically for parameter list case here we might mix parameters and variables declared in function,
1251+
// however it is detected separately when checking initializers of parameters
1252+
// to make sure that they reference no variables declared after them.
1253+
useResult =
1254+
lastLocation.kind === SyntaxKind.Parameter ||
1255+
(
1256+
lastLocation === (<FunctionLikeDeclaration>location).type &&
1257+
!!findAncestor(result.valueDeclaration, isParameter)
1258+
);
1259+
}
12521260
}
12531261
}
12541262
else if (location.kind === SyntaxKind.ConditionalType) {

tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
1-
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
2-
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
31
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
42
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer.
53
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer.
6-
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration.
74

85

9-
==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (6 errors) ====
6+
==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (3 errors) ====
107
let foo: string = "";
118

129
function f1 (bar = foo) { // unexpected compiler error; works at runtime
13-
~~~
14-
!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
1510
var foo: number = 2;
1611
return bar; // returns 1
1712
}
1813

1914
function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime
20-
~~~
21-
!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
2215
var foo: number = 2;
2316
return bar(); // returns 1
2417
}
@@ -46,9 +39,6 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t
4639
}
4740

4841
function f7({[foo]: bar}: any[]) {
49-
~~~
50-
!!! error TS2448: Block-scoped variable 'foo' used before its declaration.
51-
!!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts:30:9: 'foo' is declared here.
5242
let foo: number = 2;
5343
}
5444

tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ let foo: string = "";
55
function f1 (bar = foo) { // unexpected compiler error; works at runtime
66
>f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 21))
77
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13))
8-
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7))
8+
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))
99

1010
var foo: number = 2;
1111
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7))
@@ -18,7 +18,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at
1818
>f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1_es6.ts, 5, 1))
1919
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13))
2020
>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20))
21-
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7))
21+
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))
2222
>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20))
2323

2424
var foo: number = 2;
@@ -68,7 +68,7 @@ function f6 (async = async) {
6868

6969
function f7({[foo]: bar}: any[]) {
7070
>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1))
71-
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7))
71+
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))
7272
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13))
7373

7474
let foo: number = 2;

tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,33 @@ let foo: string = "";
44
>"" : ""
55

66
function f1 (bar = foo) { // unexpected compiler error; works at runtime
7-
>f1 : (bar?: number) => number
8-
>bar : number
9-
>foo : number
7+
>f1 : (bar?: string) => string
8+
>bar : string
9+
>foo : string
1010

1111
var foo: number = 2;
1212
>foo : number
1313
>2 : 2
1414

1515
return bar; // returns 1
16-
>bar : number
16+
>bar : string
1717
}
1818

1919
function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime
20-
>f2 : (bar?: (baz?: number) => number) => number
21-
>bar : (baz?: number) => number
22-
>(baz = foo) => baz : (baz?: number) => number
23-
>baz : number
24-
>foo : number
25-
>baz : number
20+
>f2 : (bar?: (baz?: string) => string) => string
21+
>bar : (baz?: string) => string
22+
>(baz = foo) => baz : (baz?: string) => string
23+
>baz : string
24+
>foo : string
25+
>baz : string
2626

2727
var foo: number = 2;
2828
>foo : number
2929
>2 : 2
3030

3131
return bar(); // returns 1
32-
>bar() : number
33-
>bar : (baz?: number) => number
32+
>bar() : string
33+
>bar : (baz?: string) => string
3434
}
3535

3636
function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime
@@ -74,7 +74,7 @@ function f6 (async = async) {
7474

7575
function f7({[foo]: bar}: any[]) {
7676
>f7 : ({ [foo]: bar }: any[]) => void
77-
>foo : number
77+
>foo : string
7878
>bar : any
7979

8080
let foo: number = 2;

0 commit comments

Comments
 (0)