Skip to content

Commit 8173ee9

Browse files
committed
Merge pull request #8425 from Microsoft/use-before-def
check usage before declaration for computed properties in destructuri…
2 parents 4d53a21 + 50390bb commit 8173ee9

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -574,18 +574,28 @@ namespace ts {
574574
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
575575
const container = getEnclosingBlockScopeContainer(declaration);
576576

577-
if (declaration.parent.parent.kind === SyntaxKind.VariableStatement ||
578-
declaration.parent.parent.kind === SyntaxKind.ForStatement) {
579-
// variable statement/for statement case,
580-
// use site should not be inside variable declaration (initializer of declaration or binding element)
581-
return isSameScopeDescendentOf(usage, declaration, container);
582-
}
583-
else if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement ||
584-
declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
585-
// ForIn/ForOf case - use site should not be used in expression part
586-
const expression = (<ForInStatement | ForOfStatement>declaration.parent.parent).expression;
587-
return isSameScopeDescendentOf(usage, expression, container);
577+
switch (declaration.parent.parent.kind) {
578+
case SyntaxKind.VariableStatement:
579+
case SyntaxKind.ForStatement:
580+
case SyntaxKind.ForOfStatement:
581+
// variable statement/for/for-of statement case,
582+
// use site should not be inside variable declaration (initializer of declaration or binding element)
583+
if (isSameScopeDescendentOf(usage, declaration, container)) {
584+
return true;
585+
}
586+
break;
588587
}
588+
589+
switch (declaration.parent.parent.kind) {
590+
case SyntaxKind.ForInStatement:
591+
case SyntaxKind.ForOfStatement:
592+
// ForIn/ForOf case - use site should not be used in expression part
593+
if (isSameScopeDescendentOf(usage, (<ForInStatement | ForOfStatement>declaration.parent.parent).expression, container)) {
594+
return true;
595+
}
596+
}
597+
598+
return false;
589599
}
590600

591601
function isUsedInFunctionOrNonStaticProperty(declaration: Declaration, usage: Node): boolean {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2448: Block-scoped variable 'a' used before its declaration.
2+
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2448: Block-scoped variable 'a' used before its declaration.
3+
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,35): error TS7027: Unreachable code detected.
4+
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Block-scoped variable 'b' used before its declaration.
5+
6+
7+
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (4 errors) ====
8+
// 1:
9+
for (let {[a]: a} of [{ }]) continue;
10+
~
11+
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
12+
13+
// 2:
14+
for (let {[a]: a} = { }; false; ) continue;
15+
~
16+
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
17+
~~~~~~~~
18+
!!! error TS7027: Unreachable code detected.
19+
20+
// 3:
21+
let {[b]: b} = { };
22+
~
23+
!!! error TS2448: Block-scoped variable 'b' used before its declaration.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [blockScopedBindingUsedBeforeDef.ts]
2+
// 1:
3+
for (let {[a]: a} of [{ }]) continue;
4+
5+
// 2:
6+
for (let {[a]: a} = { }; false; ) continue;
7+
8+
// 3:
9+
let {[b]: b} = { };
10+
11+
//// [blockScopedBindingUsedBeforeDef.js]
12+
// 1:
13+
for (var _i = 0, _a = [{}]; _i < _a.length; _i++) {
14+
var _b = a, a = _a[_i][_b];
15+
continue;
16+
}
17+
// 2:
18+
for (var _c = a, a = {}[_c]; false;)
19+
continue;
20+
// 3:
21+
var _d = b, b = {}[_d];
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// 1:
2+
for (let {[a]: a} of [{ }]) continue;
3+
4+
// 2:
5+
for (let {[a]: a} = { }; false; ) continue;
6+
7+
// 3:
8+
let {[b]: b} = { };

0 commit comments

Comments
 (0)