Skip to content

Commit 6a41961

Browse files
crisbetoatscott
authored andcommitted
fix(compiler): ignore empty switch blocks (#53776)
Adds some code to the compiler so that it ignores empty `@switch` blocks instead of trying to generate code for them. Fixes #53773. PR Close #53776
1 parent b87324d commit 6a41961

File tree

7 files changed

+99
-0
lines changed

7 files changed

+99
-0
lines changed

packages/compiler-cli/src/ngtsc/typecheck/test/type_check_block_spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,10 @@ describe('type check blocks', () => {
15331533
'else if ((_t2()) === "two") { "" + ((this).two()); } ' +
15341534
'else { "" + ((this).default()); } }');
15351535
});
1536+
1537+
it('should handle an empty switch block', () => {
1538+
expect(tcb('@switch (expr) {}')).toContain('if (true) { ((this).expr); }');
1539+
});
15361540
});
15371541

15381542
describe('for loop blocks', () => {

packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/GOLDEN_PARTIAL.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,47 @@ export declare class MyApp {
290290
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, true, never>;
291291
}
292292

293+
/****************************************************************************************************
294+
* PARTIAL FILE: empty_switch.js
295+
****************************************************************************************************/
296+
import { Component } from '@angular/core';
297+
import * as i0 from "@angular/core";
298+
export class MyApp {
299+
constructor() {
300+
this.message = 'hello';
301+
}
302+
}
303+
MyApp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
304+
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: `
305+
<div>
306+
{{message}}
307+
@switch (message) {}
308+
{{message}}
309+
</div>
310+
`, isInline: true });
311+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
312+
type: Component,
313+
args: [{
314+
template: `
315+
<div>
316+
{{message}}
317+
@switch (message) {}
318+
{{message}}
319+
</div>
320+
`,
321+
}]
322+
}] });
323+
324+
/****************************************************************************************************
325+
* PARTIAL FILE: empty_switch.d.ts
326+
****************************************************************************************************/
327+
import * as i0 from "@angular/core";
328+
export declare class MyApp {
329+
message: string;
330+
static ɵfac: i0.ɵɵFactoryDeclaration<MyApp, never>;
331+
static ɵcmp: i0.ɵɵComponentDeclaration<MyApp, "ng-component", never, {}, {}, never, never, false, never>;
332+
}
333+
293334
/****************************************************************************************************
294335
* PARTIAL FILE: basic_if.js
295336
****************************************************************************************************/

packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_control_flow/TEST_CASES.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,23 @@
7070
}
7171
]
7272
},
73+
{
74+
"description": "should not generate code for empty switch blocks",
75+
"inputFiles": [
76+
"empty_switch.ts"
77+
],
78+
"expectations": [
79+
{
80+
"files": [
81+
{
82+
"expected": "empty_switch_template.js",
83+
"generated": "empty_switch.js"
84+
}
85+
],
86+
"failureMessage": "Incorrect template"
87+
}
88+
]
89+
},
7390
{
7491
"description": "should generate a basic if block",
7592
"inputFiles": [
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
template: `
5+
<div>
6+
{{message}}
7+
@switch (message) {}
8+
{{message}}
9+
</div>
10+
`,
11+
})
12+
export class MyApp {
13+
message = 'hello';
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function MyApp_Template(rf, ctx) {
2+
if (rf & 1) {
3+
$r3$.ɵɵelementStart(0, "div");
4+
$r3$.ɵɵtext(1);
5+
$r3$.ɵɵtext(2);
6+
$r3$.ɵɵelementEnd();
7+
}
8+
if (rf & 2) {
9+
$r3$.ɵɵadvance(1);
10+
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
11+
$r3$.ɵɵadvance(1);
12+
$r3$.ɵɵtextInterpolate1(" ", ctx.message, " ");
13+
}
14+
}

packages/compiler/src/render3/view/template.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,10 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
12491249
}
12501250

12511251
visitSwitchBlock(block: t.SwitchBlock): void {
1252+
if (block.cases.length === 0) {
1253+
return;
1254+
}
1255+
12521256
// We have to process the block in two steps: once here and again in the update instruction
12531257
// callback in order to generate the correct expressions when pipes or pure functions are used.
12541258
const caseData = block.cases.map(currentCase => {

packages/compiler/src/template/pipeline/src/ingest.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,11 @@ function ingestIfBlock(unit: ViewCompilationUnit, ifBlock: t.IfBlock): void {
379379
* Ingest an `@switch` block into the given `ViewCompilation`.
380380
*/
381381
function ingestSwitchBlock(unit: ViewCompilationUnit, switchBlock: t.SwitchBlock): void {
382+
// Don't ingest empty switches since they won't render anything.
383+
if (switchBlock.cases.length === 0) {
384+
return;
385+
}
386+
382387
let firstXref: ir.XrefId|null = null;
383388
let firstSlotHandle: ir.SlotHandle|null = null;
384389
let conditions: Array<ir.ConditionalCaseExpr> = [];

0 commit comments

Comments
 (0)