New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(do-expr): SwitchStatement with IfStatement cases #11728
Changes from 4 commits
7ce7758
ed71ebf
8439fc8
363e2a5
063baf0
38088a1
1cbb509
8cadeb1
3723a28
9510c99
a3c491a
cd1fdbb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
const x = (n) => do { | ||
switch (n) { | ||
case 0: | ||
if (true) { | ||
'out'; | ||
break; | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const x = n => function () { | ||
switch (n) { | ||
case 0: | ||
if (true) { | ||
return 'out'; | ||
} | ||
|
||
} | ||
}(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const x = do { | ||
y: { | ||
'out'; | ||
break y; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can not remove labelled break statement without more execution context, i.e. // returns 42
do { y: { "out"; break y; } 42 } I don't come up with a satisfiable fix regarding to the LabeledStatement without significant rewriting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do, but does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we replace (() => { y: { return "out"; } return 42 } })()
// returns "out" I don't think we correctly handle the labeled break statement in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I see. I forgot about the loop. Thanks for the feedback, and sounds good! |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"plugins": ["transform-block-scoping", "proposal-do-expressions"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var x = function () { | ||
y: { | ||
return 'out'; | ||
} | ||
}(); |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -81,14 +81,21 @@ export function getCompletionRecords(): NodePath[] { | |||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("alternate"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isDoExpression() || this.isFor() || this.isWhile()) { | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("body"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isProgram() || this.isBlockStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isProgram()) { | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("body").pop(), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isBlockStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can not remove do { switch(0) { case 0: {
if (true) { break; } "unreachable";
} }
} If The completion record tracking of SwitchStatement was introduced at #10070. The babel/packages/babel-traverse/src/path/family.js Lines 52 to 60 in e498bee
The babel/packages/babel-traverse/src/path/family.js Lines 29 to 41 in e498bee
Apparently this routine can not find function findBreak(statements) {
let breakStatement;
if (!Array.isArray(statements)) {
statements = [statements];
}
for (const statement of statements) {
if (statement.isBlockStatement()) {
breakStatement = findBreak(statement.get("body"));
} else if (statement.isIfStatement()) {
breakStatement =
findBreak(statement.get("consequent")) ??
findBreak(statement.get("alternate"));
} else if (statement.isCatchClause() || statement.isLabeledStatement()) {
breakStatement = findBreak(statement.get("body"));
// todo: add other statements except Iteration and Switch, which is breakable statement.
} else if (statement.isBreakStatement()) {
breakStatement = statement;
}
if (breakStatement) {
return breakStatement;
}
}
return null;
} By doing so we can reuse current There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reasoning behind returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a good question! Each function owns a new execution context. So when a {
a: 42;
() => { break a }
} is invalid because the label There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That completely makes sense. I have made the necessary changes. Please let me know if there needs to be any others! |
||||||||||||||||||||||||||||||||||||||||||||||
const body = this.get("body"); | ||||||||||||||||||||||||||||||||||||||||||||||
const last = body[body.length - 1]; | ||||||||||||||||||||||||||||||||||||||||||||||
if (last.isBreakStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
last.remove(); | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("body").pop(), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isFunction()) { | ||||||||||||||||||||||||||||||||||||||||||||||
return this.get("body").getCompletionRecords(); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isTryStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("block"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("handler"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isCatchClause()) { | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isCatchClause() || this.isLabeledStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
paths = addCompletionRecords(this.get("body"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
} else if (this.isSwitchStatement()) { | ||||||||||||||||||||||||||||||||||||||||||||||
paths = completionRecordForSwitch(this.get("cases"), paths); | ||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test case where
BreakStatement
does not follow anExpressionStatement
?