@@ -16726,6 +16726,11 @@ namespace ts {
16726
16726
if (container.kind === SyntaxKind.PropertyDeclaration && hasModifier(container, ModifierFlags.Static)) {
16727
16727
getNodeLinks(declaration).flags |= NodeCheckFlags.ClassWithConstructorReference;
16728
16728
getNodeLinks(node).flags |= NodeCheckFlags.ConstructorReferenceInClass;
16729
+ // If the class expression is in a loop and the name of the class is used,
16730
+ // the temporary variable which stores the evaluated class expression must be block scoped.
16731
+ if (getEnclosingIterationStatement(declaration)) {
16732
+ getNodeLinks(declaration).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
16733
+ }
16729
16734
}
16730
16735
break;
16731
16736
}
@@ -16831,6 +16836,10 @@ namespace ts {
16831
16836
return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n));
16832
16837
}
16833
16838
16839
+ function getEnclosingIterationStatement(node: Node): Node | undefined {
16840
+ return findAncestor(node, n => (!n || nodeStartsNewLexicalEnvironment(n)) ? "quit" : isIterationStatement(n, /* lookInLabeledStatements */ false));
16841
+ }
16842
+
16834
16843
function getPartOfForStatementContainingNode(node: Node, container: ForStatement) {
16835
16844
return findAncestor(node, n => n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement);
16836
16845
}
@@ -16849,18 +16858,8 @@ namespace ts {
16849
16858
16850
16859
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
16851
16860
const usedInFunction = isInsideFunction(node.parent, container);
16852
- let current = container;
16853
-
16854
- let containedInIterationStatement = false;
16855
- while (current && !nodeStartsNewLexicalEnvironment(current)) {
16856
- if (isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
16857
- containedInIterationStatement = true;
16858
- break;
16859
- }
16860
- current = current.parent;
16861
- }
16862
-
16863
- if (containedInIterationStatement) {
16861
+ const enclosingIterationStatement = getEnclosingIterationStatement(container);
16862
+ if (enclosingIterationStatement) {
16864
16863
if (usedInFunction) {
16865
16864
// mark iteration statement as containing block-scoped binding captured in some function
16866
16865
let capturesBlockScopeBindingInLoopBody = true;
@@ -16880,7 +16879,7 @@ namespace ts {
16880
16879
}
16881
16880
}
16882
16881
if (capturesBlockScopeBindingInLoopBody) {
16883
- getNodeLinks(current ).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
16882
+ getNodeLinks(enclosingIterationStatement ).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
16884
16883
}
16885
16884
}
16886
16885
@@ -18439,6 +18438,20 @@ namespace ts {
18439
18438
const links = getNodeLinks(node.expression);
18440
18439
if (!links.resolvedType) {
18441
18440
links.resolvedType = checkExpression(node.expression);
18441
+
18442
+ if (isPropertyDeclaration(node.parent) && isClassExpression(node.parent.parent)) {
18443
+ const container = getEnclosingBlockScopeContainer(node);
18444
+ const enclosingIterationStatement = getEnclosingIterationStatement(container);
18445
+ // A computed property of a class expression inside a loop must be block scoped because
18446
+ // the property name should be bound at class evaluation time.
18447
+ if (enclosingIterationStatement) {
18448
+ getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
18449
+ // The hoisted variable which stores the evaluated property name should be block scoped.
18450
+ getNodeLinks(node).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
18451
+ // The temporary name of the class expression should be block scoped.
18452
+ getNodeLinks(node.parent.parent).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
18453
+ }
18454
+ }
18442
18455
// This will allow types number, string, symbol or any. It will also allow enums, the unknown
18443
18456
// type, and any union of these types (like string | number).
18444
18457
if (links.resolvedType.flags & TypeFlags.Nullable ||
0 commit comments