check usage before declaration for computed properties in destructuring inside for-of variable declaration

This commit is contained in:
Vladimir Matveev 2016-05-02 13:31:35 -07:00
parent a7e40469ff
commit 50390bb586
4 changed files with 72 additions and 10 deletions

View file

@ -574,18 +574,28 @@ namespace ts {
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
const container = getEnclosingBlockScopeContainer(declaration);
if (declaration.parent.parent.kind === SyntaxKind.VariableStatement ||
declaration.parent.parent.kind === SyntaxKind.ForStatement) {
// variable statement/for statement case,
// use site should not be inside variable declaration (initializer of declaration or binding element)
return isSameScopeDescendentOf(usage, declaration, container);
switch (declaration.parent.parent.kind) {
case SyntaxKind.VariableStatement:
case SyntaxKind.ForStatement:
case SyntaxKind.ForOfStatement:
// variable statement/for/for-of statement case,
// use site should not be inside variable declaration (initializer of declaration or binding element)
if (isSameScopeDescendentOf(usage, declaration, container)) {
return true;
}
break;
}
else if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement ||
declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
// ForIn/ForOf case - use site should not be used in expression part
const expression = (<ForInStatement | ForOfStatement>declaration.parent.parent).expression;
return isSameScopeDescendentOf(usage, expression, container);
switch (declaration.parent.parent.kind) {
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
// ForIn/ForOf case - use site should not be used in expression part
if (isSameScopeDescendentOf(usage, (<ForInStatement | ForOfStatement>declaration.parent.parent).expression, container)) {
return true;
}
}
return false;
}
function isUsedInFunctionOrNonStaticProperty(declaration: Declaration, usage: Node): boolean {

View file

@ -0,0 +1,23 @@
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2448: Block-scoped variable 'a' used before its declaration.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2448: Block-scoped variable 'a' used before its declaration.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,35): error TS7027: Unreachable code detected.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Block-scoped variable 'b' used before its declaration.
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (4 errors) ====
// 1:
for (let {[a]: a} of [{ }]) continue;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
// 2:
for (let {[a]: a} = { }; false; ) continue;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
~~~~~~~~
!!! error TS7027: Unreachable code detected.
// 3:
let {[b]: b} = { };
~
!!! error TS2448: Block-scoped variable 'b' used before its declaration.

View file

@ -0,0 +1,21 @@
//// [blockScopedBindingUsedBeforeDef.ts]
// 1:
for (let {[a]: a} of [{ }]) continue;
// 2:
for (let {[a]: a} = { }; false; ) continue;
// 3:
let {[b]: b} = { };
//// [blockScopedBindingUsedBeforeDef.js]
// 1:
for (var _i = 0, _a = [{}]; _i < _a.length; _i++) {
var _b = a, a = _a[_i][_b];
continue;
}
// 2:
for (var _c = a, a = {}[_c]; false;)
continue;
// 3:
var _d = b, b = {}[_d];

View file

@ -0,0 +1,8 @@
// 1:
for (let {[a]: a} of [{ }]) continue;
// 2:
for (let {[a]: a} = { }; false; ) continue;
// 3:
let {[b]: b} = { };