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

fix lookup regression again and again #26810

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
30 changes: 19 additions & 11 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1237,17 +1237,25 @@ namespace ts {
// local types not visible outside the function body
: false;
}
if (meaning & result.flags & SymbolFlags.FunctionScopedVariable) {
// parameters are visible only inside function body, parameter list and return type
// technically for parameter list case here we might mix parameters and variables declared in function,
// 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 ||
(
lastLocation === (<FunctionLikeDeclaration>location).type &&
!!findAncestor(result.valueDeclaration, isParameter)
);
if (meaning & result.flags & SymbolFlags.Variable) {
// expression inside parameter will lookup as normal variable scope when targeting es2015+
const functionLocation = <FunctionLikeDeclaration>location;
if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) &&
functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
useResult = false;
}
else if (result.flags & SymbolFlags.FunctionScopedVariable) {
// parameters are visible only inside function body, parameter list and return type
// technically for parameter list case here we might mix parameters and variables declared in function,
// 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 ||
(
lastLocation === (<FunctionLikeDeclaration>location).type &&
!!findAncestor(result.valueDeclaration, isParameter)
);
}
}
}
else if (location.kind === SyntaxKind.ConditionalType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it.
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer.
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer.
tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration.


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

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

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ let foo: string = "";
function f1 (bar = foo) { // unexpected compiler error; works at runtime
>f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 21))
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))

var foo: number = 2;
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7))
Expand All @@ -18,7 +18,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at
>f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1_es6.ts, 5, 1))
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13))
>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))
>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20))

var foo: number = 2;
Expand Down Expand Up @@ -68,7 +68,7 @@ function f6 (async = async) {

function f7({[foo]: bar}: any[]) {
>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7))
>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3))
>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13))

let foo: number = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@ let foo: string = "";
>"" : ""

function f1 (bar = foo) { // unexpected compiler error; works at runtime
>f1 : (bar?: number) => number
>bar : number
>foo : number
>f1 : (bar?: string) => string
>bar : string
>foo : string

var foo: number = 2;
>foo : number
>2 : 2

return bar; // returns 1
>bar : number
>bar : string
}

function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime
>f2 : (bar?: (baz?: number) => number) => number
>bar : (baz?: number) => number
>(baz = foo) => baz : (baz?: number) => number
>baz : number
>foo : number
>baz : number
>f2 : (bar?: (baz?: string) => string) => string
>bar : (baz?: string) => string
>(baz = foo) => baz : (baz?: string) => string
>baz : string
>foo : string
>baz : string

var foo: number = 2;
>foo : number
>2 : 2

return bar(); // returns 1
>bar() : number
>bar : (baz?: number) => number
>bar() : string
>bar : (baz?: string) => string
}

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

function f7({[foo]: bar}: any[]) {
>f7 : ({ [foo]: bar }: any[]) => void
>foo : number
>foo : string
>bar : any

let foo: number = 2;
Expand Down