mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-08 12:55:49 -05:00
* 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:
@@ -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) {
|
||||
|
||||
38
tests/baselines/reference/useBeforeDeclaration.js
Normal file
38
tests/baselines/reference/useBeforeDeclaration.js
Normal 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 = {}));
|
||||
34
tests/baselines/reference/useBeforeDeclaration.symbols
Normal file
34
tests/baselines/reference/useBeforeDeclaration.symbols
Normal 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))
|
||||
|
||||
}
|
||||
|
||||
|
||||
39
tests/baselines/reference/useBeforeDeclaration.types
Normal file
39
tests/baselines/reference/useBeforeDeclaration.types
Normal 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"
|
||||
|
||||
}
|
||||
|
||||
|
||||
20
tests/cases/compiler/useBeforeDeclaration.ts
Normal file
20
tests/cases/compiler/useBeforeDeclaration.ts
Normal 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"};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user