From d7580755974df4fe3d64af54462b855d3f9f8f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Thu, 9 Aug 2018 16:40:11 +0800 Subject: [PATCH 1/2] add special check for parameter initializer lookup if targeting es2015+ --- src/compiler/checker.ts | 16 ++-- ...InitializersForwardReferencing1.errors.txt | 45 ++++++++++++ ...arameterInitializersForwardReferencing1.js | 61 ++++++++++++++++ ...terInitializersForwardReferencing1.symbols | 67 +++++++++++++++++ ...meterInitializersForwardReferencing1.types | 73 +++++++++++++++++++ ...ializersForwardReferencing1_es6.errors.txt | 36 +++++++++ ...eterInitializersForwardReferencing1_es6.js | 51 +++++++++++++ ...nitializersForwardReferencing1_es6.symbols | 67 +++++++++++++++++ ...rInitializersForwardReferencing1_es6.types | 73 +++++++++++++++++++ ...arameterInitializersForwardReferencing1.ts | 27 +++++++ ...eterInitializersForwardReferencing1_es6.ts | 29 ++++++++ 11 files changed, 540 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.js create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.symbols create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.types create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types create mode 100644 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts create mode 100644 tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 51eeb0fdb48..36c6d71f672 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1197,16 +1197,22 @@ namespace ts { : false; } if (meaning & SymbolFlags.Value && 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 = + // parameter initializer will lookup as normal variable scope when targeting es2015+ + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && lastLocation.initializer === originalLocation && result.valueDeclaration !== lastLocation) { + useResult = false; + } + else { + // 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 === (location).type && !!findAncestor(result.valueDeclaration, isParameter) ); + } } } else if (location.kind === SyntaxKind.ConditionalType) { diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt new file mode 100644 index 00000000000..9879ec320ca --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. + + +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (5 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 + } + + function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. + return bar; + } + + function f4 (foo, bar = foo) { + return bar + } + + function f5 (a = a) { + ~ +!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. + return a + } + + function f6 (async = async) { + ~~~~~ +!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. + return async + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js new file mode 100644 index 00000000000..43f303a94cd --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -0,0 +1,61 @@ +//// [parameterInitializersForwardReferencing1.ts] +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} + +//// [parameterInitializersForwardReferencing1.js] +var foo = ""; +function f1(bar) { + if (bar === void 0) { bar = foo; } + var foo = 2; + return bar; // returns 1 +} +function f2(bar) { + if (bar === void 0) { bar = function (baz) { + if (baz === void 0) { baz = foo; } + return baz; + }; } + var foo = 2; + return bar(); // returns 1 +} +function f3(bar, foo) { + if (bar === void 0) { bar = foo; } + if (foo === void 0) { foo = 2; } + return bar; +} +function f4(foo, bar) { + if (bar === void 0) { bar = foo; } + return bar; +} +function f5(a) { + if (a === void 0) { a = a; } + return a; +} +function f6(async) { + if (async === void 0) { async = async; } + return async; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols new file mode 100644 index 00000000000..6860e39fd8d --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -0,0 +1,67 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts === +let foo: string = ""; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 0, 3)) + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1.ts, 0, 21)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 2, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 3, 7)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 3, 7)) + + return bar; // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 2, 13)) +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1.ts, 5, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 7, 13)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1.ts, 7, 20)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 8, 7)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1.ts, 7, 20)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 8, 7)) + + return bar(); // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 7, 13)) +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1.ts, 10, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 12, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 12, 23)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 12, 23)) + + return bar; +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 12, 13)) +} + +function f4 (foo, bar = foo) { +>f4 : Symbol(f4, Decl(parameterInitializersForwardReferencing1.ts, 14, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 16, 13)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 16, 17)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 16, 13)) + + return bar +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 16, 17)) +} + +function f5 (a = a) { +>f5 : Symbol(f5, Decl(parameterInitializersForwardReferencing1.ts, 18, 1)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) + + return a +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) +} + +function f6 (async = async) { +>f6 : Symbol(f6, Decl(parameterInitializersForwardReferencing1.ts, 22, 1)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) + + return async +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types new file mode 100644 index 00000000000..c33c227a37a --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -0,0 +1,73 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts === +let foo: string = ""; +>foo : string +>"" : "" + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : (bar?: number) => number +>bar : number +>foo : number + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar; // returns 1 +>bar : number +} + +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 + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar(); // returns 1 +>bar() : number +>bar : (baz?: number) => number +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : (bar?: number, foo?: number) => number +>bar : number +>foo : number +>foo : number +>2 : 2 + + return bar; +>bar : number +} + +function f4 (foo, bar = foo) { +>f4 : (foo: any, bar?: any) => any +>foo : any +>bar : any +>foo : any + + return bar +>bar : any +} + +function f5 (a = a) { +>f5 : (a?: any) => any +>a : any +>a : any + + return a +>a : any +} + +function f6 (async = async) { +>f6 : (async?: any) => any +>async : any +>async : any + + return async +>async : any +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt new file mode 100644 index 00000000000..cffa83707e0 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -0,0 +1,36 @@ +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 (2 errors) ==== + let foo: string = ""; + + function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 + } + + function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 + } + + function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; + } + + function f4 (foo, bar = foo) { + return bar + } + + function f5 (a = a) { + ~ +!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. + return a + } + + function f6 (async = async) { + ~~~~~ +!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. + return async + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js new file mode 100644 index 00000000000..add0837e312 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -0,0 +1,51 @@ +//// [parameterInitializersForwardReferencing1_es6.ts] +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} + +//// [parameterInitializersForwardReferencing1_es6.js] +let foo = ""; +function f1(bar = foo) { + var foo = 2; + return bar; // returns 1 +} +function f2(bar = (baz = foo) => baz) { + var fooo = 2; + return bar(); // returns 1 +} +function f3(bar = foo, foo = 2) { + return bar; +} +function f4(foo, bar = foo) { + return bar; +} +function f5(a = a) { + return a; +} +function f6(async = async) { + return async; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols new file mode 100644 index 00000000000..c38a392c4d8 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -0,0 +1,67 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts === +let foo: string = ""; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) + +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, 0, 3)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) + + return bar; // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13)) +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>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, 0, 3)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) + + var fooo: number = 2; +>fooo : Symbol(fooo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) + + return bar(); // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1_es6.ts, 10, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) + + return bar; +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) +} + +function f4 (foo, bar = foo) { +>f4 : Symbol(f4, Decl(parameterInitializersForwardReferencing1_es6.ts, 14, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 13)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) + + return bar +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) +} + +function f5 (a = a) { +>f5 : Symbol(f5, Decl(parameterInitializersForwardReferencing1_es6.ts, 18, 1)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) + + return a +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) +} + +function f6 (async = async) { +>f6 : Symbol(f6, Decl(parameterInitializersForwardReferencing1_es6.ts, 22, 1)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) + + return async +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types new file mode 100644 index 00000000000..bd17f482335 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -0,0 +1,73 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts === +let foo: string = ""; +>foo : string +>"" : "" + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : (bar?: string) => string +>bar : string +>foo : string + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar; // returns 1 +>bar : string +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : (bar?: (baz?: string) => string) => string +>bar : (baz?: string) => string +>(baz = foo) => baz : (baz?: string) => string +>baz : string +>foo : string +>baz : string + + var fooo: number = 2; +>fooo : number +>2 : 2 + + return bar(); // returns 1 +>bar() : string +>bar : (baz?: string) => string +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : (bar?: string, foo?: number) => string +>bar : string +>foo : string +>foo : number +>2 : 2 + + return bar; +>bar : string +} + +function f4 (foo, bar = foo) { +>f4 : (foo: any, bar?: string) => string +>foo : any +>bar : string +>foo : string + + return bar +>bar : string +} + +function f5 (a = a) { +>f5 : (a?: any) => any +>a : any +>a : any + + return a +>a : any +} + +function f6 (async = async) { +>f6 : (async?: any) => any +>async : any +>async : any + + return async +>async : any +} diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts new file mode 100644 index 00000000000..8492a053856 --- /dev/null +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -0,0 +1,27 @@ +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} \ No newline at end of file diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts new file mode 100644 index 00000000000..dfd6b8d4e1a --- /dev/null +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -0,0 +1,29 @@ +// @target: es2015 + +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} \ No newline at end of file From 8869f39c25f8e9e7660ada38f0d33fcea714e49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 28 Aug 2018 16:41:26 +0800 Subject: [PATCH 2/2] accept more case --- src/compiler/checker.ts | 6 +++--- ...eterInitializersForwardReferencing1.errors.txt | 13 +++++++++++-- .../parameterInitializersForwardReferencing1.js | 11 ++++++++++- ...rameterInitializersForwardReferencing1.symbols | 10 ++++++++++ ...parameterInitializersForwardReferencing1.types | 11 +++++++++++ ...InitializersForwardReferencing1_es6.errors.txt | 9 +++++++-- ...arameterInitializersForwardReferencing1_es6.js | 14 +++++++++++--- ...terInitializersForwardReferencing1_es6.symbols | 14 ++++++++++++-- ...meterInitializersForwardReferencing1_es6.types | 15 +++++++++++++-- .../parameterInitializersForwardReferencing1.ts | 6 +++++- ...arameterInitializersForwardReferencing1_es6.ts | 8 ++++++-- 11 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36c6d71f672..063044eda68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1196,12 +1196,12 @@ namespace ts { // local types not visible outside the function body : false; } - if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) { + if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { // parameter initializer will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && lastLocation.initializer === originalLocation && result.valueDeclaration !== lastLocation) { + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && result.valueDeclaration !== lastLocation) { useResult = false; } - else { + 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 diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt index 9879ec320ca..055a37838f1 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -3,9 +3,10 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(8, tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration. -==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (5 errors) ==== +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (6 errors) ==== let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime @@ -42,4 +43,12 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25 ~~~~~ !!! error TS2372: Parameter 'async' cannot be referenced in its initializer. return async - } \ No newline at end of file + } + + function f7({[foo]: bar}: any[]) { + ~~~ +!!! error TS2448: Block-scoped variable 'foo' used before its declaration. +!!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts:30:9: 'foo' is declared here. + let foo: number = 2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js index 43f303a94cd..ad68f64ca2c 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -25,7 +25,12 @@ function f5 (a = a) { function f6 (async = async) { return async -} +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} + //// [parameterInitializersForwardReferencing1.js] var foo = ""; @@ -59,3 +64,7 @@ function f6(async) { if (async === void 0) { async = async; } return async; } +function f7(_a) { + var _b = foo, bar = _a[_b]; + var foo = 2; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols index 6860e39fd8d..f3ea0f1e7e8 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -65,3 +65,13 @@ function f6 (async = async) { return async >async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) } + +function f7({[foo]: bar}: any[]) { +>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1.ts, 26, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 29, 7)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 28, 13)) + + let foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 29, 7)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types index c33c227a37a..3a1d8d5864f 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -71,3 +71,14 @@ function f6 (async = async) { return async >async : any } + +function f7({[foo]: bar}: any[]) { +>f7 : ({ [foo]: bar }: any[]) => void +>foo : number +>bar : any + + let foo: number = 2; +>foo : number +>2 : 2 +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index cffa83707e0..e7708894b65 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -11,7 +11,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -33,4 +33,9 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t ~~~~~ !!! error TS2372: Parameter 'async' cannot be referenced in its initializer. return async - } \ No newline at end of file + } + + function f7({[foo]: bar}: any[]) { + let foo: number = 2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js index add0837e312..0c89b79b764 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -7,7 +7,7 @@ function f1 (bar = foo) { // unexpected compiler error; works at runtime } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -25,7 +25,12 @@ function f5 (a = a) { function f6 (async = async) { return async -} +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} + //// [parameterInitializersForwardReferencing1_es6.js] let foo = ""; @@ -34,7 +39,7 @@ function f1(bar = foo) { return bar; // returns 1 } function f2(bar = (baz = foo) => baz) { - var fooo = 2; + var foo = 2; return bar(); // returns 1 } function f3(bar = foo, foo = 2) { @@ -49,3 +54,6 @@ function f5(a = a) { function f6(async = async) { return async; } +function f7({ [foo]: bar }) { + let foo = 2; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index c38a392c4d8..f9366034aa6 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -21,8 +21,8 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) - var fooo: number = 2; ->fooo : Symbol(fooo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) return bar(); // returns 1 >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) @@ -65,3 +65,13 @@ function f6 (async = async) { return async >async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) } + +function f7({[foo]: bar}: any[]) { +>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13)) + + let foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index bd17f482335..16bd49f1cf7 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -24,8 +24,8 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >foo : string >baz : string - var fooo: number = 2; ->fooo : number + var foo: number = 2; +>foo : number >2 : 2 return bar(); // returns 1 @@ -71,3 +71,14 @@ function f6 (async = async) { return async >async : any } + +function f7({[foo]: bar}: any[]) { +>f7 : ({ [foo]: bar }: any[]) => void +>foo : string +>bar : any + + let foo: number = 2; +>foo : number +>2 : 2 +} + diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts index 8492a053856..640900253bd 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -24,4 +24,8 @@ function f5 (a = a) { function f6 (async = async) { return async -} \ No newline at end of file +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts index dfd6b8d4e1a..55afbbf7c2f 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -8,7 +8,7 @@ function f1 (bar = foo) { // unexpected compiler error; works at runtime } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -26,4 +26,8 @@ function f5 (a = a) { function f6 (async = async) { return async -} \ No newline at end of file +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +}