Merge pull request #7693 from Microsoft/transforms-block-scoped-bindings

Add support for captured block scoped bindings
This commit is contained in:
Vladimir Matveev
2016-03-29 09:39:20 -07:00
33 changed files with 1172 additions and 291 deletions
+34 -2
View File
@@ -482,6 +482,19 @@ namespace ts {
return node;
}
export function createSwitch(expression: Expression, caseBlock: CaseBlock, location?: TextRange): SwitchStatement {
const node = <SwitchStatement>createNode(SyntaxKind.SwitchStatement, location);
node.expression = parenthesizeExpressionForList(expression);
node.caseBlock = caseBlock;
return node;
}
export function createCaseBlock(clauses: CaseClause[], location?: TextRange): CaseBlock {
const node = <CaseBlock>createNode(SyntaxKind.CaseBlock, location);
node.clauses = createNodeArray(clauses);
return node;
}
export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange) {
const node = <ForStatement>createNode(SyntaxKind.ForStatement, location);
node.initializer = initializer;
@@ -687,6 +700,22 @@ namespace ts {
);
}
export function createBreak(label?: Identifier, location?: TextRange): BreakStatement {
const node = <BreakStatement>createNode(SyntaxKind.BreakStatement, location);
if (label) {
node.label = label;
}
return node;
}
export function createContinue(label?: Identifier, location?: TextRange): BreakStatement {
const node = <ContinueStatement>createNode(SyntaxKind.ContinueStatement, location);
if (label) {
node.label = label;
}
return node;
}
export function createFunctionApply(func: Expression, thisArg: Expression, argumentsExpression: Expression, location?: TextRange) {
return createCall(
createPropertyAccess(func, "apply"),
@@ -1349,8 +1378,11 @@ namespace ts {
return clone;
}
}
else if (getLeftmostExpression(expression).kind === SyntaxKind.ObjectLiteralExpression) {
return createParen(expression, /*location*/ expression);
else {
const leftmostExpressionKind = getLeftmostExpression(expression).kind;
if (leftmostExpressionKind === SyntaxKind.ObjectLiteralExpression || leftmostExpressionKind === SyntaxKind.FunctionExpression) {
return createParen(expression, /*location*/ expression);
}
}
return expression;
+10 -1
View File
@@ -1751,7 +1751,16 @@ const _super = (function (geti, seti) {
}
function emitCaseOrDefaultClauseStatements(parentNode: Node, statements: NodeArray<Statement>) {
if (statements.length === 1 && rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)) {
const emitAsSingleStatement =
statements.length === 1 &&
(
// treat synthesized nodes as located on the same line for emit purposes
nodeIsSynthesized(parentNode) ||
nodeIsSynthesized(statements[0]) ||
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)
);
if (emitAsSingleStatement) {
write(" ");
emit(statements[0]);
}
+1 -1
View File
@@ -165,7 +165,7 @@ namespace ts {
const pendingAssignments: Expression[] = [];
flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment);
flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
const expression = inlineExpressions(pendingAssignments);
aggregateTransformFlags(expression);
+777 -23
View File
@@ -10,6 +10,133 @@ namespace ts {
/** Enables substitutions for block-scoped bindings. */
BlockScopedBindings = 1 << 1,
}
/**
* If loop contains block scoped binding captured in some function then loop body is converted to a function.
* Lexical bindings declared in loop initializer will be passed into the loop body function as parameters,
* however if this binding is modified inside the body - this new value should be propagated back to the original binding.
* This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body.
* On every iteration this variable is initialized with value of corresponding binding.
* At every point where control flow leaves the loop either explicitly (break/continue) or implicitly (at the end of loop body)
* we copy the value inside the loop to the out parameter holder.
*
* for (let x;;) {
* let a = 1;
* let b = () => a;
* x++
* if (...) break;
* ...
* }
*
* will be converted to
*
* var out_x;
* var loop = function(x) {
* var a = 1;
* var b = function() { return a; }
* x++;
* if (...) return out_x = x, "break";
* ...
* out_x = x;
* }
* for (var x;;) {
* out_x = x;
* var state = loop(x);
* x = out_x;
* if (state === "break") break;
* }
*
* NOTE: values to out parameters are not copies if loop is abrupted with 'return' - in this case this will end the entire enclosing function
* so nobody can observe this new value.
*/
interface LoopOutParameter {
originalName: Identifier;
outParamName: Identifier;
}
const enum CopyDirection {
ToOriginal,
ToOutParameter
}
const enum Jump {
Break = 1 << 1,
Continue = 1 << 2,
Return = 1 << 3
}
interface ConvertedLoopState {
/*
* set of labels that occurred inside the converted loop
* used to determine if labeled jump can be emitted as is or it should be dispatched to calling code
*/
labels?: Map<string>;
/*
* collection of labeled jumps that transfer control outside the converted loop.
* maps store association 'label -> labelMarker' where
* - label - value of label as it appear in code
* - label marker - return value that should be interpreted by calling code as 'jump to <label>'
*/
labeledNonLocalBreaks?: Map<string>;
labeledNonLocalContinues?: Map<string>;
/*
* set of non-labeled jumps that transfer control outside the converted loop
* used to emit dispatching logic in the caller of converted loop
*/
nonLocalJumps?: Jump;
/*
* set of non-labeled jumps that should be interpreted as local
* i.e. if converted loop contains normal loop or switch statement then inside this loop break should be treated as local jump
*/
allowedNonLabeledJumps?: Jump;
/*
* alias for 'arguments' object from the calling code stack frame
* i.e.
* for (let x;;) <statement that captures x in closure and uses 'arguments'>
* should be converted to
* var loop = function(x) { <code where 'arguments' is replaced with 'arguments_1'> }
* var arguments_1 = arguments
* for (var x;;) loop(x);
* otherwise semantics of the code will be different since 'arguments' inside converted loop body
* will refer to function that holds converted loop.
* This value is set on demand.
*/
argumentsName?: Identifier;
/*
* alias for 'this' from the calling code stack frame in case if this was used inside the converted loop
*/
thisName?: Identifier;
/*
* set to true if node contains lexical 'this' so we can mark function that wraps convered loop body as 'CapturedThis' for subsequent substitution.
*/
containsLexicalThis?: boolean;
/*
* list of non-block scoped variable declarations that appear inside converted loop
* such variable declarations should be moved outside the loop body
* for (let x;;) {
* var y = 1;
* ...
* }
* should be converted to
* var loop = function(x) {
* y = 1;
* ...
* }
* var y;
* for (var x;;) loop(x);
*/
hoistedLocalVariables?: Identifier[];
/**
* List of loop out parameters - detailed descripion can be found in the comment to LoopOutParameter
*/
loopOutParameters?: LoopOutParameter[];
}
export function transformES6(context: TransformationContext) {
const {
@@ -35,6 +162,11 @@ namespace ts {
let enclosingBlockScopeContainerParent: Node;
let containingNonArrowFunction: FunctionLikeDeclaration;
/**
* Used to track if we are emitting body of the converted loop
*/
let convertedLoopState: ConvertedLoopState;
/**
* Keeps track of whether substitutions have been enabled for specific cases.
* They are persisted between each SourceFile transformation and should not
@@ -52,20 +184,37 @@ namespace ts {
function transformSourceFile(node: SourceFile) {
currentSourceFile = node;
enclosingBlockScopeContainer = node;
currentNode = node;
return visitEachChild(node, visitor, context);
}
function visitor(node: Node): VisitResult<Node> {
return saveStateAndInvoke(node, dispatcher);
}
function dispatcher(node: Node): VisitResult<Node> {
return convertedLoopState
? visitorForConvertedLoopWorker(node)
: visitorWorker(node);
}
function saveStateAndInvoke<T>(node: Node, f: (node: Node) => T): T {
const savedContainingNonArrowFunction = containingNonArrowFunction;
const savedCurrentParent = currentParent;
const savedCurrentNode = currentNode;
const savedEnclosingBlockScopeContainer = enclosingBlockScopeContainer;
const savedEnclosingBlockScopeContainerParent = enclosingBlockScopeContainerParent;
const savedConvertedLoopState = convertedLoopState;
if (nodeStartsNewLexicalEnvironment(node)) {
// don't treat content of nodes that start new lexical environment as part of converted loop copy
convertedLoopState = undefined;
}
onBeforeVisitNode(node);
const visited = f(node);
const visited = visitorWorker(node);
convertedLoopState = savedConvertedLoopState;
containingNonArrowFunction = savedContainingNonArrowFunction;
currentParent = savedCurrentParent;
currentNode = savedCurrentNode;
@@ -74,8 +223,14 @@ namespace ts {
return visited;
}
function shouldCheckNode(node: Node): boolean {
return (node.transformFlags & TransformFlags.ES6) !== 0 ||
node.kind === SyntaxKind.LabeledStatement ||
(isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node));
}
function visitorWorker(node: Node): VisitResult<Node> {
if (node.transformFlags & TransformFlags.ES6) {
if (shouldCheckNode(node)) {
return visitJavaScript(node);
}
else if (node.transformFlags & TransformFlags.ContainsES6) {
@@ -86,6 +241,52 @@ namespace ts {
}
}
function visitorForConvertedLoopWorker(node: Node): VisitResult<Node> {
const savedUseCapturedThis = useCapturedThis;
if (nodeStartsNewLexicalEnvironment(node)) {
useCapturedThis = false
}
let result: VisitResult<Node>;
if (shouldCheckNode(node)) {
result = visitJavaScript(node);
}
else {
result = visitNodesInConvertedLoop(node);
}
useCapturedThis = savedUseCapturedThis;
return result;
}
function visitNodesInConvertedLoop(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ReturnStatement:
return visitReturnStatement(<ReturnStatement>node);
case SyntaxKind.VariableStatement:
return visitVariableStatement(<VariableStatement>node);
case SyntaxKind.SwitchStatement:
return visitSwitchStatement(<SwitchStatement>node);
case SyntaxKind.BreakStatement:
case SyntaxKind.ContinueStatement:
return visitBreakOrContinueStatement(<BreakOrContinueStatement>node);
case SyntaxKind.ThisKeyword:
return visitThisKeyword(node);
case SyntaxKind.Identifier:
return visitIdentifier(<Identifier>node);
default:
return visitEachChild(node, visitor, context);
}
}
function visitJavaScript(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.ExportKeyword:
@@ -112,6 +313,9 @@ namespace ts {
case SyntaxKind.VariableDeclaration:
return visitVariableDeclaration(<VariableDeclaration>node);
case SyntaxKind.Identifier:
return visitIdentifier(<Identifier>node);
case SyntaxKind.VariableDeclarationList:
return visitVariableDeclarationList(<VariableDeclarationList>node);
@@ -216,6 +420,116 @@ namespace ts {
}
}
function visitSwitchStatement(node: SwitchStatement): SwitchStatement {
Debug.assert(convertedLoopState !== undefined);
const savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
// for switch statement allow only non-labeled break
convertedLoopState.allowedNonLabeledJumps |= Jump.Break;
const result = visitEachChild(node, visitor, context);
convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
return result;
}
function visitReturnStatement(node: ReturnStatement): Statement {
Debug.assert(convertedLoopState !== undefined);
convertedLoopState.nonLocalJumps |= Jump.Return;
return createReturn(
createObjectLiteral(
[
createPropertyAssignment(
createIdentifier("value"),
node.expression
? visitNode(node.expression, visitor, isExpression)
: createVoidZero()
)
]
)
);
}
function visitThisKeyword(node: Node): Node {
Debug.assert(convertedLoopState !== undefined);
if (useCapturedThis) {
// if useCapturedThis is true then 'this' keyword is contained inside an arrow function.
convertedLoopState.containsLexicalThis = true;
return node;
}
return convertedLoopState.thisName || (convertedLoopState.thisName = createUniqueName("this"));
}
function visitIdentifier(node: Identifier): Identifier {
if (!convertedLoopState) {
return node;
}
if (isGeneratedIdentifier(node)) {
return node;
}
if (node.text !== "arguments" && !resolver.isArgumentsLocalBinding(<Identifier>getOriginalNode(node))) {
return node;
}
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments"));
}
function visitBreakOrContinueStatement(node: BreakOrContinueStatement): Statement {
if (convertedLoopState) {
// check if we can emit break/continue as is
// it is possible if either
// - break/continue is labeled and label is located inside the converted loop
// - break/continue is non-labeled and located in non-converted loop/switch statement
const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue;
const canUseBreakOrContinue =
(node.label && convertedLoopState.labels && convertedLoopState.labels[node.label.text]) ||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
if (!canUseBreakOrContinue) {
let labelMarker: string;
if (!node.label) {
if (node.kind === SyntaxKind.BreakStatement) {
convertedLoopState.nonLocalJumps |= Jump.Break;
labelMarker = "break";
}
else {
convertedLoopState.nonLocalJumps |= Jump.Continue;
// note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
labelMarker = "continue";
}
}
else {
if (node.kind === SyntaxKind.BreakStatement) {
labelMarker = `break-${node.label.text}`;
setLabeledJump(convertedLoopState, /*isBreak*/ true, node.label.text, labelMarker);
}
else {
labelMarker = `continue-${node.label.text}`;
setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker);
}
}
let returnExpression: Expression = createLiteral(labelMarker);
if (convertedLoopState.loopOutParameters.length) {
const outParams = convertedLoopState.loopOutParameters;
let expr: Expression;
for (let i = 0; i < outParams.length; ++i) {
const copyExpr = copyOutParameter(outParams[i], CopyDirection.ToOutParameter);
if (i === 0) {
expr = copyExpr
}
else {
expr = createBinary(expr, SyntaxKind.CommaToken, copyExpr);
}
}
returnExpression = createBinary(expr, SyntaxKind.CommaToken, returnExpression);
}
return createReturn(returnExpression);
}
}
return visitEachChild(node, visitor, context);
}
/**
* Visits a ClassDeclaration and transforms it into a variable statement.
*
@@ -406,13 +720,22 @@ namespace ts {
addDefaultSuperCallIfNeeded(statements, constructor, hasExtendsClause, hasSynthesizedSuper);
if (constructor) {
addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, hasSynthesizedSuper ? 1 : 0));
const body = saveStateAndInvoke(constructor, hasSynthesizedSuper ? transformConstructorBodyWithSynthesizedSuper : transformConstructorBodyWithoutSynthesizedSuper);
addRange(statements, body);
}
addRange(statements, endLexicalEnvironment());
return createBlock(statements, /*location*/ constructor && constructor.body, /*multiLine*/ true);
}
function transformConstructorBodyWithSynthesizedSuper(node: ConstructorDeclaration) {
return visitNodes(node.body.statements, visitor, isStatement, 1);
}
function transformConstructorBodyWithoutSynthesizedSuper(node: ConstructorDeclaration) {
return visitNodes(node.body.statements, visitor, isStatement, 0);
}
/**
* Adds a synthesized call to `_super` if it is needed.
*
@@ -791,7 +1114,12 @@ namespace ts {
enableSubstitutionsForCapturedThis();
}
const savedUseCapturedThis = useCapturedThis;
useCapturedThis = true;
const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
useCapturedThis = savedUseCapturedThis;
setNodeEmitFlags(func, NodeEmitFlags.CapturesThis);
return func;
}
@@ -839,7 +1167,7 @@ namespace ts {
node.asteriskToken,
name,
visitNodes(node.parameters, visitor, isParameter),
transformFunctionBody(node),
saveStateAndInvoke(node, transformFunctionBody),
location,
/*original*/ node
);
@@ -977,6 +1305,34 @@ namespace ts {
return flattenDestructuringAssignment(context, node, needsDestructuringValue, hoistVariableDeclaration, visitor);
}
function visitVariableStatement(node: VariableStatement): Statement {
if (convertedLoopState && (getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) == 0) {
// we are inside a converted loop - hoist variable declarations
let assignments: Expression[];
for (const decl of node.declarationList.declarations) {
hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
if (decl.initializer) {
let assignment: Expression;
if (isBindingPattern(decl.name)) {
assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration,/*nameSubstitution*/ undefined, visitor);
}
else {
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, decl.initializer);
}
(assignments || (assignments = [])).push(assignment);
}
}
if (assignments) {
return createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc)));
}
else {
// none of declarations has initializer - the entire variable statement can be deleted
return undefined;
}
}
return visitEachChild(node, visitor, context);
}
/**
* Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
*
@@ -1103,29 +1459,43 @@ namespace ts {
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor);
}
function visitLabeledStatement(node: LabeledStatement) {
// TODO: Convert loop body for block scoped bindings.
return visitEachChild(node, visitor, context);
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
if (convertedLoopState) {
if (!convertedLoopState.labels) {
convertedLoopState.labels = {};
}
convertedLoopState.labels[node.label.text] = node.label.text;
}
let result: VisitResult<Statement>;
if (isIterationStatement(node.statement, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(<IterationStatement>node.statement)) {
result = visitNodes(createNodeArray([node.statement]), visitor, isStatement);
}
else {
result = visitEachChild(node, visitor, context);
}
if (convertedLoopState) {
convertedLoopState.labels[node.label.text] = undefined;
}
return result;
}
function visitDoStatement(node: DoStatement) {
// TODO: Convert loop body for block scoped bindings.
return visitEachChild(node, visitor, context);
return convertIterationStatementBodyIfNecessary(node);
}
function visitWhileStatement(node: WhileStatement) {
// TODO: Convert loop body for block scoped bindings.
return visitEachChild(node, visitor, context);
return convertIterationStatementBodyIfNecessary(node);
}
function visitForStatement(node: ForStatement) {
// TODO: Convert loop body for block scoped bindings.
return visitEachChild(node, visitor, context);
return convertIterationStatementBodyIfNecessary(node);
}
function visitForInStatement(node: ForInStatement) {
// TODO: Convert loop body for block scoped bindings.
return visitEachChild(node, visitor, context);
return convertIterationStatementBodyIfNecessary(node);
}
/**
@@ -1133,9 +1503,30 @@ namespace ts {
*
* @param node A ForOfStatement.
*/
function visitForOfStatement(node: ForOfStatement): Statement {
// TODO: Convert loop body for block scoped bindings.
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
const statementOrStatements = convertIterationStatementBodyIfNecessary(node);
const lastStatement = isArray(statementOrStatements) ? lastOrUndefined(statementOrStatements) : statementOrStatements;
const loop = lastStatement.kind === SyntaxKind.LabeledStatement
? (<LabeledStatement>lastStatement).statement
: lastStatement;
Debug.assert(loop.kind === SyntaxKind.ForOfStatement);
const statement =
lastStatement.kind === SyntaxKind.LabeledStatement
? createLabel((<LabeledStatement>lastStatement).label, convertForOfToFor(<ForOfStatement>loop))
: convertForOfToFor(<ForOfStatement>loop);
if (isArray(statementOrStatements)) {
statementOrStatements[statementOrStatements.length - 1] = statement;
return statementOrStatements;
}
else {
return statement;
}
}
function convertForOfToFor(node: ForOfStatement): ForStatement {
// The following ES6 code:
//
// for (let v of expr) { }
@@ -1157,7 +1548,7 @@ namespace ts {
// Note also that because an extra statement is needed to assign to the LHS,
// for-of bodies are always emitted as blocks.
const expression = visitNode(node.expression, visitor, isExpression);
const expression = node.expression;
const initializer = node.initializer;
const statements: Statement[] = [];
@@ -1233,12 +1624,11 @@ namespace ts {
}
}
const statement = visitNode(node.statement, visitor, isStatement);
if (isBlock(statement)) {
addRange(statements, statement.statements);
if (isBlock(node.statement)) {
addRange(statements, (<Block>node.statement).statements);
}
else {
statements.push(statement);
statements.push(node.statement);
}
return createFor(
@@ -1311,6 +1701,369 @@ namespace ts {
return createParen(inlineExpressions(expressions));
}
function shouldConvertIterationStatementBody(node: IterationStatement): boolean {
return (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
}
/**
* Records constituents of name for the given variable to be hoisted in the outer scope.
*/
function hoistVariableDeclarationDeclaredInConvertedLoop(state: ConvertedLoopState, node: VariableDeclaration): void {
if (!state.hoistedLocalVariables) {
state.hoistedLocalVariables = [];
}
visit(node.name);
function visit(node: Identifier | BindingPattern) {
if (node.kind === SyntaxKind.Identifier) {
state.hoistedLocalVariables.push((<Identifier>node));
}
else {
for (const element of (<BindingPattern>node).elements) {
visit(element.name);
}
}
}
}
function convertIterationStatementBodyIfNecessary(node: IterationStatement): VisitResult<Statement> {
if (!shouldConvertIterationStatementBody(node)) {
let saveAllowedNonLabeledJumps: Jump;
if (convertedLoopState) {
// we get here if we are trying to emit normal loop loop inside converted loop
// set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
convertedLoopState.allowedNonLabeledJumps = Jump.Break | Jump.Continue;
}
const result = visitEachChild(node, visitor, context);
if (convertedLoopState) {
convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
}
return result;
}
const functionName = createUniqueName("_loop");
let loopInitializer: VariableDeclarationList;
switch (node.kind) {
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
const initializer = (<ForStatement | ForInStatement | ForOfStatement>node).initializer;
if (initializer && initializer.kind === SyntaxKind.VariableDeclarationList) {
loopInitializer = <VariableDeclarationList>(<ForStatement | ForInStatement | ForOfStatement>node).initializer;
}
break;
}
// variables that will be passed to the loop as parameters
const loopParameters: ParameterDeclaration[] = [];
// variables declared in the loop initializer that will be changed inside the loop
const loopOutParameters: LoopOutParameter[] = [];
if (loopInitializer && (getCombinedNodeFlags(loopInitializer) & NodeFlags.BlockScoped)) {
for (const decl of loopInitializer.declarations) {
processLoopVariableDeclaration(decl, loopParameters, loopOutParameters);
}
}
const outerConvertedLoopState = convertedLoopState;
convertedLoopState = { loopOutParameters };
if (outerConvertedLoopState) {
// convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
// if outer converted loop has already accumulated some state - pass it through
if (outerConvertedLoopState.argumentsName) {
// outer loop has already used 'arguments' so we've already have some name to alias it
// use the same name in all nested loops
convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName;
}
if (outerConvertedLoopState.thisName) {
// outer loop has already used 'this' so we've already have some name to alias it
// use the same name in all nested loops
convertedLoopState.thisName = outerConvertedLoopState.thisName;
}
if (outerConvertedLoopState.hoistedLocalVariables) {
// we've already collected some non-block scoped variable declarations in enclosing loop
// use the same storage in nested loop
convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables;
}
}
let loopBody = visitEachChild(node.statement, visitor, context);
const currentState = convertedLoopState;
convertedLoopState = outerConvertedLoopState;
if (loopOutParameters.length) {
const statements = isBlock(loopBody) ? (<Block>loopBody).statements.slice() : [loopBody];
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true);
}
if (!isBlock(loopBody)) {
loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true);
}
const convertedLoopVariable =
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[
createVariableDeclaration(
functionName,
setNodeEmitFlags(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
loopParameters,
<Block>loopBody
),
currentState.containsLexicalThis
? NodeEmitFlags.CapturesThis
: 0
)
)
]
)
);
const statements: Statement[] = [convertedLoopVariable];
let extraVariableDeclarations: VariableDeclaration[];
// propagate state from the inner loop to the outer loop if necessary
if (currentState.argumentsName) {
// if alias for arguments is set
if (outerConvertedLoopState) {
// pass it to outer converted loop
outerConvertedLoopState.argumentsName = currentState.argumentsName;
}
else {
// this is top level converted loop and we need to create an alias for 'arguments' object
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
createVariableDeclaration(
currentState.argumentsName,
createIdentifier("arguments")
)
);
}
}
if (currentState.thisName) {
// if alias for this is set
if (outerConvertedLoopState) {
// pass it to outer converted loop
outerConvertedLoopState.thisName = currentState.thisName;
}
else {
// this is top level converted loop so we need to create an alias for 'this' here
// NOTE:
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
createVariableDeclaration(
currentState.thisName,
createIdentifier("this")
)
);
}
}
if (currentState.hoistedLocalVariables) {
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
if (outerConvertedLoopState) {
// pass them to outer converted loop
outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables;
}
else {
if (!extraVariableDeclarations) {
extraVariableDeclarations = [];
}
// hoist collected variable declarations
for (const name in currentState.hoistedLocalVariables) {
const identifier = currentState.hoistedLocalVariables[name];
extraVariableDeclarations.push(createVariableDeclaration(identifier));
}
}
}
// add extra variables to hold out parameters if necessary
if (loopOutParameters.length) {
if (!extraVariableDeclarations) {
extraVariableDeclarations = [];
}
for (const outParam of loopOutParameters) {
extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName));
}
}
// create variable statement to hold all introduced variable declarations
if (extraVariableDeclarations) {
statements.push(createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(extraVariableDeclarations)
));
}
let loop = <IterationStatement>getMutableClone(node);
// clean statement part
loop.statement = undefined;
// visit childnodes to transform initializer/condition/incrementor parts
loop = visitEachChild(loop, visitor, context);
// set loop statement
loop.statement = createBlock(
generateCallToConvertedLoop(functionName, loopParameters, currentState),
/*location*/ undefined,
/*multiline*/ true
);
statements.push(
currentParent.kind === SyntaxKind.LabeledStatement
? createLabel((<LabeledStatement>currentParent).label, loop)
: loop
);
return statements;
}
function copyOutParameter(outParam: LoopOutParameter, copyDirection: CopyDirection): BinaryExpression {
const source = copyDirection === CopyDirection.ToOriginal ? outParam.outParamName : outParam.originalName;
const target = copyDirection === CopyDirection.ToOriginal ? outParam.originalName : outParam.outParamName;
return createBinary(target, SyntaxKind.EqualsToken, source);
}
function copyOutParameters(outParams: LoopOutParameter[], copyDirection: CopyDirection, statements: Statement[]): void {
for (const outParam of outParams) {
statements.push(createStatement(copyOutParameter(outParam, copyDirection)));
}
}
function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, parameters: ParameterDeclaration[], state: ConvertedLoopState): Statement[] {
const outerConvertedLoopState = convertedLoopState;
const statements: Statement[] = [];
// loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
// simple loops are emitted as just 'loop()';
// NOTE: if loop uses only 'continue' it still will be emitted as simple loop
const isSimpleLoop =
!(state.nonLocalJumps & ~Jump.Continue) &&
!state.labeledNonLocalBreaks &&
!state.labeledNonLocalContinues;
const call = createCall(loopFunctionExpressionName, map(parameters, p => <Identifier>p.name));
if (isSimpleLoop) {
statements.push(createStatement(call));
copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements);
}
else {
const loopResultName = createUniqueName("state");
const stateVariable = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
[createVariableDeclaration(loopResultName, call)]
)
);
statements.push(stateVariable);
copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements);
if (state.nonLocalJumps & Jump.Return) {
let returnStatement: ReturnStatement;
if (outerConvertedLoopState) {
outerConvertedLoopState.nonLocalJumps |= Jump.Return;
returnStatement = createReturn(loopResultName);
}
else {
returnStatement = createReturn(createPropertyAccess(loopResultName, "value"));
}
statements.push(
createIf(
createBinary(
createTypeOf(loopResultName),
SyntaxKind.EqualsEqualsEqualsToken,
createLiteral("object")
),
returnStatement
)
);
}
if (state.nonLocalJumps & Jump.Break) {
statements.push(
createIf(
createBinary(
loopResultName,
SyntaxKind.EqualsEqualsEqualsToken,
createLiteral("break")
),
createBreak()
)
);
}
if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
const caseClauses: CaseClause[] = [];
processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
statements.push(
createSwitch(
loopResultName,
createCaseBlock(caseClauses)
)
);
}
}
return statements;
}
function setLabeledJump(state: ConvertedLoopState, isBreak: boolean, labelText: string, labelMarker: string): void {
if (isBreak) {
if (!state.labeledNonLocalBreaks) {
state.labeledNonLocalBreaks = {};
}
state.labeledNonLocalBreaks[labelText] = labelMarker;
}
else {
if (!state.labeledNonLocalContinues) {
state.labeledNonLocalContinues = {};
}
state.labeledNonLocalContinues[labelText] = labelMarker;
}
}
function processLabeledJumps(table: Map<string>, isBreak: boolean, loopResultName: Identifier, outerLoop: ConvertedLoopState, caseClauses: CaseClause[]): void {
if (!table) {
return;
}
for (const labelText in table) {
const labelMarker = table[labelText];
const statements: Statement[] = [];
// if there are no outer converted loop or outer label in question is located inside outer converted loop
// then emit labeled break\continue
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) {
const label = createIdentifier(labelText);
statements.push(isBreak ? createBreak(label) : createContinue(label));
}
else {
setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
statements.push(createReturn(loopResultName));
}
caseClauses.push(createCaseClause(createLiteral(labelMarker), statements));
}
}
function processLoopVariableDeclaration(decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[]) {
const name = decl.name;
if (isBindingPattern(name)) {
for (const element of name.elements) {
processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
}
}
else {
loopParameters.push(createParameter(name));
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
const outParamName = createUniqueName("out_" + name.text);
loopOutParameters.push({ originalName: name, outParamName });
}
}
}
/**
* Adds the members of an object literal to an array of expressions.
*
@@ -1756,6 +2509,7 @@ namespace ts {
return containingNonArrowFunction
&& isClassElement(containingNonArrowFunction)
&& !hasModifier(containingNonArrowFunction, ModifierFlags.Static)
&& currentParent.kind !== SyntaxKind.CallExpression
? createPropertyAccess(createIdentifier("_super"), "prototype")
: createIdentifier("_super");
}
+48 -10
View File
@@ -43,11 +43,16 @@ namespace ts {
let exportedLocalNames: Identifier[];
let exportedFunctionDeclarations: ExpressionStatement[];
let enclosingBlockScopedContainer: Node;
let currentParent: Node;
let currentNode: Node;
return transformSourceFile;
function transformSourceFile(node: SourceFile) {
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
currentNode = node;
// Perform the transformation.
const updated = transformSystemModuleWorker(node);
@@ -442,6 +447,28 @@ namespace ts {
}
function visitNestedNode(node: Node): VisitResult<Node> {
const savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
const savedCurrentParent = currentParent;
const savedCurrentNode = currentNode;
const currentGrandparent = currentParent;
currentParent = currentNode;
currentNode = node;
if (currentParent && isBlockScope(currentParent, currentGrandparent)) {
enclosingBlockScopedContainer = currentParent;
}
const result = visitNestedNodeWorker(node);
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
currentParent = savedCurrentParent;
currentNode = savedCurrentNode;
return result;
}
function visitNestedNodeWorker(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.VariableStatement:
return visitVariableStatement(<VariableStatement>node);
@@ -562,10 +589,17 @@ namespace ts {
* @param node The variable statement to visit.
*/
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
// hoist only non-block scoped declarations or block scoped declarations parented by source file
const shouldHoist =
((getCombinedNodeFlags(getOriginalNode(node.declarationList)) & NodeFlags.BlockScoped) == 0) ||
enclosingBlockScopedContainer.kind === SyntaxKind.SourceFile;
if (!shouldHoist) {
return node;
}
const isExported = hasModifier(node, ModifierFlags.Export);
const expressions: Expression[] = [];
for (const variable of node.declarationList.declarations) {
addNode(expressions, transformVariable(variable, isExported));
addNode(expressions, <Expression>transformVariable(variable, isExported));
}
if (expressions.length) {
@@ -581,7 +615,7 @@ namespace ts {
* @param node The VariableDeclaration to transform.
* @param isExported A value used to indicate whether the containing statement was exported.
*/
function transformVariable(node: VariableDeclaration, isExported: boolean): Expression {
function transformVariable(node: VariableDeclaration, isExported: boolean): VariableDeclaration | Expression {
// Hoist any bound names within the declaration.
hoistBindingElement(node, isExported);
@@ -685,6 +719,10 @@ namespace ts {
return statements;
}
function shouldHoistLoopInitializer(node: VariableDeclarationList | Expression) {
return isVariableDeclarationList(node) && (getCombinedNodeFlags(node) & NodeFlags.BlockScoped) === 0;
}
/**
* Visits the body of a ForStatement to hoist declarations.
*
@@ -692,10 +730,10 @@ namespace ts {
*/
function visitForStatement(node: ForStatement): ForStatement {
const initializer = node.initializer;
if (isVariableDeclarationList(initializer)) {
if (shouldHoistLoopInitializer(initializer)) {
const expressions: Expression[] = [];
for (const variable of initializer.declarations) {
addNode(expressions, transformVariable(variable, /*isExported*/ false));
for (const variable of (<VariableDeclarationList>initializer).declarations) {
addNode(expressions, <Expression>transformVariable(variable, /*isExported*/ false));
};
return createFor(
@@ -735,9 +773,9 @@ namespace ts {
*/
function visitForInStatement(node: ForInStatement): ForInStatement {
const initializer = node.initializer;
if (isVariableDeclarationList(initializer)) {
if (shouldHoistLoopInitializer(initializer)) {
const updated = getMutableClone(node);
updated.initializer = transformForBinding(initializer);
updated.initializer = transformForBinding(<VariableDeclarationList>initializer);
updated.statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock);
return updated;
}
@@ -753,9 +791,9 @@ namespace ts {
*/
function visitForOfStatement(node: ForOfStatement): ForOfStatement {
const initializer = node.initializer;
if (isVariableDeclarationList(initializer)) {
if (shouldHoistLoopInitializer(initializer)) {
const updated = getMutableClone(node);
updated.initializer = transformForBinding(initializer);
updated.initializer = transformForBinding(<VariableDeclarationList>initializer);
updated.statement = visitNode(node.statement, visitNestedNode, isStatement, /*optional*/ false, liftToBlock);
return updated;
}
@@ -1315,7 +1353,7 @@ namespace ts {
exportedFunctionDeclarations.push(createDeclarationExport(node));
}
function hoistBindingElement(node: VariableDeclaration | BindingElement, isExported: boolean) {
function hoistBindingElement(node: VariableDeclaration | BindingElement, isExported: boolean): void {
const name = node.name;
if (isIdentifier(name)) {
hoistVariableDeclaration(getSynthesizedClone(name));
+1 -1
View File
@@ -799,7 +799,7 @@ namespace ts {
return false;
}
export function isIterationStatement(node: Node, lookInLabeledStatements: boolean): boolean {
export function isIterationStatement(node: Node, lookInLabeledStatements: boolean): node is IterationStatement {
switch (node.kind) {
case SyntaxKind.ForStatement:
case SyntaxKind.ForInStatement:
+2 -2
View File
@@ -851,9 +851,9 @@ namespace ts {
*
* @param nodes The NodeArray.
*/
export function liftToBlock(nodes: Node[]): Block {
export function liftToBlock(nodes: Node[]): Statement {
Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block.");
return createBlock(<NodeArray<Statement>>nodes);
return <Statement>singleOrUndefined(nodes) || createBlock(<NodeArray<Statement>>nodes);
}
/**
@@ -10,7 +10,7 @@ declare function use(n: number): void;
//// [blockScopedBindingsReassignedInLoop1.js]
(function () {
'use strict';
var _loop_1 = function(i) {
var _loop_1 = function (i) {
(function () { return use(++i); })();
out_i_1 = i;
};
@@ -42,7 +42,7 @@ for (let x = 1, y = 2; x < y; ++x, --y) {
}
//// [blockScopedBindingsReassignedInLoop2.js]
var _loop_1 = function(x, y) {
var _loop_1 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_1 = x, out_y_1 = y, "break";
@@ -58,9 +58,10 @@ for (var x = 1, y = 2; x < y; ++x, --y) {
var state_1 = _loop_1(x, y);
x = out_x_1;
y = out_y_1;
if (state_1 === "break") break;
if (state_1 === "break")
break;
}
var _loop_2 = function(x, y) {
var _loop_2 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_2 = x, out_y_2 = y, "continue";
@@ -77,7 +78,7 @@ for (var x = 1, y = 2; x < y; ++x, --y) {
x = out_x_2;
y = out_y_2;
}
var _loop_3 = function(x, y) {
var _loop_3 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_3 = x, out_y_3 = y, "break-loop";
@@ -90,14 +91,14 @@ var _loop_3 = function(x, y) {
};
var out_x_3, out_y_3;
loop: for (var x = 1, y = 2; x < y; ++x, --y) {
var state_3 = _loop_3(x, y);
var state_2 = _loop_3(x, y);
x = out_x_3;
y = out_y_3;
switch(state_3) {
switch (state_2) {
case "break-loop": break loop;
}
}
var _loop_4 = function(x, y) {
var _loop_4 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_4 = x, out_y_4 = y, "continue-loop";
@@ -110,10 +111,10 @@ var _loop_4 = function(x, y) {
};
var out_x_4, out_y_4;
loop: for (var x = 1, y = 2; x < y; ++x, --y) {
var state_4 = _loop_4(x, y);
var state_3 = _loop_4(x, y);
x = out_x_4;
y = out_y_4;
switch(state_4) {
switch (state_3) {
case "continue-loop": continue loop;
}
}
@@ -93,28 +93,29 @@ for (let x = 1, y = 2; x < y; ++x, --y) {
//// [blockScopedBindingsReassignedInLoop3.js]
var _loop_1 = function(x, y) {
var _loop_1 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_1 = x, out_y_1 = y, "break";
}
else {
var _loop_2 = function(a_1) {
var _loop_2 = function (a_1) {
var f = function () { return a_1; };
if (a_1) {
a_1 = x;
return out_a_1_1 = a_1, "break";
return out_a_1 = a_1, "break";
}
else {
y++;
}
out_a_1_1 = a_1;
out_a_1 = a_1;
};
var out_a_1_1;
var out_a_1;
for (var a_1 = 1; a_1 < 5; --a_1) {
var state_1 = _loop_2(a_1);
a_1 = out_a_1_1;
if (state_1 === "break") break;
a_1 = out_a_1;
if (state_1 === "break")
break;
}
y = 5;
}
@@ -126,29 +127,30 @@ for (var x = 1, y = 2; x < y; ++x, --y) {
var state_2 = _loop_1(x, y);
x = out_x_1;
y = out_y_1;
if (state_2 === "break") break;
if (state_2 === "break")
break;
}
var _loop_3 = function(x, y) {
var _loop_3 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_2 = x, out_y_2 = y, "continue";
}
else {
var _loop_4 = function(a_2) {
var _loop_4 = function (a_2) {
var f = function () { return a_2; };
if (a_2) {
a_2 = x;
return out_a_2_1 = a_2, "continue";
return out_a_2 = a_2, "continue";
}
else {
y++;
}
out_a_2_1 = a_2;
out_a_2 = a_2;
};
var out_a_2_1;
var out_a_2;
for (var a_2 = 1; a_2 < 5; --a_2) {
_loop_4(a_2);
a_2 = out_a_2_1;
a_2 = out_a_2;
}
y = 5;
}
@@ -161,31 +163,31 @@ for (var x = 1, y = 2; x < y; ++x, --y) {
x = out_x_2;
y = out_y_2;
}
var _loop_5 = function(x, y) {
var _loop_5 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_3 = x, out_y_3 = y, "break-loop2";
}
else {
var _loop_6 = function(a_3) {
var _loop_6 = function (a_3) {
var f = function () { return a_3; };
if (a_3) {
a_3 = x;
return out_a_3_1 = a_3, "break-loop1";
return out_a_3 = a_3, "break-loop1";
}
else {
y++;
return out_a_3_1 = a_3, "break-loop2";
return out_a_3 = a_3, "break-loop2";
}
out_a_3_1 = a_3;
out_a_3 = a_3;
};
var out_a_3_1;
var out_a_3;
loop1: for (var a_3 = 1; a_3 < 5; --a_3) {
var state_5 = _loop_6(a_3);
a_3 = out_a_3_1;
switch(state_5) {
var state_3 = _loop_6(a_3);
a_3 = out_a_3;
switch (state_3) {
case "break-loop1": break loop1;
case "break-loop2": return state_5;
case "break-loop2": return state_3;
}
}
y = 5;
@@ -195,38 +197,38 @@ var _loop_5 = function(x, y) {
};
var out_x_3, out_y_3;
loop2: for (var x = 1, y = 2; x < y; ++x, --y) {
var state_6 = _loop_5(x, y);
var state_4 = _loop_5(x, y);
x = out_x_3;
y = out_y_3;
switch(state_6) {
switch (state_4) {
case "break-loop2": break loop2;
}
}
var _loop_7 = function(x, y) {
var _loop_7 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return out_x_4 = x, out_y_4 = y, "continue-loop2";
}
else {
var _loop_8 = function(a_4) {
var _loop_8 = function (a_4) {
var f = function () { return a_4; };
if (a_4) {
a_4 = x;
return out_a_4_1 = a_4, "continue-loop1";
return out_a_4 = a_4, "continue-loop1";
}
else {
y++;
return out_a_4_1 = a_4, "continue-loop2";
return out_a_4 = a_4, "continue-loop2";
}
out_a_4_1 = a_4;
out_a_4 = a_4;
};
var out_a_4_1;
var out_a_4;
loop1: for (var a_4 = 1; a_4 < 5; --a_4) {
var state_7 = _loop_8(a_4);
a_4 = out_a_4_1;
switch(state_7) {
var state_5 = _loop_8(a_4);
a_4 = out_a_4;
switch (state_5) {
case "continue-loop1": continue loop1;
case "continue-loop2": return state_7;
case "continue-loop2": return state_5;
}
}
y = 5;
@@ -236,10 +238,10 @@ var _loop_7 = function(x, y) {
};
var out_x_4, out_y_4;
loop2: for (var x = 1, y = 2; x < y; ++x, --y) {
var state_8 = _loop_7(x, y);
var state_6 = _loop_7(x, y);
x = out_x_4;
y = out_y_4;
switch(state_8) {
switch (state_6) {
case "continue-loop2": continue loop2;
}
}
@@ -13,7 +13,7 @@ function f1() {
//// [blockScopedBindingsReassignedInLoop4.js]
function f1() {
var _loop_1 = function(x, y) {
var _loop_1 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1) {
return { value: 1 };
@@ -29,6 +29,7 @@ function f1() {
var state_1 = _loop_1(x, y);
x = out_x_1;
y = out_y_1;
if (typeof state_1 === "object") return state_1.value;
if (typeof state_1 === "object")
return state_1.value;
}
}
@@ -9,7 +9,7 @@ for (let x = 1, y = 2; x < y; ++x, --y) {
//// [blockScopedBindingsReassignedInLoop5.js]
var _loop_1 = function(x, y) {
var _loop_1 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1)
return out_x_1 = x, out_y_1 = y, "break";
@@ -23,5 +23,6 @@ for (var x = 1, y = 2; x < y; ++x, --y) {
var state_1 = _loop_1(x, y);
x = out_x_1;
y = out_y_1;
if (state_1 === "break") break;
if (state_1 === "break")
break;
}
@@ -31,7 +31,7 @@ function f2() {
//// [blockScopedBindingsReassignedInLoop6.js]
function f1() {
var _loop_1 = function(x, y) {
var _loop_1 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1)
return out_x_1 = x, out_y_1 = y, "break";
@@ -47,12 +47,14 @@ function f1() {
var state_1 = _loop_1(x, y);
x = out_x_1;
y = out_y_1;
if (typeof state_1 === "object") return state_1.value;
if (state_1 === "break") break;
if (typeof state_1 === "object")
return state_1.value;
if (state_1 === "break")
break;
}
}
function f2() {
var _loop_2 = function(x, y) {
var _loop_2 = function (x, y) {
var a = function () { return x++ + y++; };
if (x == 1)
return out_x_2 = x, out_y_2 = y, "break";
@@ -68,7 +70,9 @@ function f2() {
var state_2 = _loop_2(x, y);
x = out_x_2;
y = out_y_2;
if (typeof state_2 === "object") return state_2.value;
if (state_2 === "break") break;
if (typeof state_2 === "object")
return state_2.value;
if (state_2 === "break")
break;
}
}
@@ -50,7 +50,7 @@ var A = (function () {
function A() {
}
A.prototype.foo = function () {
var _loop_1 = function(x) {
var _loop_1 = function (x) {
var f = function () { return x; };
this_1.bar(f());
};
@@ -63,9 +63,9 @@ var A = (function () {
A.prototype.bar = function (a) {
};
A.prototype.baz = function () {
var _loop_2 = function(x) {
var _loop_2 = function (x) {
var a = function () { return x; };
var _loop_3 = function(y) {
var _loop_3 = function (y) {
var b = function () { return y; };
this_2.bar(b());
};
@@ -76,16 +76,16 @@ var A = (function () {
this_2.bar(a());
};
var this_2 = this;
for (var _b = 0, _c = [1]; _b < _c.length; _b++) {
var x = _c[_b];
for (var _i = 0, _a = [1]; _i < _a.length; _i++) {
var x = _a[_i];
_loop_2(x);
}
};
A.prototype.baz2 = function () {
var _loop_4 = function(x) {
var _loop_4 = function (x) {
var a = function () { return x; };
this_3.bar(a());
var _loop_5 = function(y) {
var _loop_5 = function (y) {
var b = function () { return y; };
this_3.bar(b());
};
@@ -95,8 +95,8 @@ var A = (function () {
}
};
var this_3 = this;
for (var _b = 0, _c = [1]; _b < _c.length; _b++) {
var x = _c[_b];
for (var _i = 0, _a = [1]; _i < _a.length; _i++) {
var x = _a[_i];
_loop_4(x);
}
};
@@ -108,7 +108,7 @@ var B = (function () {
B.prototype.foo = function () {
var _this = this;
var a = function () {
var _loop_6 = function(x) {
var _loop_6 = function (x) {
var f = function () { return x; };
_this.bar(f());
};
@@ -14,7 +14,7 @@ function foo() {
}
//// [capturedLetConstInLoop11.js]
var _loop_1 = function() {
var _loop_1 = function () {
var x = 1;
(function () { return x; });
};
@@ -22,14 +22,15 @@ for (;;) {
_loop_1();
}
function foo() {
var _loop_2 = function() {
var _loop_2 = function () {
var a = 0;
switch (a) {
case 0: return { value: function () { return a; } };
}
};
for (;;) {
var state_2 = _loop_2();
if (typeof state_2 === "object") return state_2.value;
var state_1 = _loop_2();
if (typeof state_1 === "object")
return state_1.value;
}
}
@@ -16,7 +16,7 @@ function foo() {
//// [capturedLetConstInLoop11_ES6.js]
for (;;) {
let x = 1;
(() => x);
() => x;
}
function foo() {
for (;;) {
@@ -18,8 +18,11 @@
//// [capturedLetConstInLoop12.js]
(function () {
"use strict";
var _loop_1 = function(i) {
(function () { return (_a = [i + 1], i = _a[0], _a); var _a; })();
var _loop_1 = function (i) {
(function () {
return _a = [i + 1], i = _a[0], _a;
var _a;
})();
out_i_1 = i;
};
var out_i_1;
@@ -30,8 +33,11 @@
})();
(function () {
"use strict";
var _loop_2 = function(i) {
(function () { return (_a = { a: i + 1 }, i = _a.a, _a); var _a; })();
var _loop_2 = function (i) {
(function () {
return (_a = { a: i + 1 }, i = _a.a, _a);
var _a;
})();
out_i_2 = i;
};
var out_i_2;
@@ -179,7 +179,7 @@ function foo8_c(x) {
//// [capturedLetConstInLoop2.js]
// ========let
function foo0(x) {
var _loop_1 = function(x_1) {
var _loop_1 = function (x_1) {
var a = arguments_1.length;
(function () { return x_1 + a; });
(function () { return x_1 + a; });
@@ -191,7 +191,7 @@ function foo0(x) {
}
}
function foo0_1(x) {
var _loop_2 = function(x_2) {
var _loop_2 = function (x_2) {
var a = arguments_2.length;
(function () { return x_2 + a; });
(function () { return x_2 + a; });
@@ -202,7 +202,7 @@ function foo0_1(x) {
}
}
function foo1(x) {
var _loop_3 = function(x_3) {
var _loop_3 = function (x_3) {
var a = arguments_3.length;
(function () { return x_3 + a; });
(function () { return x_3 + a; });
@@ -213,7 +213,7 @@ function foo1(x) {
}
}
function foo2(x) {
var _loop_4 = function() {
var _loop_4 = function () {
var a = arguments_4.length;
(function () { return x + a; });
(function () { return x + a; });
@@ -224,7 +224,7 @@ function foo2(x) {
}
}
function foo3(x) {
var _loop_5 = function() {
var _loop_5 = function () {
var x_4;
var a = arguments_5.length;
(function () { return x_4 + a; });
@@ -236,7 +236,7 @@ function foo3(x) {
} while (1 === 1);
}
function foo4(x) {
var _loop_6 = function(y) {
var _loop_6 = function (y) {
var a = arguments_6.length;
var x_5 = 1;
(function () { return x_5 + a; });
@@ -248,7 +248,7 @@ function foo4(x) {
}
}
function foo5(x) {
var _loop_7 = function(x_6, y) {
var _loop_7 = function (x_6, y) {
var a = arguments_7.length;
(function () { return x_6 + y + a; });
(function () { return x_6 + y + a; });
@@ -259,7 +259,7 @@ function foo5(x) {
}
}
function foo6(x) {
var _loop_8 = function() {
var _loop_8 = function () {
var x_7, y;
var a = arguments_8.length;
(function () { return x_7 + y + a; });
@@ -271,7 +271,7 @@ function foo6(x) {
}
}
function foo7(x) {
var _loop_9 = function() {
var _loop_9 = function () {
var x_8, y;
var a = arguments_9.length;
(function () { return x_8 + y + a; });
@@ -283,7 +283,7 @@ function foo7(x) {
} while (1 === 1);
}
function foo8(x) {
var _loop_10 = function(y) {
var _loop_10 = function (y) {
var x_9 = 1;
var a = arguments_10.length;
(function () { return x_9 + y + a; });
@@ -296,7 +296,7 @@ function foo8(x) {
}
///=======const
function foo0_c(x) {
var _loop_11 = function(x_10) {
var _loop_11 = function (x_10) {
var a = arguments_11.length;
(function () { return x_10 + a; });
(function () { return x_10 + a; });
@@ -308,7 +308,7 @@ function foo0_c(x) {
}
}
function foo0_1_c(x) {
var _loop_12 = function(x_11) {
var _loop_12 = function (x_11) {
var a = arguments_12.length;
(function () { return x_11 + a; });
(function () { return x_11 + a; });
@@ -319,7 +319,7 @@ function foo0_1_c(x) {
}
}
function foo1_c(x) {
var _loop_13 = function(x_12) {
var _loop_13 = function (x_12) {
var a = arguments_13.length;
(function () { return x_12 + a; });
(function () { return x_12 + a; });
@@ -330,7 +330,7 @@ function foo1_c(x) {
}
}
function foo2_c(x) {
var _loop_14 = function() {
var _loop_14 = function () {
var a = arguments_14.length;
(function () { return x + a; });
(function () { return x + a; });
@@ -341,7 +341,7 @@ function foo2_c(x) {
}
}
function foo3_c(x) {
var _loop_15 = function() {
var _loop_15 = function () {
var x_13 = 1;
var a = arguments_15.length;
(function () { return x_13 + a; });
@@ -353,7 +353,7 @@ function foo3_c(x) {
} while (1 === 1);
}
function foo4_c(x) {
var _loop_16 = function(y) {
var _loop_16 = function (y) {
var a = arguments_16.length;
var x_14 = 1;
(function () { return x_14 + a; });
@@ -365,7 +365,7 @@ function foo4_c(x) {
}
}
function foo5_c(x) {
var _loop_17 = function(x_15, y) {
var _loop_17 = function (x_15, y) {
var a = arguments_17.length;
(function () { return x_15 + y + a; });
(function () { return x_15 + y + a; });
@@ -376,7 +376,7 @@ function foo5_c(x) {
}
}
function foo6_c(x) {
var _loop_18 = function() {
var _loop_18 = function () {
var x_16 = 1, y = 1;
var a = arguments_18.length;
(function () { return x_16 + y + a; });
@@ -388,7 +388,7 @@ function foo6_c(x) {
}
}
function foo7_c(x) {
var _loop_19 = function() {
var _loop_19 = function () {
var x_17 = 1, y = 1;
var a = arguments_19.length;
(function () { return x_17 + y + a; });
@@ -400,7 +400,7 @@ function foo7_c(x) {
} while (1 === 1);
}
function foo8_c(x) {
var _loop_20 = function(y) {
var _loop_20 = function (y) {
var x_18 = 1;
var a = arguments_20.length;
(function () { return x_18 + y + a; });
@@ -219,7 +219,7 @@ function foo8_c(x) {
//// [capturedLetConstInLoop3.js]
function foo0(x) {
var _loop_1 = function(x_1) {
var _loop_1 = function (x_1) {
v = x_1;
(function () { return x_1 + v; });
(function () { return x_1 + v; });
@@ -232,7 +232,7 @@ function foo0(x) {
use(v);
}
function foo0_1(x) {
var _loop_2 = function(x_2) {
var _loop_2 = function (x_2) {
v = x_2;
(function () { return x_2 + v; });
(function () { return x_2 + v; });
@@ -244,7 +244,7 @@ function foo0_1(x) {
use(v);
}
function foo1(x) {
var _loop_3 = function(x_3) {
var _loop_3 = function (x_3) {
v = x_3;
(function () { return x_3 + v; });
(function () { return x_3 + v; });
@@ -256,7 +256,7 @@ function foo1(x) {
use(v);
}
function foo2(x) {
var _loop_4 = function() {
var _loop_4 = function () {
var x_4 = 1;
v = x_4;
(function () { return x_4 + v; });
@@ -269,7 +269,7 @@ function foo2(x) {
use(v);
}
function foo3(x) {
var _loop_5 = function() {
var _loop_5 = function () {
var x_5;
(function () { return x_5 + v; });
(function () { return x_5 + v; });
@@ -281,7 +281,7 @@ function foo3(x) {
use(v);
}
function foo4(x) {
var _loop_6 = function(y) {
var _loop_6 = function (y) {
v = y;
var x_6 = 1;
(function () { return x_6 + v; });
@@ -294,7 +294,7 @@ function foo4(x) {
use(v);
}
function foo5(x) {
var _loop_7 = function(x_7, y) {
var _loop_7 = function (x_7, y) {
v = x_7;
(function () { return x_7 + y + v; });
(function () { return x_7 + y + v; });
@@ -306,7 +306,7 @@ function foo5(x) {
use(v);
}
function foo6(x) {
var _loop_8 = function() {
var _loop_8 = function () {
var x_8, y;
v = x_8;
(function () { return x_8 + y + v; });
@@ -319,7 +319,7 @@ function foo6(x) {
use(v);
}
function foo7(x) {
var _loop_9 = function() {
var _loop_9 = function () {
var x_9, y;
v = x_9;
(function () { return x_9 + y + v; });
@@ -332,7 +332,7 @@ function foo7(x) {
use(v);
}
function foo8(x) {
var _loop_10 = function(y) {
var _loop_10 = function (y) {
var x_10 = 1;
v = x_10;
(function () { return x_10 + y + v; });
@@ -346,7 +346,7 @@ function foo8(x) {
}
//===const
function foo0_c(x) {
var _loop_11 = function(x_11) {
var _loop_11 = function (x_11) {
v = x_11;
(function () { return x_11 + v; });
(function () { return x_11 + v; });
@@ -359,7 +359,7 @@ function foo0_c(x) {
use(v);
}
function foo0_1_c(x) {
var _loop_12 = function(x_12) {
var _loop_12 = function (x_12) {
v = x_12;
(function () { return x_12 + v; });
(function () { return x_12 + v; });
@@ -371,7 +371,7 @@ function foo0_1_c(x) {
use(v);
}
function foo1_c(x) {
var _loop_13 = function(x_13) {
var _loop_13 = function (x_13) {
v = x_13;
(function () { return x_13 + v; });
(function () { return x_13 + v; });
@@ -383,7 +383,7 @@ function foo1_c(x) {
use(v);
}
function foo2_c(x) {
var _loop_14 = function() {
var _loop_14 = function () {
var x_14 = 1;
v = x_14;
(function () { return x_14 + v; });
@@ -396,7 +396,7 @@ function foo2_c(x) {
use(v);
}
function foo3_c(x) {
var _loop_15 = function() {
var _loop_15 = function () {
var x_15 = 1;
(function () { return x_15 + v; });
(function () { return x_15 + v; });
@@ -408,7 +408,7 @@ function foo3_c(x) {
use(v);
}
function foo4_c(x) {
var _loop_16 = function(y) {
var _loop_16 = function (y) {
v = y;
var x_16 = 1;
(function () { return x_16 + v; });
@@ -421,7 +421,7 @@ function foo4_c(x) {
use(v);
}
function foo5_c(x) {
var _loop_17 = function(x_17, y) {
var _loop_17 = function (x_17, y) {
v = x_17;
(function () { return x_17 + y + v; });
(function () { return x_17 + y + v; });
@@ -433,7 +433,7 @@ function foo5_c(x) {
use(v);
}
function foo6_c(x) {
var _loop_18 = function() {
var _loop_18 = function () {
var x_18 = 1, y = 1;
v = x_18;
(function () { return x_18 + y + v; });
@@ -446,7 +446,7 @@ function foo6_c(x) {
use(v);
}
function foo7_c(x) {
var _loop_19 = function() {
var _loop_19 = function () {
var x_19 = 1, y = 1;
v = x_19;
(function () { return x_19 + y + v; });
@@ -459,7 +459,7 @@ function foo7_c(x) {
use(v);
}
function foo8_c(x) {
var _loop_20 = function(y) {
var _loop_20 = function (y) {
var x_20 = 1;
v = x_20;
(function () { return x_20 + y + v; });
@@ -144,24 +144,24 @@ for (const y = 0; y < 1;) {
//// [capturedLetConstInLoop4.js]
System.register([], function(exports_1, context_1) {
System.register([], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var v0, v00, v1, v2, v3, v4, v5, v6, v7, v8, v0_c, v00_c, v1_c, v2_c, v3_c, v4_c, v5_c, v6_c, v7_c, v8_c;
//======let
function exportedFoo() {
return v0 + v00 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;
}
exports_1("exportedFoo", exportedFoo);
//======const
function exportedFoo2() {
return v0_c + v00_c + v1_c + v2_c + v3_c + v4_c + v5_c + v6_c + v7_c + v8_c;
}
var v0, v00, v1, v2, v3, v4, v5, v6, v7, v8, v0_c, v00_c, v1_c, v2_c, v3_c, v4_c, v5_c, v6_c, v7_c, v8_c;
exports_1("exportedFoo", exportedFoo);
exports_1("exportedFoo2", exportedFoo2);
return {
setters:[],
execute: function() {
var _loop_1 = function(x) {
setters: [],
execute: function () {
var _loop_1 = function (x) {
v0 = x;
(function () { return x + v0; });
(function () { return x; });
@@ -170,7 +170,7 @@ System.register([], function(exports_1, context_1) {
var x = _a[_i];
_loop_1(x);
}
var _loop_2 = function(x) {
var _loop_2 = function (x) {
v00 = x;
(function () { return x + v00; });
(function () { return x; });
@@ -178,7 +178,7 @@ System.register([], function(exports_1, context_1) {
for (var x in []) {
_loop_2(x);
}
var _loop_3 = function(x) {
var _loop_3 = function (x) {
v1 = x;
(function () { return x + v1; });
(function () { return x; });
@@ -186,7 +186,7 @@ System.register([], function(exports_1, context_1) {
for (var x = 0; x < 1; ++x) {
_loop_3(x);
}
var _loop_4 = function() {
var _loop_4 = function () {
var x;
v2 = x;
(function () { return x + v2; });
@@ -195,7 +195,7 @@ System.register([], function(exports_1, context_1) {
while (1 === 1) {
_loop_4();
}
var _loop_5 = function() {
var _loop_5 = function () {
var x;
v3 = x;
(function () { return x + v3; });
@@ -204,7 +204,7 @@ System.register([], function(exports_1, context_1) {
do {
_loop_5();
} while (1 === 1);
var _loop_6 = function(y) {
var _loop_6 = function (y) {
var x = 1;
v4 = x;
(function () { return x + v4; });
@@ -213,7 +213,7 @@ System.register([], function(exports_1, context_1) {
for (var y = 0; y < 1; ++y) {
_loop_6(y);
}
var _loop_7 = function(x, y) {
var _loop_7 = function (x, y) {
v5 = x;
(function () { return x + y + v5; });
(function () { return x + y; });
@@ -221,7 +221,7 @@ System.register([], function(exports_1, context_1) {
for (var x = 0, y = 1; x < 1; ++x) {
_loop_7(x, y);
}
var _loop_8 = function() {
var _loop_8 = function () {
var x, y;
v6 = x;
(function () { return x + y + v6; });
@@ -230,7 +230,7 @@ System.register([], function(exports_1, context_1) {
while (1 === 1) {
_loop_8();
}
var _loop_9 = function() {
var _loop_9 = function () {
var x, y;
v7 = x;
(function () { return x + y + v7; });
@@ -239,7 +239,7 @@ System.register([], function(exports_1, context_1) {
do {
_loop_9();
} while (1 === 1);
var _loop_10 = function(y) {
var _loop_10 = function (y) {
var x = 1;
v8 = x;
(function () { return x + y + v8; });
@@ -248,7 +248,7 @@ System.register([], function(exports_1, context_1) {
for (var y = 0; y < 1; ++y) {
_loop_10(y);
}
var _loop_11 = function(x) {
var _loop_11 = function (x) {
v0_c = x;
(function () { return x + v0_c; });
(function () { return x; });
@@ -257,7 +257,7 @@ System.register([], function(exports_1, context_1) {
var x = _c[_b];
_loop_11(x);
}
var _loop_12 = function(x) {
var _loop_12 = function (x) {
v00_c = x;
(function () { return x + v00; });
(function () { return x; });
@@ -265,7 +265,7 @@ System.register([], function(exports_1, context_1) {
for (var x in []) {
_loop_12(x);
}
var _loop_13 = function(x) {
var _loop_13 = function (x) {
v1_c = x;
(function () { return x + v1_c; });
(function () { return x; });
@@ -273,7 +273,7 @@ System.register([], function(exports_1, context_1) {
for (var x = 0; x < 1;) {
_loop_13(x);
}
var _loop_14 = function() {
var _loop_14 = function () {
var x = 1;
v2_c = x;
(function () { return x + v2_c; });
@@ -282,7 +282,7 @@ System.register([], function(exports_1, context_1) {
while (1 === 1) {
_loop_14();
}
var _loop_15 = function() {
var _loop_15 = function () {
var x = 1;
v3_c = x;
(function () { return x + v3_c; });
@@ -291,7 +291,7 @@ System.register([], function(exports_1, context_1) {
do {
_loop_15();
} while (1 === 1);
var _loop_16 = function(y) {
var _loop_16 = function (y) {
var x = 1;
v4_c = x;
(function () { return x + v4_c; });
@@ -300,7 +300,7 @@ System.register([], function(exports_1, context_1) {
for (var y = 0; y < 1;) {
_loop_16(y);
}
var _loop_17 = function(x, y) {
var _loop_17 = function (x, y) {
v5_c = x;
(function () { return x + y + v5_c; });
(function () { return x + y; });
@@ -308,7 +308,7 @@ System.register([], function(exports_1, context_1) {
for (var x = 0, y = 1; x < 1;) {
_loop_17(x, y);
}
var _loop_18 = function() {
var _loop_18 = function () {
var x = 1, y = 1;
v6_c = x;
(function () { return x + y + v6_c; });
@@ -317,7 +317,7 @@ System.register([], function(exports_1, context_1) {
while (1 === 1) {
_loop_18();
}
var _loop_19 = function() {
var _loop_19 = function () {
var x = 1, y = 1;
v7_c = x;
(function () { return x + y + v7_c; });
@@ -326,7 +326,7 @@ System.register([], function(exports_1, context_1) {
do {
_loop_19();
} while (1 === 1);
var _loop_20 = function(y) {
var _loop_20 = function (y) {
var x = 1;
v8_c = x;
(function () { return x + y + v8_c; });
@@ -336,5 +336,5 @@ System.register([], function(exports_1, context_1) {
_loop_20(y);
}
}
}
};
});
@@ -282,7 +282,7 @@ function foo8_c(x) {
//// [capturedLetConstInLoop5.js]
//====let
function foo0(x) {
var _loop_1 = function(x_1) {
var _loop_1 = function (x_1) {
v = x_1;
(function () { return x_1 + v; });
(function () { return x_1 + v; });
@@ -294,12 +294,13 @@ function foo0(x) {
for (var _i = 0, _a = []; _i < _a.length; _i++) {
var x_1 = _a[_i];
var state_1 = _loop_1(x_1);
if (typeof state_1 === "object") return state_1.value;
if (typeof state_1 === "object")
return state_1.value;
}
use(v);
}
function foo00(x) {
var _loop_2 = function(x_2) {
var _loop_2 = function (x_2) {
v = x_2;
(function () { return x_2 + v; });
(function () { return x_2 + v; });
@@ -310,12 +311,13 @@ function foo00(x) {
var v;
for (var x_2 in []) {
var state_2 = _loop_2(x_2);
if (typeof state_2 === "object") return state_2.value;
if (typeof state_2 === "object")
return state_2.value;
}
use(v);
}
function foo1(x) {
var _loop_3 = function(x_3) {
var _loop_3 = function (x_3) {
v = x_3;
(function () { return x_3 + v; });
(function () { return x_3 + v; });
@@ -326,12 +328,13 @@ function foo1(x) {
var v;
for (var x_3 = 0; x_3 < 1; ++x_3) {
var state_3 = _loop_3(x_3);
if (typeof state_3 === "object") return state_3.value;
if (typeof state_3 === "object")
return state_3.value;
}
use(v);
}
function foo2(x) {
var _loop_4 = function() {
var _loop_4 = function () {
var x_4 = 1;
v = x_4;
(function () { return x_4 + v; });
@@ -343,12 +346,13 @@ function foo2(x) {
var v;
while (1 === 1) {
var state_4 = _loop_4();
if (typeof state_4 === "object") return state_4.value;
if (typeof state_4 === "object")
return state_4.value;
}
use(v);
}
function foo3(x) {
var _loop_5 = function() {
var _loop_5 = function () {
var x_5;
(function () { return x_5 + v; });
(function () { return x_5 + v; });
@@ -359,12 +363,13 @@ function foo3(x) {
var v;
do {
var state_5 = _loop_5();
if (typeof state_5 === "object") return state_5.value;
if (typeof state_5 === "object")
return state_5.value;
} while (1 === 1);
use(v);
}
function foo4(x) {
var _loop_6 = function(y) {
var _loop_6 = function (y) {
v = y;
var x_6 = 1;
(function () { return x_6 + v; });
@@ -376,12 +381,13 @@ function foo4(x) {
var v;
for (var y = 0; y < 1; ++y) {
var state_6 = _loop_6(y);
if (typeof state_6 === "object") return state_6.value;
if (typeof state_6 === "object")
return state_6.value;
}
use(v);
}
function foo5(x) {
var _loop_7 = function(x_7, y) {
var _loop_7 = function (x_7, y) {
v = x_7;
(function () { return x_7 + y + v; });
(function () { return x_7 + y + v; });
@@ -392,12 +398,13 @@ function foo5(x) {
var v;
for (var x_7 = 0, y = 1; x_7 < 1; ++x_7) {
var state_7 = _loop_7(x_7, y);
if (typeof state_7 === "object") return state_7.value;
if (typeof state_7 === "object")
return state_7.value;
}
use(v);
}
function foo6(x) {
var _loop_8 = function() {
var _loop_8 = function () {
var x_8, y;
v = x_8;
(function () { return x_8 + y + v; });
@@ -409,13 +416,14 @@ function foo6(x) {
var v;
while (1 === 1) {
var state_8 = _loop_8();
if (typeof state_8 === "object") return state_8.value;
if (typeof state_8 === "object")
return state_8.value;
}
;
use(v);
}
function foo7(x) {
var _loop_9 = function() {
var _loop_9 = function () {
var x_9, y;
v = x_9;
(function () { return x_9 + y + v; });
@@ -427,12 +435,13 @@ function foo7(x) {
var v;
do {
var state_9 = _loop_9();
if (typeof state_9 === "object") return state_9.value;
if (typeof state_9 === "object")
return state_9.value;
} while (1 === 1);
use(v);
}
function foo8(x) {
var _loop_10 = function(y) {
var _loop_10 = function (y) {
var x_10 = 1;
v = x_10;
(function () { return x_10 + y + v; });
@@ -444,13 +453,14 @@ function foo8(x) {
var v;
for (var y = 0; y < 1; ++y) {
var state_10 = _loop_10(y);
if (typeof state_10 === "object") return state_10.value;
if (typeof state_10 === "object")
return state_10.value;
}
use(v);
}
//====const
function foo0_c(x) {
var _loop_11 = function(x_11) {
var _loop_11 = function (x_11) {
v = x_11;
(function () { return x_11 + v; });
(function () { return x_11 + v; });
@@ -462,12 +472,13 @@ function foo0_c(x) {
for (var _i = 0, _a = []; _i < _a.length; _i++) {
var x_11 = _a[_i];
var state_11 = _loop_11(x_11);
if (typeof state_11 === "object") return state_11.value;
if (typeof state_11 === "object")
return state_11.value;
}
use(v);
}
function foo00_c(x) {
var _loop_12 = function(x_12) {
var _loop_12 = function (x_12) {
v = x_12;
(function () { return x_12 + v; });
(function () { return x_12 + v; });
@@ -478,12 +489,13 @@ function foo00_c(x) {
var v;
for (var x_12 in []) {
var state_12 = _loop_12(x_12);
if (typeof state_12 === "object") return state_12.value;
if (typeof state_12 === "object")
return state_12.value;
}
use(v);
}
function foo1_c(x) {
var _loop_13 = function(x_13) {
var _loop_13 = function (x_13) {
v = x_13;
(function () { return x_13 + v; });
(function () { return x_13 + v; });
@@ -494,12 +506,13 @@ function foo1_c(x) {
var v;
for (var x_13 = 0; x_13 < 1;) {
var state_13 = _loop_13(x_13);
if (typeof state_13 === "object") return state_13.value;
if (typeof state_13 === "object")
return state_13.value;
}
use(v);
}
function foo2_c(x) {
var _loop_14 = function() {
var _loop_14 = function () {
var x_14 = 1;
v = x_14;
(function () { return x_14 + v; });
@@ -511,12 +524,13 @@ function foo2_c(x) {
var v;
while (1 === 1) {
var state_14 = _loop_14();
if (typeof state_14 === "object") return state_14.value;
if (typeof state_14 === "object")
return state_14.value;
}
use(v);
}
function foo3_c(x) {
var _loop_15 = function() {
var _loop_15 = function () {
var x_15 = 1;
(function () { return x_15 + v; });
(function () { return x_15 + v; });
@@ -527,12 +541,13 @@ function foo3_c(x) {
var v;
do {
var state_15 = _loop_15();
if (typeof state_15 === "object") return state_15.value;
if (typeof state_15 === "object")
return state_15.value;
} while (1 === 1);
use(v);
}
function foo4_c(x) {
var _loop_16 = function(y) {
var _loop_16 = function (y) {
v = y;
var x_16 = 1;
(function () { return x_16 + v; });
@@ -544,12 +559,13 @@ function foo4_c(x) {
var v;
for (var y = 0; y < 1;) {
var state_16 = _loop_16(y);
if (typeof state_16 === "object") return state_16.value;
if (typeof state_16 === "object")
return state_16.value;
}
use(v);
}
function foo5_c(x) {
var _loop_17 = function(x_17, y) {
var _loop_17 = function (x_17, y) {
v = x_17;
(function () { return x_17 + y + v; });
(function () { return x_17 + y + v; });
@@ -560,12 +576,13 @@ function foo5_c(x) {
var v;
for (var x_17 = 0, y = 1; x_17 < 1;) {
var state_17 = _loop_17(x_17, y);
if (typeof state_17 === "object") return state_17.value;
if (typeof state_17 === "object")
return state_17.value;
}
use(v);
}
function foo6_c(x) {
var _loop_18 = function() {
var _loop_18 = function () {
var x_18 = 1, y = 1;
v = x_18;
(function () { return x_18 + y + v; });
@@ -577,12 +594,13 @@ function foo6_c(x) {
var v;
while (1 === 1) {
var state_18 = _loop_18();
if (typeof state_18 === "object") return state_18.value;
if (typeof state_18 === "object")
return state_18.value;
}
use(v);
}
function foo7_c(x) {
var _loop_19 = function() {
var _loop_19 = function () {
var x_19 = 1, y = 1;
v = x_19;
(function () { return x_19 + y + v; });
@@ -594,12 +612,13 @@ function foo7_c(x) {
var v;
do {
var state_19 = _loop_19();
if (typeof state_19 === "object") return state_19.value;
if (typeof state_19 === "object")
return state_19.value;
} while (1 === 1);
use(v);
}
function foo8_c(x) {
var _loop_20 = function(y) {
var _loop_20 = function (y) {
var x_20 = 1;
v = x_20;
(function () { return x_20 + y + v; });
@@ -611,7 +630,8 @@ function foo8_c(x) {
var v;
for (var y = 0; y < 1;) {
var state_20 = _loop_20(y);
if (typeof state_20 === "object") return state_20.value;
if (typeof state_20 === "object")
return state_20.value;
}
use(v);
}
@@ -129,8 +129,8 @@ function foo_c() {
//// [capturedLetConstInLoop8.js]
function foo() {
l0: for (var z = 0; z < 1; ++z) {
var _loop_1 = function(x) {
var _loop_2 = function(y) {
var _loop_1 = function (x) {
var _loop_2 = function (y) {
(function () { return x + y; });
(function () { return x + y; });
if (y == 1) {
@@ -163,9 +163,11 @@ function foo() {
};
ll1: for (var y = 0; y < 1; ++y) {
var state_1 = _loop_2(y);
if (typeof state_1 === "object") return state_1;
if (state_1 === "break") break;
switch(state_1) {
if (typeof state_1 === "object")
return state_1;
if (state_1 === "break")
break;
switch (state_1) {
case "break-l1": return state_1;
case "break-ll1": break ll1;
case "continue-l0": return state_1;
@@ -197,9 +199,11 @@ function foo() {
};
l1: for (var x = 0; x < 1; ++x) {
var state_2 = _loop_1(x);
if (typeof state_2 === "object") return state_2.value;
if (state_2 === "break") break;
switch(state_2) {
if (typeof state_2 === "object")
return state_2.value;
if (state_2 === "break")
break;
switch (state_2) {
case "break-l1": break l1;
case "continue-l0": continue l0;
case "continue-l1": continue l1;
@@ -209,8 +213,8 @@ function foo() {
}
function foo_c() {
l0: for (var z = 0; z < 1;) {
var _loop_3 = function(x) {
var _loop_4 = function(y) {
var _loop_3 = function (x) {
var _loop_4 = function (y) {
(function () { return x + y; });
(function () { return x + y; });
if (y == 1) {
@@ -243,9 +247,11 @@ function foo_c() {
};
ll1: for (var y = 0; y < 1;) {
var state_3 = _loop_4(y);
if (typeof state_3 === "object") return state_3;
if (state_3 === "break") break;
switch(state_3) {
if (typeof state_3 === "object")
return state_3;
if (state_3 === "break")
break;
switch (state_3) {
case "break-l1": return state_3;
case "break-ll1": break ll1;
case "continue-l0": return state_3;
@@ -277,9 +283,11 @@ function foo_c() {
};
l1: for (var x = 0; x < 1;) {
var state_4 = _loop_3(x);
if (typeof state_4 === "object") return state_4.value;
if (state_4 === "break") break;
switch(state_4) {
if (typeof state_4 === "object")
return state_4.value;
if (state_4 === "break")
break;
switch (state_4) {
case "break-l1": break l1;
case "continue-l0": continue l0;
case "continue-l1": continue l1;
@@ -139,7 +139,7 @@ function foo3 () {
}
//// [capturedLetConstInLoop9.js]
var _loop_1 = function(x) {
var _loop_1 = function (x) {
var x_1;
(function () { return x_1; });
{
@@ -157,7 +157,7 @@ var _loop_1 = function(x) {
(function () { return x_4; });
break;
}
var _loop_2 = function() {
var _loop_2 = function () {
var x_5;
(function () { return x_5; });
};
@@ -177,7 +177,7 @@ for (var x = 0; x < 1; ++x) {
_loop_1(x);
}
function foo() {
var _loop_3 = function(a) {
var _loop_3 = function (a) {
if (a === 1) {
return "break";
}
@@ -198,8 +198,8 @@ function foo() {
}
return { value: 50 };
}
var _loop_4 = function(b) {
_c = [{ x1: 1, y: arguments_1.length }][0], x1 = _c.x1, z1 = _c.y;
var _loop_4 = function (b) {
_a = [{ x1: 1, y: arguments_1.length }][0], x1 = _a.x1, z1 = _a.y;
if (b === 1) {
return "break";
}
@@ -209,25 +209,28 @@ function foo() {
(function () { return b; });
return { value: 100 };
};
for (var _d = 0, _e = []; _d < _e.length; _d++) {
var b = _e[_d];
var state_3 = _loop_4(b);
if (typeof state_3 === "object") return state_3;
if (state_3 === "break") break;
switch(state_3) {
case "break-l0": return state_3;
for (var _c = 0, _d = []; _c < _d.length; _c++) {
var b = _d[_c];
var state_1 = _loop_4(b);
if (typeof state_1 === "object")
return state_1;
if (state_1 === "break")
break;
switch (state_1) {
case "break-l0": return state_1;
}
}
(function () { return a; });
};
var arguments_1 = arguments;
var x, z, x1, z1;
l0: for (var _f = 0, _g = []; _f < _g.length; _f++) {
var a = _g[_f];
var state_4 = _loop_3(a);
if (typeof state_4 === "object") return state_4.value;
if (state_4 === "break") break;
switch(state_4) {
var arguments_1 = arguments, x, z, x1, z1;
l0: for (var _i = 0, _a = []; _i < _a.length; _i++) {
var a = _a[_i];
var state_2 = _loop_3(a);
if (typeof state_2 === "object")
return state_2.value;
if (state_2 === "break")
break;
switch (state_2) {
case "break-l0": break l0;
}
}
@@ -235,6 +238,7 @@ function foo() {
use(z);
use(x1);
use(z1);
var _b, _a;
}
function foo2() {
for (var _i = 0, _a = []; _i < _a.length; _i++) {
@@ -272,7 +276,7 @@ var C = (function () {
}
C.prototype.foo = function () {
var _this = this;
var _loop_5 = function(i) {
var _loop_5 = function (i) {
var f = function () { return _this.N * i; };
};
for (var i = 0; i < 100; i++) {
@@ -283,7 +287,7 @@ var C = (function () {
}());
function foo3() {
var x = arguments.length;
var _loop_6 = function(y) {
var _loop_6 = function (y) {
var z = arguments_2.length;
(function () { return y + z + arguments.length; });
};
@@ -196,10 +196,10 @@ function foo() {
if (b === 2) {
break l0;
}
(() => b);
() => b;
return 100;
}
(() => a);
() => a;
}
use(x);
use(z);
@@ -13,7 +13,7 @@ for (; false;) {
//// [nestedBlockScopedBindings14.js]
var x;
var _loop_1 = function() {
var _loop_1 = function () {
var x_1;
(function () { return x_1; });
};
@@ -32,7 +32,7 @@ for (; false;) {
}
//// [nestedBlockScopedBindings15.js]
var _loop_1 = function() {
var _loop_1 = function () {
{
var x_1;
(function () { return x_1; });
@@ -47,7 +47,7 @@ for (; false;) {
y = 1;
}
}
var _loop_2 = function() {
var _loop_2 = function () {
switch (1) {
case 1:
var z0_1;
@@ -37,7 +37,7 @@ for (; false;) {
//// [nestedBlockScopedBindings16.js]
var x;
var _loop_1 = function() {
var _loop_1 = function () {
{
var x_1;
(function () { return x_1; });
@@ -54,7 +54,7 @@ for (; false;) {
}
}
var z0;
var _loop_2 = function() {
var _loop_2 = function () {
switch (1) {
case 1:
var z0_1;
@@ -71,7 +71,7 @@ function a5() {
//// [nestedBlockScopedBindings3.js]
function a0() {
{
var _loop_1 = function(x) {
var _loop_1 = function (x) {
(function () { return x; });
};
for (var x = 0; x < 1;) {
@@ -79,7 +79,7 @@ function a0() {
}
}
{
var _loop_2 = function(x) {
var _loop_2 = function (x) {
(function () { return x; });
};
for (var x = void 0;;) {
@@ -88,13 +88,13 @@ function a0() {
}
}
function a1() {
var _loop_3 = function(x) {
var _loop_3 = function (x) {
(function () { return x; });
};
for (var x = void 0; x < 1;) {
_loop_3(x);
}
var _loop_4 = function(x) {
var _loop_4 = function (x) {
(function () { return x; });
};
for (var x = void 0;;) {
@@ -120,7 +120,7 @@ function a3() {
}
}
function a4() {
var _loop_5 = function(x) {
var _loop_5 = function (x) {
x = x + 1;
(function () { return x; });
out_x_1 = x;
@@ -137,7 +137,7 @@ function a4() {
}
}
function a5() {
var _loop_6 = function(x) {
var _loop_6 = function (x) {
x = x + 1;
(function () { return x; });
out_x_2 = x;
@@ -50,7 +50,7 @@ function a0() {
}
}
function a1() {
var _loop_1 = function(x) {
var _loop_1 = function (x) {
x = x + 1;
(function () { return x; });
out_x_1 = x;
@@ -68,7 +68,7 @@ function a2() {
for (var x = void 0; x < 1;) {
x = x + 1;
}
var _loop_2 = function(x) {
var _loop_2 = function (x) {
x = x + 2;
(function () { return x; });
out_x_2 = x;
@@ -80,7 +80,7 @@ function a2() {
}
}
function a3() {
var _loop_3 = function(x) {
var _loop_3 = function (x) {
x = x + 1;
(function () { return x; });
out_x_3 = x;
@@ -90,7 +90,7 @@ function a3() {
_loop_3(x);
x = out_x_3;
}
var _loop_4 = function(x) {
var _loop_4 = function (x) {
x = x + 2;
(function () { return x; });
out_x_4 = x;
@@ -90,7 +90,7 @@ function a0() {
}
}
function a1() {
var _loop_1 = function(x) {
var _loop_1 = function (x) {
x = x + 1;
(function () { return x; });
};
@@ -105,7 +105,7 @@ function a2() {
for (var x in []) {
x = x + 1;
}
var _loop_2 = function(x) {
var _loop_2 = function (x) {
x = x + 2;
(function () { return x; });
out_x_1 = x;
@@ -117,14 +117,14 @@ function a2() {
}
}
function a3() {
var _loop_3 = function(x) {
var _loop_3 = function (x) {
x = x + 1;
(function () { return x; });
};
for (var x in []) {
_loop_3(x);
}
var _loop_4 = function(x) {
var _loop_4 = function (x) {
x = x + 2;
(function () { return x; });
out_x_2 = x;
@@ -160,7 +160,7 @@ function a5() {
for (var x in []) {
x = x + 1;
}
var _loop_5 = function(x) {
var _loop_5 = function (x) {
x = x + 2;
(function () { return x; });
out_x_3 = x;
@@ -99,7 +99,7 @@ function a0() {
}
}
function a1() {
var _loop_1 = function(x) {
var _loop_1 = function (x) {
x = x + 1;
(function () { return x; });
};
@@ -116,7 +116,7 @@ function a2() {
var x = _a[_i];
x = x + 1;
}
var _loop_2 = function(x) {
var _loop_2 = function (x) {
x = x + 2;
(function () { return x; });
out_x_1 = x;
@@ -128,7 +128,7 @@ function a2() {
}
}
function a3() {
var _loop_3 = function(x) {
var _loop_3 = function (x) {
x = x + 1;
(function () { return x; });
};
@@ -136,7 +136,7 @@ function a3() {
var x = _a[_i];
_loop_3(x);
}
var _loop_4 = function(x) {
var _loop_4 = function (x) {
x = x + 2;
(function () { return x; });
out_x_2 = x;
@@ -148,7 +148,7 @@ function a3() {
}
}
function a4() {
var _loop_5 = function(x) {
var _loop_5 = function (x) {
x = x + 1;
(function () { return x; });
};
@@ -186,7 +186,7 @@ function a6() {
}
}
function a7() {
var _loop_6 = function(x) {
var _loop_6 = function (x) {
x = x + 1;
(function () { return x; });
};
@@ -8,7 +8,7 @@ for (let y; false;) {
}
//// [nestedBlockScopedBindings7.js]
var _loop_1 = function(x) {
var _loop_1 = function (x) {
(function () { return x; });
};
for (var x = void 0; false;) {
@@ -11,7 +11,7 @@ for (let y; false; ) {
//// [nestedBlockScopedBindings8.js]
var x;
var _loop_1 = function(x_1) {
var _loop_1 = function (x_1) {
(function () { return x_1; });
};
for (var x_1; false;) {