mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 22:29:17 +00:00
fix(minifier): preserve block statement in labeled iteration statements (#25162)
Preserve block statements inside labeled statements when they contain an
iteration statement (for/while/do-while).
Previously, these blocks were removed, which caused continue label
syntax errors to not be preserved in the minified output:
```js
label: {
for (let i = 0; i < 10; i++) {
continue label; // SyntaxError: 'label' does not denote an iteration statement
}
}
```
fixes #25215
------------------
this guard is broad as we are not checking if inner loop has labeled
continue, this optimization could be implemented but its better if we
wait for #24155
```js
label: for (let i = 0; i < 10; i++) continue label;
```
This commit is contained in:
1 parent
771d79a9e3
commit
e75e102c49
2 files changed
+27
-2
No files matched your search
@@ -43,6 +43,7 @@ impl<'a> PeepholeOptimizations {
|
||||
|| matches!(first, Statement::FunctionDeclaration(_))
|
||||
|| (matches!(first, Statement::IfStatement(decl) if decl.alternate.is_some())
|
||||
&& matches!(ctx.parent(), Ancestor::IfStatementConsequent(_)))
|
||||
|| (first.is_iteration_statement() && ctx.parent().is_labeled_statement())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ fn test_break_optimization() {
|
||||
test("f:while(a())break f;", "f:for(;a();)break f;");
|
||||
test_same("f:for(x in a())break f");
|
||||
|
||||
test("f:{while(a())break;}", "f:for(;a();)break;");
|
||||
test("f:{for(x in a())break}", "f:for(x in a())break;");
|
||||
test("f:{while(a())break;}", "f:{for(;a();)break;}");
|
||||
test("f:{for(x in a())break}", "f:{for(x in a())break;}");
|
||||
|
||||
test("f:try{break f;}catch(e){break f;}", "f:try{break f}catch{break f}"); // ;
|
||||
test(
|
||||
@@ -29,6 +29,30 @@ fn test_break_optimization() {
|
||||
test_same("function f() { a: { b(); return; } c(); }");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_labeled_continue_optimization() {
|
||||
test("a:while(true)continue a;", "a:for(;;)continue a;"); // a:for(;;);
|
||||
test(
|
||||
"x:while(x)y:while(y){if(a)continue x;if(b)continue x;}",
|
||||
"x:for(;x;)y:for(;y;)if(a||b)continue x;",
|
||||
);
|
||||
test(
|
||||
"x:while(x)y:while(y){if(a)continue y;if(b)continue y;}",
|
||||
"x:for(;x;)y:for(;y;)if(a||b)continue y;",
|
||||
); // x:for(;x;)y:for(;y;)a||b;
|
||||
test(
|
||||
"x:while(x)y:while(y){if(a)continue x;if(b)continue y}",
|
||||
"x:for(;x;)y:for(;y;){if(a)continue x;if(b)continue y}",
|
||||
); // x:for(;x;)y:for(;y;){if(a)continue x;b}
|
||||
// SyntaxError: Illegal continue statement: 'a' does not denote an iteration statement
|
||||
test_same("a:if(a()){b();continue a}");
|
||||
// SyntaxError: Illegal continue statement: no surrounding iteration statement
|
||||
test_same("a:{for(let i=0;i<10;i++)continue a}");
|
||||
test("f:{if(true){a();continue f;}else;b();}", "f:{a();continue f}");
|
||||
// SyntaxError: Undefined label 'a'
|
||||
test_same("for(let i=0;i<10;i++)continue a;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_return_optimization() {
|
||||
test("function f(){return}", "function f(){}");
|
||||
|
||||
Reference in new issue
Block a user