Skip to content

Commit 36257ec

Browse files
committed
Fix issue with destructuring in for..of
1 parent 3989d23 commit 36257ec

1 file changed

Lines changed: 62 additions & 46 deletions

File tree

  • src/compiler/transformers

src/compiler/transformers/es6.ts

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ namespace ts {
207207

208208
const savedConvertedLoopState = convertedLoopState;
209209
if (nodeStartsNewLexicalEnvironment(node)) {
210-
// don't treat content of nodes that start new lexical environment as part of converted loop copy
210+
// don't treat content of nodes that start new lexical environment as part of converted loop copy
211211
convertedLoopState = undefined;
212212
}
213213

@@ -249,7 +249,7 @@ namespace ts {
249249
}
250250

251251
let result: VisitResult<Node>;
252-
252+
253253
if (shouldCheckNode(node)) {
254254
result = visitJavaScript(node);
255255
}
@@ -422,7 +422,7 @@ namespace ts {
422422

423423
function visitSwitchStatement(node: SwitchStatement): SwitchStatement {
424424
Debug.assert(convertedLoopState !== undefined);
425-
425+
426426
const savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
427427
// for switch statement allow only non-labeled break
428428
convertedLoopState.allowedNonLabeledJumps |= Jump.Break;
@@ -432,7 +432,7 @@ namespace ts {
432432
convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
433433
return result;
434434
}
435-
435+
436436
function visitReturnStatement(node: ReturnStatement): Statement {
437437
Debug.assert(convertedLoopState !== undefined);
438438

@@ -455,7 +455,7 @@ namespace ts {
455455
Debug.assert(convertedLoopState !== undefined);
456456

457457
if (useCapturedThis) {
458-
// if useCapturedThis is true then 'this' keyword is contained inside an arrow function.
458+
// if useCapturedThis is true then 'this' keyword is contained inside an arrow function.
459459
convertedLoopState.containsLexicalThis = true;
460460
return node;
461461
}
@@ -1116,9 +1116,9 @@ namespace ts {
11161116

11171117
const savedUseCapturedThis = useCapturedThis;
11181118
useCapturedThis = true;
1119-
1119+
11201120
const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
1121-
1121+
11221122
useCapturedThis = savedUseCapturedThis;
11231123
setNodeEmitFlags(func, NodeEmitFlags.CapturesThis);
11241124
return func;
@@ -1504,29 +1504,31 @@ namespace ts {
15041504
* @param node A ForOfStatement.
15051505
*/
15061506
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
1507-
const statementOrStatements = convertIterationStatementBodyIfNecessary(node);
1508-
const lastStatement = isArray(statementOrStatements) ? lastOrUndefined(statementOrStatements) : statementOrStatements;
1509-
const loop = lastStatement.kind === SyntaxKind.LabeledStatement
1510-
? (<LabeledStatement>lastStatement).statement
1511-
: lastStatement;
1512-
1513-
Debug.assert(loop.kind === SyntaxKind.ForOfStatement);
1514-
1515-
const statement =
1516-
lastStatement.kind === SyntaxKind.LabeledStatement
1517-
? createLabel((<LabeledStatement>lastStatement).label, convertForOfToFor(<ForOfStatement>loop))
1518-
: convertForOfToFor(<ForOfStatement>loop);
1519-
1520-
if (isArray(statementOrStatements)) {
1521-
statementOrStatements[statementOrStatements.length - 1] = statement;
1522-
return statementOrStatements;
1523-
}
1524-
else {
1525-
return statement;
1526-
}
1507+
return convertIterationStatementBodyIfNecessary(node, convertForOfToFor);
1508+
// debugger;
1509+
// const statementOrStatements = convertIterationStatementBodyIfNecessary(node);
1510+
// const lastStatement = isArray(statementOrStatements) ? lastOrUndefined(statementOrStatements) : statementOrStatements;
1511+
// const loop = lastStatement.kind === SyntaxKind.LabeledStatement
1512+
// ? (<LabeledStatement>lastStatement).statement
1513+
// : lastStatement;
1514+
1515+
// Debug.assert(loop.kind === SyntaxKind.ForOfStatement);
1516+
1517+
// const statement =
1518+
// lastStatement.kind === SyntaxKind.LabeledStatement
1519+
// ? createLabel((<LabeledStatement>lastStatement).label, convertForOfToFor(<ForOfStatement>loop))
1520+
// : convertForOfToFor(<ForOfStatement>loop);
1521+
1522+
// if (isArray(statementOrStatements)) {
1523+
// statementOrStatements[statementOrStatements.length - 1] = statement;
1524+
// return statementOrStatements;
1525+
// }
1526+
// else {
1527+
// return statement;
1528+
// }
15271529
}
15281530

1529-
function convertForOfToFor(node: ForOfStatement): ForStatement {
1531+
function convertForOfToFor(node: ForOfStatement, convertedLoopBodyStatements: Statement[]): ForStatement {
15301532
// The following ES6 code:
15311533
//
15321534
// for (let v of expr) { }
@@ -1624,11 +1626,17 @@ namespace ts {
16241626
}
16251627
}
16261628

1627-
if (isBlock(node.statement)) {
1628-
addRange(statements, (<Block>node.statement).statements);
1629+
if (convertedLoopBodyStatements) {
1630+
addRange(statements, convertedLoopBodyStatements);
16291631
}
16301632
else {
1631-
statements.push(node.statement);
1633+
const statement = visitNode(node.statement, visitor, isStatement);
1634+
if (isBlock(statement)) {
1635+
addRange(statements, (<Block>statement).statements);
1636+
}
1637+
else {
1638+
statements.push(statement);
1639+
}
16321640
}
16331641

16341642
return createFor(
@@ -1727,7 +1735,7 @@ namespace ts {
17271735
}
17281736
}
17291737

1730-
function convertIterationStatementBodyIfNecessary(node: IterationStatement): VisitResult<Statement> {
1738+
function convertIterationStatementBodyIfNecessary(node: IterationStatement, convert?: (node: IterationStatement, convertedLoopBodyStatements: Statement[]) => IterationStatement): VisitResult<Statement> {
17311739
if (!shouldConvertIterationStatementBody(node)) {
17321740
let saveAllowedNonLabeledJumps: Jump;
17331741
if (convertedLoopState) {
@@ -1737,7 +1745,7 @@ namespace ts {
17371745
convertedLoopState.allowedNonLabeledJumps = Jump.Break | Jump.Continue;
17381746
}
17391747

1740-
const result = visitEachChild(node, visitor, context);
1748+
const result = convert ? convert(node, /*convertedLoopBodyStatements*/ undefined) : visitEachChild(node, visitor, context);
17411749

17421750
if (convertedLoopState) {
17431751
convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
@@ -1817,7 +1825,7 @@ namespace ts {
18171825
loopParameters,
18181826
<Block>loopBody
18191827
),
1820-
currentState.containsLexicalThis
1828+
currentState.containsLexicalThis
18211829
? NodeEmitFlags.CapturesThis
18221830
: 0
18231831
)
@@ -1895,25 +1903,33 @@ namespace ts {
18951903
}
18961904
}
18971905

1898-
// create variable statement to hold all introduced variable declarations
1906+
// create variable statement to hold all introduced variable declarations
18991907
if (extraVariableDeclarations) {
19001908
statements.push(createVariableStatement(
19011909
/*modifiers*/ undefined,
19021910
createVariableDeclarationList(extraVariableDeclarations)
19031911
));
19041912
}
19051913

1906-
let loop = <IterationStatement>getMutableClone(node);
1907-
// clean statement part
1908-
loop.statement = undefined;
1909-
// visit childnodes to transform initializer/condition/incrementor parts
1910-
loop = visitEachChild(loop, visitor, context);
1911-
// set loop statement
1912-
loop.statement = createBlock(
1913-
generateCallToConvertedLoop(functionName, loopParameters, currentState),
1914-
/*location*/ undefined,
1915-
/*multiline*/ true
1916-
);
1914+
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState);
1915+
let loop: IterationStatement;
1916+
if (convert) {
1917+
loop = convert(node, convertedLoopBodyStatements);
1918+
}
1919+
else {
1920+
loop = <IterationStatement>getMutableClone(node);
1921+
// clean statement part
1922+
loop.statement = undefined;
1923+
// visit childnodes to transform initializer/condition/incrementor parts
1924+
loop = visitEachChild(loop, visitor, context);
1925+
// set loop statement
1926+
loop.statement = createBlock(
1927+
generateCallToConvertedLoop(functionName, loopParameters, currentState),
1928+
/*location*/ undefined,
1929+
/*multiline*/ true
1930+
);
1931+
}
1932+
19171933
statements.push(
19181934
currentParent.kind === SyntaxKind.LabeledStatement
19191935
? createLabel((<LabeledStatement>currentParent).label, loop)

0 commit comments

Comments
 (0)