fix(do-expr): SwitchStatement with IfStatement cases (#11728)

* test(do-expr): condition before break

* test(do-expr): labeled break

* fix(do-expr): add check for break in BlockStatement

* fix(do-expr): add LabeledStatement case for getCompletionRecords

* test(do-expr): rename condition before break to condition before expression

* revert(do-expr): undo remove break for do switch

* revert(do-expr): undo remove labeled break

* test(do-expr): add condition before break

* test(do-expr): update condition before break

* test(do-expr): remove labeled break

* fix(do-expr): add tree search in findBreak

* fix(do-expr): ignore isFunction case in findBreak
This commit is contained in:
Barron Wei 2020-09-18 10:34:35 -04:00 committed by GitHub
parent 44f8287d7a
commit 1a8e7ff2ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 14 deletions

View File

@ -0,0 +1,10 @@
const x = (n) => do {
switch (n) {
case 0:
if (true) {
break;
}
}
}
expect(x(0)).toBe(undefined);

View File

@ -0,0 +1,8 @@
const x = (n) => do {
switch (n) {
case 0:
if (true) {
break;
}
}
}

View File

@ -0,0 +1,6 @@
const x = n => function () {
switch (n) {
case 0:
if (true) return void 0;
}
}();

View File

@ -0,0 +1,10 @@
const x = (n) => do {
switch (n) {
case 0:
if (true) {
'out';
break;
}
}
}

View File

@ -0,0 +1,9 @@
const x = n => function () {
switch (n) {
case 0:
if (true) {
return 'out';
}
}
}();

View File

@ -18,6 +18,40 @@ function addCompletionRecords(path, paths) {
return paths; return paths;
} }
function findBreak(statements): ?NodePath {
let breakStatement;
if (!Array.isArray(statements)) {
statements = [statements];
}
for (const statement of statements) {
if (
statement.isDoExpression() ||
statement.isProgram() ||
statement.isBlockStatement() ||
statement.isCatchClause() ||
statement.isLabeledStatement()
) {
breakStatement = findBreak(statement.get("body"));
} else if (statement.isIfStatement()) {
breakStatement =
findBreak(statement.get("consequent")) ??
findBreak(statement.get("alternate"));
} else if (statement.isTryStatement()) {
breakStatement =
findBreak(statement.get("block")) ??
findBreak(statement.get("handler"));
} else if (statement.isBreakStatement()) {
breakStatement = statement;
}
if (breakStatement) {
return breakStatement;
}
}
return null;
}
function completionRecordForSwitch(cases, paths) { function completionRecordForSwitch(cases, paths) {
let isLastCaseWithConsequent = true; let isLastCaseWithConsequent = true;
@ -25,20 +59,7 @@ function completionRecordForSwitch(cases, paths) {
const switchCase = cases[i]; const switchCase = cases[i];
const consequent = switchCase.get("consequent"); const consequent = switchCase.get("consequent");
let breakStatement; let breakStatement = findBreak(consequent);
findBreak: for (const statement of consequent) {
if (statement.isBlockStatement()) {
for (const statementInBlock of statement.get("body")) {
if (statementInBlock.isBreakStatement()) {
breakStatement = statementInBlock;
break findBreak;
}
}
} else if (statement.isBreakStatement()) {
breakStatement = statement;
break;
}
}
if (breakStatement) { if (breakStatement) {
while ( while (