From eb3b91cf1b1e681eac27c9b650830b8c3c978cd6 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 12 Oct 2015 17:24:39 -0700 Subject: [PATCH] addressed PR feedback --- src/compiler/checker.ts | 15 +- ...lockScopedVariablesUseBeforeDef.errors.txt | 93 ++++++++++++ .../blockScopedVariablesUseBeforeDef.js | 143 +++++++++++++++--- .../blockScopedVariablesUseBeforeDef.symbols | 76 ---------- .../blockScopedVariablesUseBeforeDef.types | 81 ---------- ...clarations-useBeforeDefinition2.errors.txt | 11 -- ...tDeclarations-useBeforeDefinition2.symbols | 9 ++ ...nstDeclarations-useBeforeDefinition2.types | 10 ++ ...clarations-useBeforeDefinition2.errors.txt | 11 -- ...tDeclarations-useBeforeDefinition2.symbols | 9 ++ ...letDeclarations-useBeforeDefinition2.types | 10 ++ .../blockScopedVariablesUseBeforeDef.ts | 85 ++++++++--- 12 files changed, 336 insertions(+), 217 deletions(-) create mode 100644 tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt delete mode 100644 tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols delete mode 100644 tests/baselines/reference/blockScopedVariablesUseBeforeDef.types delete mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.symbols create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.types delete mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.symbols create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3eead9fc957..0213f594f5b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -412,7 +412,7 @@ namespace ts { return origin.pos > target.pos ? RelativeLocation.SameFileLocatedBefore : RelativeLocation.SameFileLocatedAfter; } - if (!compilerOptions.outFile && !compilerOptions.out) { + if (modulekind || (!compilerOptions.outFile && !compilerOptions.out)) { // nodes are in different files and order cannot be determines return RelativeLocation.Unknown; } @@ -666,7 +666,18 @@ namespace ts { isUsedBeforeDeclaration = true; break; } - else if (isFunctionLike(current)) { + + if (isFunctionLike(current)) { + break; + } + + const isInitializerOfNonStaticProperty = + current.parent && + current.parent.kind === SyntaxKind.PropertyDeclaration && + (current.parent.flags & NodeFlags.Static) === 0 && + (current.parent).initializer === current; + + if (isInitializerOfNonStaticProperty) { break; } current = current.parent; diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt new file mode 100644 index 00000000000..a2bae3307a1 --- /dev/null +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt @@ -0,0 +1,93 @@ +tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(53,20): error TS2448: Block-scoped variable 'x' used before its declaration. +tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(60,20): error TS2448: Block-scoped variable 'x' used before its declaration. + + +==== tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts (2 errors) ==== + function foo1() { + let a = () => x; + let x; + } + + function foo2() { + let a = function () { return x; } + let x; + } + + function foo3() { + class X { + m() { return x;} + } + let x; + } + + function foo4() { + let y = class { + m() { return x; } + }; + let x; + } + + function foo5() { + let x = () => y; + let y = () => x; + } + + function foo6() { + function f() { + return x; + } + let x; + } + + function foo7() { + class A { + a = x; + } + let x; + } + + function foo8() { + let y = class { + a = x; + } + let x; + } + + function foo9() { + let y = class { + static a = x; + ~ +!!! error TS2448: Block-scoped variable 'x' used before its declaration. + } + let x; + } + + function foo10() { + class A { + static a = x; + ~ +!!! error TS2448: Block-scoped variable 'x' used before its declaration. + } + let x; + } + + function foo11() { + function f () { + let y = class { + static a = x; + } + } + let x; + } + + function foo12() { + function f () { + let y = class { + a; + constructor() { + this.a = x; + } + } + } + let x; + } \ No newline at end of file diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js index 2792521344f..212b9d8b7b8 100644 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js @@ -1,38 +1,87 @@ //// [blockScopedVariablesUseBeforeDef.ts] function foo1() { - let a = () => x; - let x; + let a = () => x; + let x; } function foo2() { - let a = function () { return x; } - let x; + let a = function () { return x; } + let x; } function foo3() { - class X { - m() { return x;} - } - let x; + class X { + m() { return x;} + } + let x; } function foo4() { - let y = class { - m() { return x; } - }; - let x; + let y = class { + m() { return x; } + }; + let x; } function foo5() { - let x = () => y; - let y = () => x; + let x = () => y; + let y = () => x; } function foo6() { - function f() { - return x; - } - let x; + function f() { + return x; + } + let x; +} + +function foo7() { + class A { + a = x; + } + let x; +} + +function foo8() { + let y = class { + a = x; + } + let x; +} + +function foo9() { + let y = class { + static a = x; + } + let x; +} + +function foo10() { + class A { + static a = x; + } + let x; +} + +function foo11() { + function f () { + let y = class { + static a = x; + } + } + let x; +} + +function foo12() { + function f () { + let y = class { + a; + constructor() { + this.a = x; + } + } + } + let x; } //// [blockScopedVariablesUseBeforeDef.js] @@ -72,3 +121,61 @@ function foo6() { } var x; } +function foo7() { + var A = (function () { + function A() { + this.a = x; + } + return A; + })(); + var x; +} +function foo8() { + var y = (function () { + function class_2() { + this.a = x; + } + return class_2; + })(); + var x; +} +function foo9() { + var y = (function () { + function class_3() { + } + class_3.a = x; + return class_3; + })(); + var x; +} +function foo10() { + var A = (function () { + function A() { + } + A.a = x; + return A; + })(); + var x; +} +function foo11() { + function f() { + var y = (function () { + function class_4() { + } + class_4.a = x; + return class_4; + })(); + } + var x; +} +function foo12() { + function f() { + var y = (function () { + function class_5() { + this.a = x; + } + return class_5; + })(); + } + var x; +} diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols deleted file mode 100644 index a528af236c1..00000000000 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols +++ /dev/null @@ -1,76 +0,0 @@ -=== tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts === -function foo1() { ->foo1 : Symbol(foo1, Decl(blockScopedVariablesUseBeforeDef.ts, 0, 0)) - - let a = () => x; ->a : Symbol(a, Decl(blockScopedVariablesUseBeforeDef.ts, 1, 4)) ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 2, 4)) - - let x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 2, 4)) -} - -function foo2() { ->foo2 : Symbol(foo2, Decl(blockScopedVariablesUseBeforeDef.ts, 3, 1)) - - let a = function () { return x; } ->a : Symbol(a, Decl(blockScopedVariablesUseBeforeDef.ts, 6, 4)) ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 7, 4)) - - let x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 7, 4)) -} - -function foo3() { ->foo3 : Symbol(foo3, Decl(blockScopedVariablesUseBeforeDef.ts, 8, 1)) - - class X { ->X : Symbol(X, Decl(blockScopedVariablesUseBeforeDef.ts, 10, 17)) - - m() { return x;} ->m : Symbol(m, Decl(blockScopedVariablesUseBeforeDef.ts, 11, 10)) ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 14, 4)) - } - let x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 14, 4)) -} - -function foo4() { ->foo4 : Symbol(foo4, Decl(blockScopedVariablesUseBeforeDef.ts, 15, 1)) - - let y = class { ->y : Symbol(y, Decl(blockScopedVariablesUseBeforeDef.ts, 18, 4)) - - m() { return x; } ->m : Symbol((Anonymous class).m, Decl(blockScopedVariablesUseBeforeDef.ts, 18, 16)) ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 21, 4)) - - }; - let x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 21, 4)) -} - -function foo5() { ->foo5 : Symbol(foo5, Decl(blockScopedVariablesUseBeforeDef.ts, 22, 1)) - - let x = () => y; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 25, 4)) ->y : Symbol(y, Decl(blockScopedVariablesUseBeforeDef.ts, 26, 4)) - - let y = () => x; ->y : Symbol(y, Decl(blockScopedVariablesUseBeforeDef.ts, 26, 4)) ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 25, 4)) -} - -function foo6() { ->foo6 : Symbol(foo6, Decl(blockScopedVariablesUseBeforeDef.ts, 27, 1)) - - function f() { ->f : Symbol(f, Decl(blockScopedVariablesUseBeforeDef.ts, 29, 17)) - - return x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 33, 4)) - } - let x; ->x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 33, 4)) -} diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types deleted file mode 100644 index bc3d5f8eba8..00000000000 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types +++ /dev/null @@ -1,81 +0,0 @@ -=== tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts === -function foo1() { ->foo1 : () => void - - let a = () => x; ->a : () => any ->() => x : () => any ->x : any - - let x; ->x : any -} - -function foo2() { ->foo2 : () => void - - let a = function () { return x; } ->a : () => any ->function () { return x; } : () => any ->x : any - - let x; ->x : any -} - -function foo3() { ->foo3 : () => void - - class X { ->X : X - - m() { return x;} ->m : () => any ->x : any - } - let x; ->x : any -} - -function foo4() { ->foo4 : () => void - - let y = class { ->y : typeof (Anonymous class) ->class { m() { return x; } } : typeof (Anonymous class) - - m() { return x; } ->m : () => any ->x : any - - }; - let x; ->x : any -} - -function foo5() { ->foo5 : () => void - - let x = () => y; ->x : () => () => any ->() => y : () => () => any ->y : () => () => any - - let y = () => x; ->y : () => () => any ->() => x : () => () => any ->x : () => () => any -} - -function foo6() { ->foo6 : () => void - - function f() { ->f : () => any - - return x; ->x : any - } - let x; ->x : any -} diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt deleted file mode 100644 index a4d28f51878..00000000000 --- a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt +++ /dev/null @@ -1,11 +0,0 @@ -tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'c' used before its declaration. - - -==== tests/cases/compiler/file1.ts (1 errors) ==== - - c; - ~ -!!! error TS2448: Block-scoped variable 'c' used before its declaration. - -==== tests/cases/compiler/file2.ts (0 errors) ==== - const c = 0; \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.symbols b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.symbols new file mode 100644 index 00000000000..281ce427733 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/file1.ts === + +c; +>c : Symbol(c, Decl(file2.ts, 0, 5)) + +=== tests/cases/compiler/file2.ts === +const c = 0; +>c : Symbol(c, Decl(file2.ts, 0, 5)) + diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.types b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.types new file mode 100644 index 00000000000..ae60fdfa477 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/file1.ts === + +c; +>c : number + +=== tests/cases/compiler/file2.ts === +const c = 0; +>c : number +>0 : number + diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt deleted file mode 100644 index 5b8633312d9..00000000000 --- a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt +++ /dev/null @@ -1,11 +0,0 @@ -tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'l' used before its declaration. - - -==== tests/cases/compiler/file1.ts (1 errors) ==== - - l; - ~ -!!! error TS2448: Block-scoped variable 'l' used before its declaration. - -==== tests/cases/compiler/file2.ts (0 errors) ==== - const l = 0; \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.symbols b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.symbols new file mode 100644 index 00000000000..c5a067ede4d --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/file1.ts === + +l; +>l : Symbol(l, Decl(file2.ts, 0, 5)) + +=== tests/cases/compiler/file2.ts === +const l = 0; +>l : Symbol(l, Decl(file2.ts, 0, 5)) + diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.types b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.types new file mode 100644 index 00000000000..793a7a78ba7 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/file1.ts === + +l; +>l : number + +=== tests/cases/compiler/file2.ts === +const l = 0; +>l : number +>0 : number + diff --git a/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts b/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts index 7ded92df4c9..287f5ae117e 100644 --- a/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts +++ b/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts @@ -1,35 +1,84 @@ function foo1() { - let a = () => x; - let x; + let a = () => x; + let x; } function foo2() { - let a = function () { return x; } - let x; + let a = function () { return x; } + let x; } function foo3() { - class X { - m() { return x;} - } - let x; + class X { + m() { return x;} + } + let x; } function foo4() { - let y = class { - m() { return x; } - }; - let x; + let y = class { + m() { return x; } + }; + let x; } function foo5() { - let x = () => y; - let y = () => x; + let x = () => y; + let y = () => x; } function foo6() { - function f() { - return x; - } - let x; + function f() { + return x; + } + let x; +} + +function foo7() { + class A { + a = x; + } + let x; +} + +function foo8() { + let y = class { + a = x; + } + let x; +} + +function foo9() { + let y = class { + static a = x; + } + let x; +} + +function foo10() { + class A { + static a = x; + } + let x; +} + +function foo11() { + function f () { + let y = class { + static a = x; + } + } + let x; +} + +function foo12() { + function f () { + let y = class { + a; + constructor() { + this.a = x; + } + } + } + let x; } \ No newline at end of file