Fix #11660: wrong reports that block-scoped variable used before its … (#11692)

* Fix #11660: wrong reports that block-scoped variable used before its declaration

* Fix code style in checker.ts

* Add unit test for #11660

* Fix the unit test for #11660
This commit is contained in:
Dom Chen
2016-10-20 04:07:49 +08:00
committed by Mohamed Hegazy
parent 06afadda72
commit 0365c96e37
5 changed files with 139 additions and 4 deletions

View File

@@ -591,7 +591,11 @@ namespace ts {
// nodes are in different files and order cannot be determines
return true;
}
// declaration is after usage
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
if (isUsedInFunctionOrNonStaticProperty(usage)) {
return true;
}
const sourceFiles = host.getSourceFiles();
return indexOf(sourceFiles, declarationFile) <= indexOf(sourceFiles, useFile);
}
@@ -605,7 +609,8 @@ namespace ts {
// declaration is after usage
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
return isUsedInFunctionOrNonStaticProperty(declaration, usage);
const container = getEnclosingBlockScopeContainer(declaration);
return isUsedInFunctionOrNonStaticProperty(usage, container);
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
const container = getEnclosingBlockScopeContainer(declaration);
@@ -634,8 +639,7 @@ namespace ts {
return false;
}
function isUsedInFunctionOrNonStaticProperty(declaration: Declaration, usage: Node): boolean {
const container = getEnclosingBlockScopeContainer(declaration);
function isUsedInFunctionOrNonStaticProperty(usage: Node, container?: Node): boolean {
let current = usage;
while (current) {
if (current === container) {

View File

@@ -0,0 +1,38 @@
//// [tests/cases/compiler/useBeforeDeclaration.ts] ////
//// [A.ts]
namespace ts {
export function printVersion():void {
log("Version: " + sys.version); // the call of sys.version is deferred, should not report an error.
}
export function log(info:string):void {
}
}
//// [B.ts]
namespace ts {
export let sys:{version:string} = {version: "2.0.5"};
}
//// [test.js]
var ts;
(function (ts) {
function printVersion() {
log("Version: " + ts.sys.version); // the call of sys.version is deferred, should not report an error.
}
ts.printVersion = printVersion;
function log(info) {
}
ts.log = log;
})(ts || (ts = {}));
var ts;
(function (ts) {
ts.sys = { version: "2.0.5" };
})(ts || (ts = {}));

View File

@@ -0,0 +1,34 @@
=== tests/cases/compiler/A.ts ===
namespace ts {
>ts : Symbol(ts, Decl(A.ts, 0, 0), Decl(B.ts, 0, 0))
export function printVersion():void {
>printVersion : Symbol(printVersion, Decl(A.ts, 1, 14))
log("Version: " + sys.version); // the call of sys.version is deferred, should not report an error.
>log : Symbol(log, Decl(A.ts, 4, 5))
>sys.version : Symbol(version, Decl(B.ts, 2, 20))
>sys : Symbol(sys, Decl(B.ts, 2, 14))
>version : Symbol(version, Decl(B.ts, 2, 20))
}
export function log(info:string):void {
>log : Symbol(log, Decl(A.ts, 4, 5))
>info : Symbol(info, Decl(A.ts, 6, 24))
}
}
=== tests/cases/compiler/B.ts ===
namespace ts {
>ts : Symbol(ts, Decl(A.ts, 0, 0), Decl(B.ts, 0, 0))
export let sys:{version:string} = {version: "2.0.5"};
>sys : Symbol(sys, Decl(B.ts, 2, 14))
>version : Symbol(version, Decl(B.ts, 2, 20))
>version : Symbol(version, Decl(B.ts, 2, 39))
}

View File

@@ -0,0 +1,39 @@
=== tests/cases/compiler/A.ts ===
namespace ts {
>ts : typeof ts
export function printVersion():void {
>printVersion : () => void
log("Version: " + sys.version); // the call of sys.version is deferred, should not report an error.
>log("Version: " + sys.version) : void
>log : (info: string) => void
>"Version: " + sys.version : string
>"Version: " : "Version: "
>sys.version : string
>sys : { version: string; }
>version : string
}
export function log(info:string):void {
>log : (info: string) => void
>info : string
}
}
=== tests/cases/compiler/B.ts ===
namespace ts {
>ts : typeof ts
export let sys:{version:string} = {version: "2.0.5"};
>sys : { version: string; }
>version : string
>{version: "2.0.5"} : { version: string; }
>version : string
>"2.0.5" : "2.0.5"
}

View File

@@ -0,0 +1,20 @@
// @outFile: test.js
// @fileName: A.ts
namespace ts {
export function printVersion():void {
log("Version: " + sys.version); // the call of sys.version is deferred, should not report an error.
}
export function log(info:string):void {
}
}
// @fileName: B.ts
namespace ts {
export let sys:{version:string} = {version: "2.0.5"};
}