mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Bloomberg computed property name fix (#43197)
* Fix property name bindings for class expr in loops * Fix block-scope capturing with prop initializers Co-authored-by: Joey Watts <joey.watts.96@gmail.com>
This commit is contained in:
co-authored by
Joey Watts
parent
998ecd9c06
commit
b2d1f537f1
+38
-17
@@ -23775,14 +23775,20 @@ namespace ts {
|
||||
return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
|
||||
}
|
||||
|
||||
function isInsideFunction(node: Node, threshold: Node): boolean {
|
||||
return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n));
|
||||
function isInsideFunctionOrInstancePropertyInitializer(node: Node, threshold: Node): boolean {
|
||||
return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n) || (
|
||||
n.parent && isPropertyDeclaration(n.parent) && !hasStaticModifier(n.parent) && n.parent.initializer === n
|
||||
));
|
||||
}
|
||||
|
||||
function getPartOfForStatementContainingNode(node: Node, container: ForStatement) {
|
||||
return findAncestor(node, n => n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement);
|
||||
}
|
||||
|
||||
function getEnclosingIterationStatement(node: Node): Node | undefined {
|
||||
return findAncestor(node, n => (!n || nodeStartsNewLexicalEnvironment(n)) ? "quit" : isIterationStatement(n, /*lookInLabeledStatements*/ false));
|
||||
}
|
||||
|
||||
function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void {
|
||||
if (languageVersion >= ScriptTarget.ES2015 ||
|
||||
(symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 ||
|
||||
@@ -23798,20 +23804,11 @@ namespace ts {
|
||||
// if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
|
||||
|
||||
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
|
||||
const usedInFunction = isInsideFunction(node.parent, container);
|
||||
let current = container;
|
||||
const isCaptured = isInsideFunctionOrInstancePropertyInitializer(node, container);
|
||||
|
||||
let containedInIterationStatement = false;
|
||||
while (current && !nodeStartsNewLexicalEnvironment(current)) {
|
||||
if (isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
|
||||
containedInIterationStatement = true;
|
||||
break;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
if (containedInIterationStatement) {
|
||||
if (usedInFunction) {
|
||||
const enclosingIterationStatement = getEnclosingIterationStatement(container);
|
||||
if (enclosingIterationStatement) {
|
||||
if (isCaptured) {
|
||||
// mark iteration statement as containing block-scoped binding captured in some function
|
||||
let capturesBlockScopeBindingInLoopBody = true;
|
||||
if (isForStatement(container)) {
|
||||
@@ -23832,7 +23829,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (capturesBlockScopeBindingInLoopBody) {
|
||||
getNodeLinks(current).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23849,7 +23846,7 @@ namespace ts {
|
||||
getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
|
||||
}
|
||||
|
||||
if (usedInFunction) {
|
||||
if (isCaptured) {
|
||||
getNodeLinks(symbol.valueDeclaration).flags |= NodeCheckFlags.CapturedBlockScopedBinding;
|
||||
}
|
||||
}
|
||||
@@ -25529,6 +25526,20 @@ namespace ts {
|
||||
const links = getNodeLinks(node.expression);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = checkExpression(node.expression);
|
||||
// The computed property name of a non-static class field within a loop must be stored in a block-scoped binding.
|
||||
// (It needs to be bound at class evaluation time.)
|
||||
if (isPropertyDeclaration(node.parent) && !hasStaticModifier(node.parent) && isClassExpression(node.parent.parent)) {
|
||||
const container = getEnclosingBlockScopeContainer(node.parent.parent);
|
||||
const enclosingIterationStatement = getEnclosingIterationStatement(container);
|
||||
if (enclosingIterationStatement) {
|
||||
// The computed field name will use a block scoped binding which can be unique for each iteration of the loop.
|
||||
getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
// The generated variable which stores the computed field name must be block-scoped.
|
||||
getNodeLinks(node).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
|
||||
// The generated variable which stores the class must be block-scoped.
|
||||
getNodeLinks(node.parent.parent).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
|
||||
}
|
||||
}
|
||||
// This will allow types number, string, symbol or any. It will also allow enums, the unknown
|
||||
// type, and any union of these types (like string | number).
|
||||
if (links.resolvedType.flags & TypeFlags.Nullable ||
|
||||
@@ -32617,6 +32628,16 @@ namespace ts {
|
||||
for (let lexicalScope = getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = getEnclosingBlockScopeContainer(lexicalScope)) {
|
||||
getNodeLinks(lexicalScope).flags |= NodeCheckFlags.ContainsClassWithPrivateIdentifiers;
|
||||
}
|
||||
|
||||
// If this is a private field in a class expression inside the body of a loop,
|
||||
// then we must use a block-scoped binding to store the WeakMap.
|
||||
if (isClassExpression(node.parent)) {
|
||||
const enclosingIterationStatement = getEnclosingIterationStatement(node.parent);
|
||||
if (enclosingIterationStatement) {
|
||||
getNodeLinks(node.name).flags |= NodeCheckFlags.BlockScopedBindingInLoop;
|
||||
getNodeLinks(enclosingIterationStatement).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,9 @@ namespace ts {
|
||||
let lexicalEnvironmentFlagsStack: LexicalEnvironmentFlags[] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
let blockScopedVariableDeclarationsStack: Identifier[][] = [];
|
||||
let blockScopeStackOffset = 0;
|
||||
let blockScopedVariableDeclarations: Identifier[];
|
||||
let emitHelpers: EmitHelper[] | undefined;
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = noEmitSubstitution;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = noEmitNotification;
|
||||
@@ -182,6 +185,9 @@ namespace ts {
|
||||
hoistVariableDeclaration,
|
||||
hoistFunctionDeclaration,
|
||||
addInitializationStatement,
|
||||
startBlockScope,
|
||||
endBlockScope,
|
||||
addBlockScopedVariable,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
enableSubstitution,
|
||||
@@ -473,6 +479,46 @@ namespace ts {
|
||||
return lexicalEnvironmentFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a block scope. Any existing block hoisted variables are pushed onto the stack and the related storage variables are reset.
|
||||
*/
|
||||
function startBlockScope() {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot start a block scope during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot start a block scope after transformation has completed.");
|
||||
blockScopedVariableDeclarationsStack[blockScopeStackOffset] = blockScopedVariableDeclarations;
|
||||
blockScopeStackOffset++;
|
||||
blockScopedVariableDeclarations = undefined!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a block scope. The previous set of block hoisted variables are restored. Any hoisted declarations are returned.
|
||||
*/
|
||||
function endBlockScope() {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot end a block scope during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot end a block scope after transformation has completed.");
|
||||
const statements: Statement[] | undefined = some(blockScopedVariableDeclarations) ?
|
||||
[
|
||||
factory.createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
factory.createVariableDeclarationList(
|
||||
blockScopedVariableDeclarations.map(identifier => factory.createVariableDeclaration(identifier)),
|
||||
NodeFlags.Let
|
||||
)
|
||||
)
|
||||
] : undefined;
|
||||
blockScopeStackOffset--;
|
||||
blockScopedVariableDeclarations = blockScopedVariableDeclarationsStack[blockScopeStackOffset];
|
||||
if (blockScopeStackOffset === 0) {
|
||||
blockScopedVariableDeclarationsStack = [];
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
function addBlockScopedVariable(name: Identifier): void {
|
||||
Debug.assert(blockScopeStackOffset > 0, "Cannot add a block scoped variable outside of an iteration body.");
|
||||
(blockScopedVariableDeclarations || (blockScopedVariableDeclarations = [])).push(name);
|
||||
}
|
||||
|
||||
function requestEmitHelper(helper: EmitHelper): void {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
@@ -539,5 +585,8 @@ namespace ts {
|
||||
startLexicalEnvironment: noop,
|
||||
suspendLexicalEnvironment: noop,
|
||||
addDiagnostic: noop,
|
||||
startBlockScope: noop,
|
||||
endBlockScope: returnUndefined,
|
||||
addBlockScopedVariable: noop
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ namespace ts {
|
||||
factory,
|
||||
hoistVariableDeclaration,
|
||||
endLexicalEnvironment,
|
||||
resumeLexicalEnvironment
|
||||
resumeLexicalEnvironment,
|
||||
addBlockScopedVariable
|
||||
} = context;
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
@@ -310,7 +311,7 @@ namespace ts {
|
||||
visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitPostfixUnaryExpression(node.incrementor, /*valueIsDiscarded*/ true),
|
||||
visitNode(node.statement, visitor, isStatement)
|
||||
visitIterationBody(node.statement, visitor, context)
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
@@ -540,8 +541,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const expressions: Expression[] = [];
|
||||
const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference;
|
||||
const temp = factory.createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
|
||||
const classCheckFlags = resolver.getNodeCheckFlags(node);
|
||||
const isClassWithConstructorReference = classCheckFlags & NodeCheckFlags.ClassWithConstructorReference;
|
||||
const requiresBlockScopedVar = classCheckFlags & NodeCheckFlags.BlockScopedBindingInLoop;
|
||||
const temp = factory.createTempVariable(requiresBlockScopedVar ? addBlockScopedVariable : hoistVariableDeclaration, !!isClassWithConstructorReference);
|
||||
if (isClassWithConstructorReference) {
|
||||
// record an alias as the class name is not in scope for statics.
|
||||
enableSubstitutionForClassAliases();
|
||||
@@ -869,7 +872,6 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the name is a computed property, this function transforms it, then either returns an expression which caches the
|
||||
* value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
|
||||
@@ -883,7 +885,12 @@ namespace ts {
|
||||
const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
|
||||
if (!alreadyTransformed && !inlinable && shouldHoist) {
|
||||
const generatedName = factory.getGeneratedNameForNode(name);
|
||||
hoistVariableDeclaration(generatedName);
|
||||
if (resolver.getNodeCheckFlags(name) & NodeCheckFlags.BlockScopedBindingInLoop) {
|
||||
addBlockScopedVariable(generatedName);
|
||||
}
|
||||
else {
|
||||
hoistVariableDeclaration(generatedName);
|
||||
}
|
||||
return factory.createAssignment(generatedName, expression);
|
||||
}
|
||||
return (inlinable || isIdentifier(innerExpression)) ? undefined : expression;
|
||||
@@ -910,7 +917,12 @@ namespace ts {
|
||||
function addPrivateIdentifierToEnvironment(name: PrivateIdentifier) {
|
||||
const text = getTextOfPropertyName(name) as string;
|
||||
const weakMapName = factory.createUniqueName("_" + text.substring(1), GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes);
|
||||
hoistVariableDeclaration(weakMapName);
|
||||
if (resolver.getNodeCheckFlags(name) & NodeCheckFlags.BlockScopedBindingInLoop) {
|
||||
addBlockScopedVariable(weakMapName);
|
||||
}
|
||||
else {
|
||||
hoistVariableDeclaration(weakMapName);
|
||||
}
|
||||
getPrivateIdentifierEnvironment().set(name.escapedText, { placement: PrivateIdentifierPlacement.InstanceField, weakMapName });
|
||||
getPendingExpressions().push(
|
||||
factory.createAssignment(
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace ts {
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, asyncBodyVisitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace ts {
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, asyncBodyVisitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace ts {
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, asyncBodyVisitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -575,7 +575,7 @@ namespace ts {
|
||||
visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement)
|
||||
visitIterationBody(node.statement, visitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -648,7 +648,7 @@ namespace ts {
|
||||
let bodyLocation: TextRange | undefined;
|
||||
let statementsLocation: TextRange | undefined;
|
||||
const statements: Statement[] = [visitNode(binding, visitor, isStatement)];
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
const statement = visitIterationBody(node.statement, visitor, context);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
|
||||
@@ -1502,7 +1502,7 @@ namespace ts {
|
||||
: undefined,
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, visitor, context)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1231,7 +1231,7 @@ namespace ts {
|
||||
node.initializer && visitForInitializer(node.initializer),
|
||||
visitNode(node.condition, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.incrementor, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement)
|
||||
visitIterationBody(node.statement, nestedElementVisitor, context)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@@ -1251,7 +1251,7 @@ namespace ts {
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, nestedElementVisitor, context)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@@ -1272,7 +1272,7 @@ namespace ts {
|
||||
node.awaitModifier,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, nestedElementVisitor, context)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@@ -1320,7 +1320,7 @@ namespace ts {
|
||||
function visitDoStatement(node: DoStatement): VisitResult<Statement> {
|
||||
return factory.updateDoStatement(
|
||||
node,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock),
|
||||
visitIterationBody(node.statement, nestedElementVisitor, context),
|
||||
visitNode(node.expression, destructuringAndImportCallVisitor, isExpression)
|
||||
);
|
||||
}
|
||||
@@ -1334,7 +1334,7 @@ namespace ts {
|
||||
return factory.updateWhileStatement(
|
||||
node,
|
||||
visitNode(node.expression, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, factory.liftToBlock)
|
||||
visitIterationBody(node.statement, nestedElementVisitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7520,6 +7520,12 @@ namespace ts {
|
||||
/** Hoists a variable declaration to the containing scope. */
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/*@internal*/ startBlockScope(): void;
|
||||
|
||||
/*@internal*/ endBlockScope(): Statement[] | undefined;
|
||||
|
||||
/*@internal*/ addBlockScopedVariable(node: Identifier): void;
|
||||
|
||||
/** Adds an initialization statement to the top of the lexical environment. */
|
||||
/* @internal */
|
||||
addInitializationStatement(node: Statement): void;
|
||||
|
||||
@@ -311,6 +311,24 @@ namespace ts {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an iteration body, adding any block-scoped variables required by the transformation.
|
||||
*/
|
||||
export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement {
|
||||
context.startBlockScope();
|
||||
const updated = visitNode(body, visitor, isStatement, context.factory.liftToBlock);
|
||||
const declarations = context.endBlockScope();
|
||||
if (some(declarations)) {
|
||||
if (isBlock(updated)) {
|
||||
declarations.push(...updated.statements);
|
||||
return context.factory.updateBlock(updated, declarations);
|
||||
}
|
||||
declarations.push(updated);
|
||||
return context.factory.createBlock(declarations);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
|
||||
*
|
||||
@@ -872,14 +890,14 @@ namespace ts {
|
||||
case SyntaxKind.DoStatement:
|
||||
Debug.type<DoStatement>(node);
|
||||
return factory.updateDoStatement(node,
|
||||
nodeVisitor(node.statement, visitor, isStatement, factory.liftToBlock),
|
||||
visitIterationBody(node.statement, visitor, context),
|
||||
nodeVisitor(node.expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.WhileStatement:
|
||||
Debug.type<WhileStatement>(node);
|
||||
return factory.updateWhileStatement(node,
|
||||
nodeVisitor(node.expression, visitor, isExpression),
|
||||
nodeVisitor(node.statement, visitor, isStatement, factory.liftToBlock));
|
||||
visitIterationBody(node.statement, visitor, context));
|
||||
|
||||
case SyntaxKind.ForStatement:
|
||||
Debug.type<ForStatement>(node);
|
||||
@@ -887,14 +905,14 @@ namespace ts {
|
||||
nodeVisitor(node.initializer, visitor, isForInitializer),
|
||||
nodeVisitor(node.condition, visitor, isExpression),
|
||||
nodeVisitor(node.incrementor, visitor, isExpression),
|
||||
nodeVisitor(node.statement, visitor, isStatement, factory.liftToBlock));
|
||||
visitIterationBody(node.statement, visitor, context));
|
||||
|
||||
case SyntaxKind.ForInStatement:
|
||||
Debug.type<ForInStatement>(node);
|
||||
return factory.updateForInStatement(node,
|
||||
nodeVisitor(node.initializer, visitor, isForInitializer),
|
||||
nodeVisitor(node.expression, visitor, isExpression),
|
||||
nodeVisitor(node.statement, visitor, isStatement, factory.liftToBlock));
|
||||
visitIterationBody(node.statement, visitor, context));
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
Debug.type<ForOfStatement>(node);
|
||||
@@ -902,7 +920,7 @@ namespace ts {
|
||||
nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword),
|
||||
nodeVisitor(node.initializer, visitor, isForInitializer),
|
||||
nodeVisitor(node.expression, visitor, isExpression),
|
||||
nodeVisitor(node.statement, visitor, isStatement, factory.liftToBlock));
|
||||
visitIterationBody(node.statement, visitor, context));
|
||||
|
||||
case SyntaxKind.ContinueStatement:
|
||||
Debug.type<ContinueStatement>(node);
|
||||
|
||||
@@ -4782,6 +4782,10 @@ declare namespace ts {
|
||||
* environment and merging hoisted declarations upon completion.
|
||||
*/
|
||||
function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody;
|
||||
/**
|
||||
* Visits an iteration body, adding any block-scoped variables required by the transformation.
|
||||
*/
|
||||
function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement;
|
||||
/**
|
||||
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
|
||||
*
|
||||
|
||||
@@ -4782,6 +4782,10 @@ declare namespace ts {
|
||||
* environment and merging hoisted declarations upon completion.
|
||||
*/
|
||||
function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody;
|
||||
/**
|
||||
* Visits an iteration body, adding any block-scoped variables required by the transformation.
|
||||
*/
|
||||
function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement;
|
||||
/**
|
||||
* Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//// [classDeclarationLoop.ts]
|
||||
const arr = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
class C {
|
||||
prop = i;
|
||||
}
|
||||
arr.push(C);
|
||||
}
|
||||
|
||||
|
||||
//// [classDeclarationLoop.js]
|
||||
var arr = [];
|
||||
var _loop_1 = function (i) {
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
this.prop = i;
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
arr.push(C);
|
||||
};
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
_loop_1(i);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
=== tests/cases/conformance/classes/classDeclarations/classDeclarationLoop.ts ===
|
||||
const arr = [];
|
||||
>arr : Symbol(arr, Decl(classDeclarationLoop.ts, 0, 5))
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : Symbol(i, Decl(classDeclarationLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(classDeclarationLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(classDeclarationLoop.ts, 1, 8))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(classDeclarationLoop.ts, 1, 30))
|
||||
|
||||
prop = i;
|
||||
>prop : Symbol(C.prop, Decl(classDeclarationLoop.ts, 2, 13))
|
||||
>i : Symbol(i, Decl(classDeclarationLoop.ts, 1, 8))
|
||||
}
|
||||
arr.push(C);
|
||||
>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>arr : Symbol(arr, Decl(classDeclarationLoop.ts, 0, 5))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>C : Symbol(C, Decl(classDeclarationLoop.ts, 1, 30))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/conformance/classes/classDeclarations/classDeclarationLoop.ts ===
|
||||
const arr = [];
|
||||
>arr : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>++i : number
|
||||
>i : number
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
prop = i;
|
||||
>prop : number
|
||||
>i : number
|
||||
}
|
||||
arr.push(C);
|
||||
>arr.push(C) : number
|
||||
>arr.push : (...items: any[]) => number
|
||||
>arr : any[]
|
||||
>push : (...items: any[]) => number
|
||||
>C : typeof C
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [classExpressionLoop.ts]
|
||||
let arr = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
arr.push(class C {
|
||||
prop = i;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//// [classExpressionLoop.js]
|
||||
var arr = [];
|
||||
var _loop_1 = function (i) {
|
||||
arr.push(/** @class */ (function () {
|
||||
function C() {
|
||||
this.prop = i;
|
||||
}
|
||||
return C;
|
||||
}()));
|
||||
};
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
_loop_1(i);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
=== tests/cases/conformance/classes/classExpressions/classExpressionLoop.ts ===
|
||||
let arr = [];
|
||||
>arr : Symbol(arr, Decl(classExpressionLoop.ts, 0, 3))
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : Symbol(i, Decl(classExpressionLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(classExpressionLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(classExpressionLoop.ts, 1, 8))
|
||||
|
||||
arr.push(class C {
|
||||
>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>arr : Symbol(arr, Decl(classExpressionLoop.ts, 0, 3))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>C : Symbol(C, Decl(classExpressionLoop.ts, 2, 13))
|
||||
|
||||
prop = i;
|
||||
>prop : Symbol(C.prop, Decl(classExpressionLoop.ts, 2, 22))
|
||||
>i : Symbol(i, Decl(classExpressionLoop.ts, 1, 8))
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/conformance/classes/classExpressions/classExpressionLoop.ts ===
|
||||
let arr = [];
|
||||
>arr : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>++i : number
|
||||
>i : number
|
||||
|
||||
arr.push(class C {
|
||||
>arr.push(class C { prop = i; }) : number
|
||||
>arr.push : (...items: any[]) => number
|
||||
>arr : any[]
|
||||
>push : (...items: any[]) => number
|
||||
>class C { prop = i; } : typeof C
|
||||
>C : typeof C
|
||||
|
||||
prop = i;
|
||||
>prop : number
|
||||
>i : number
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ for (let i = 0; i < 3; i++) {
|
||||
arr.forEach(C => console.log(C.y()));
|
||||
|
||||
//// [classExpressionWithStaticProperties3.js]
|
||||
var _a;
|
||||
var arr = [];
|
||||
var _loop_1 = function (i) {
|
||||
var _a = void 0;
|
||||
arr.push((_a = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//// [computedPropertyNames52.js]
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
array.push(class C {
|
||||
[i] = () => C;
|
||||
static [i] = 100;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//// [computedPropertyNames52-emit.js]
|
||||
var _a;
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
let _b, _c;
|
||||
array.push((_c = class C {
|
||||
constructor() {
|
||||
this[_b] = () => C;
|
||||
}
|
||||
},
|
||||
_b = i,
|
||||
_a = i,
|
||||
_c[_a] = 100,
|
||||
_c));
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames52.js ===
|
||||
const array = [];
|
||||
>array : Symbol(array, Decl(computedPropertyNames52.js, 0, 5))
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
|
||||
array.push(class C {
|
||||
>array.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>array : Symbol(array, Decl(computedPropertyNames52.js, 0, 5))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>C : Symbol(C, Decl(computedPropertyNames52.js, 2, 15))
|
||||
|
||||
[i] = () => C;
|
||||
>[i] : Symbol(C[i], Decl(computedPropertyNames52.js, 2, 24))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>C : Symbol(C, Decl(computedPropertyNames52.js, 2, 15))
|
||||
|
||||
static [i] = 100;
|
||||
>[i] : Symbol(C[i], Decl(computedPropertyNames52.js, 3, 22))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames52.js ===
|
||||
const array = [];
|
||||
>array : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>++i : number
|
||||
>i : number
|
||||
|
||||
array.push(class C {
|
||||
>array.push(class C { [i] = () => C; static [i] = 100; }) : number
|
||||
>array.push : (...items: any[]) => number
|
||||
>array : any[]
|
||||
>push : (...items: any[]) => number
|
||||
>class C { [i] = () => C; static [i] = 100; } : typeof C
|
||||
>C : typeof C
|
||||
|
||||
[i] = () => C;
|
||||
>[i] : () => typeof C
|
||||
>i : number
|
||||
>() => C : () => typeof C
|
||||
>C : typeof C
|
||||
|
||||
static [i] = 100;
|
||||
>[i] : number
|
||||
>i : number
|
||||
>100 : 100
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//// [computedPropertyNames52.js]
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
array.push(class C {
|
||||
[i] = () => C;
|
||||
static [i] = 100;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//// [computedPropertyNames52-emit.js]
|
||||
var _a;
|
||||
var array = [];
|
||||
var _loop_1 = function (i) {
|
||||
var _b = void 0, _c = void 0;
|
||||
array.push((_c = /** @class */ (function () {
|
||||
function C() {
|
||||
this[_b] = function () { return C; };
|
||||
}
|
||||
return C;
|
||||
}()),
|
||||
_b = i,
|
||||
_a = i,
|
||||
_c[_a] = 100,
|
||||
_c));
|
||||
};
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
_loop_1(i);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames52.js ===
|
||||
const array = [];
|
||||
>array : Symbol(array, Decl(computedPropertyNames52.js, 0, 5))
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
|
||||
array.push(class C {
|
||||
>array.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>array : Symbol(array, Decl(computedPropertyNames52.js, 0, 5))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>C : Symbol(C, Decl(computedPropertyNames52.js, 2, 15))
|
||||
|
||||
[i] = () => C;
|
||||
>[i] : Symbol(C[i], Decl(computedPropertyNames52.js, 2, 24))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
>C : Symbol(C, Decl(computedPropertyNames52.js, 2, 15))
|
||||
|
||||
static [i] = 100;
|
||||
>[i] : Symbol(C[i], Decl(computedPropertyNames52.js, 3, 22))
|
||||
>i : Symbol(i, Decl(computedPropertyNames52.js, 1, 8))
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
=== tests/cases/conformance/es6/computedProperties/computedPropertyNames52.js ===
|
||||
const array = [];
|
||||
>array : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>++i : number
|
||||
>i : number
|
||||
|
||||
array.push(class C {
|
||||
>array.push(class C { [i] = () => C; static [i] = 100; }) : number
|
||||
>array.push : (...items: any[]) => number
|
||||
>array : any[]
|
||||
>push : (...items: any[]) => number
|
||||
>class C { [i] = () => C; static [i] = 100; } : typeof C
|
||||
>C : typeof C
|
||||
|
||||
[i] = () => C;
|
||||
>[i] : () => typeof C
|
||||
>i : number
|
||||
>() => C : () => typeof C
|
||||
>C : typeof C
|
||||
|
||||
static [i] = 100;
|
||||
>[i] : number
|
||||
>i : number
|
||||
>100 : 100
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [privateNameClassExpressionLoop.ts]
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
array.push(class C {
|
||||
#myField = "hello";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//// [privateNameClassExpressionLoop.js]
|
||||
var _a;
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
let _myField;
|
||||
array.push((_a = class C {
|
||||
constructor() {
|
||||
_myField.set(this, "hello");
|
||||
}
|
||||
},
|
||||
_myField = new WeakMap(),
|
||||
_a));
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
=== tests/cases/conformance/classes/members/privateNames/privateNameClassExpressionLoop.ts ===
|
||||
const array = [];
|
||||
>array : Symbol(array, Decl(privateNameClassExpressionLoop.ts, 0, 5))
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : Symbol(i, Decl(privateNameClassExpressionLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(privateNameClassExpressionLoop.ts, 1, 8))
|
||||
>i : Symbol(i, Decl(privateNameClassExpressionLoop.ts, 1, 8))
|
||||
|
||||
array.push(class C {
|
||||
>array.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>array : Symbol(array, Decl(privateNameClassExpressionLoop.ts, 0, 5))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>C : Symbol(C, Decl(privateNameClassExpressionLoop.ts, 2, 15))
|
||||
|
||||
#myField = "hello";
|
||||
>#myField : Symbol(C.#myField, Decl(privateNameClassExpressionLoop.ts, 2, 24))
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
=== tests/cases/conformance/classes/members/privateNames/privateNameClassExpressionLoop.ts ===
|
||||
const array = [];
|
||||
>array : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < 10 : boolean
|
||||
>i : number
|
||||
>10 : 10
|
||||
>++i : number
|
||||
>i : number
|
||||
|
||||
array.push(class C {
|
||||
>array.push(class C { #myField = "hello"; }) : number
|
||||
>array.push : (...items: any[]) => number
|
||||
>array : any[]
|
||||
>push : (...items: any[]) => number
|
||||
>class C { #myField = "hello"; } : typeof C
|
||||
>C : typeof C
|
||||
|
||||
#myField = "hello";
|
||||
>#myField : string
|
||||
>"hello" : "hello"
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
const arr = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
class C {
|
||||
prop = i;
|
||||
}
|
||||
arr.push(C);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
let arr = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
arr.push(class C {
|
||||
prop = i;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// @target: es2015
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
array.push(class C {
|
||||
#myField = "hello";
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// @filename: computedPropertyNames52.js
|
||||
// @out: computedPropertyNames52-emit.js
|
||||
// @allowJs: true
|
||||
// @target: es5, es2015
|
||||
const array = [];
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
array.push(class C {
|
||||
[i] = () => C;
|
||||
static [i] = 100;
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user