Skip to content

Commit b844861

Browse files
authored
Transform if-blocks to ternaries (#696)
#619 This way the TypeScript control flow will be broken in less instances and nested if-blocks like ``` {#if a} {#if a.a} .. {/if} {/if} ``` will not throw "a could be undefined" in the inner if anymore in strict mode. This will not shut down all instances of control flow breakage, because for example slots/each/await are still transformed to lambda-functions.
1 parent 088406c commit b844861

File tree

16 files changed

+180
-48
lines changed

16 files changed

+180
-48
lines changed

packages/svelte2tsx/src/htmlxtojsx/nodes/if-else.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,47 @@ import { Node } from 'estree-walker';
55
* {# if ...}...{/if} ---> {() => {if(...){<>...</>}}}
66
*/
77
export function handleIf(htmlx: string, str: MagicString, ifBlock: Node): void {
8+
const endIf = htmlx.lastIndexOf('{', ifBlock.end - 1);
9+
810
if (ifBlock.elseif) {
9-
//we are an elseif so our work is easier
10-
str.appendLeft(ifBlock.expression.start, '(');
11-
str.appendLeft(ifBlock.expression.end, ')');
11+
// {:else if expr} -> : (expr) ? <>
12+
const elseIfStart = htmlx.lastIndexOf('{', ifBlock.expression.start);
13+
const elseIfConditionEnd = htmlx.indexOf('}', ifBlock.expression.end) + 1;
14+
str.overwrite(elseIfStart, ifBlock.expression.start, '</> : (', { contentOnly: true });
15+
str.overwrite(ifBlock.expression.end, elseIfConditionEnd, ') ? <>');
16+
17+
if (!ifBlock.else) {
18+
str.appendLeft(endIf, '</> : <>');
19+
}
1220
return;
1321
}
14-
// {#if expr} ->
15-
// {() => { if (expr){ <>
16-
str.overwrite(ifBlock.start, ifBlock.expression.start, '{() => {if (');
22+
23+
// {#if expr} -> {(expr) ? <>
24+
str.overwrite(ifBlock.start, ifBlock.expression.start, '{(', { contentOnly: true });
1725
const end = htmlx.indexOf('}', ifBlock.expression.end);
18-
str.overwrite(ifBlock.expression.end, end + 1, '){<>');
26+
str.overwrite(ifBlock.expression.end, end + 1, ') ? <>', { contentOnly: true });
1927

20-
// {/if} -> </>}}}</>
21-
const endif = htmlx.lastIndexOf('{', ifBlock.end - 1);
22-
str.overwrite(endif, ifBlock.end, '</>}}}');
28+
if (ifBlock.else) {
29+
// {/if} -> </> }
30+
str.overwrite(endIf, ifBlock.end, '</> }', { contentOnly: true });
31+
} else {
32+
// {/if} -> </> : <></>}
33+
str.overwrite(endIf, ifBlock.end, '</> : <></>}', { contentOnly: true });
34+
}
2335
}
2436

2537
/**
26-
* {:else} ---> </>} else {<>
38+
* {:else} ---> </> : <>
2739
*/
2840
export function handleElse(htmlx: string, str: MagicString, elseBlock: Node, parent: Node): void {
29-
if (parent.type !== 'IfBlock') {
41+
if (
42+
parent.type !== 'IfBlock' ||
43+
(elseBlock.children[0]?.type === 'IfBlock' && elseBlock.children[0]?.elseif)
44+
) {
3045
return;
3146
}
3247
const elseEnd = htmlx.lastIndexOf('}', elseBlock.start);
3348
const elseword = htmlx.lastIndexOf(':else', elseEnd);
3449
const elseStart = htmlx.lastIndexOf('{', elseword);
35-
str.overwrite(elseStart, elseStart + 1, '</>}');
36-
str.overwrite(elseEnd, elseEnd + 1, '{<>');
37-
const colon = htmlx.indexOf(':', elseword);
38-
str.remove(colon, colon + 1);
50+
str.overwrite(elseStart, elseEnd + 1, '</> : <>');
3951
}

packages/svelte2tsx/src/svelte2tsx/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ interface AddComponentExportPara {
3838
uses$$propsOr$$restProps: boolean;
3939
strictMode: boolean;
4040
/**
41-
* If true, not fallback to `CustomEvent<any>`
41+
* If true, not fallback to `any`
4242
* -> all unknown events will throw a type error
4343
* */
4444
strictEvents: boolean;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<>{() => {if (false){<>
1+
<>{(false) ? <>
22
<svelteself {...__sveltets_ensureType(__sveltets_componentType(), element)} />
3-
</>}}}</>
3+
</> : <></>}</>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<>{() => {if (name == "world"){<>!</>}}}{__sveltets_each(x, (y) => <>!</>)}{() => {let _$$p = (x); __sveltets_awaitThen(_$$p, (y) => {<>!</>})}}{() => {if (bla){<>*</>}}}</>
1+
<>{(name == "world") ? <>!</> : <></>}{__sveltets_each(x, (y) => <>!</>)}{() => {let _$$p = (x); __sveltets_awaitThen(_$$p, (y) => {<>!</>})}}{(bla) ? <>*</> : <></>}</>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<>{() => {if (name == "world"){<>
1+
<>{(name == "world") ? <>
22
<h1>Hello {name}</h1>
3-
</>}}}</>
3+
</> : <></>}</>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<>{() => {if (true, false){<>
1+
<>{(true, false) ? <>
22
<h1>Hello {name}</h1>
3-
</>}}}</>
3+
</> : <></>}</>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<>{(name == "world") ? <>{(bla) ? <>asd</> : <></>}{(bla) ? <>asd</> : <></>}</> : (foo) ? <>{(bla) ? <>asd</> : <>bar</> }</> : <>{(bla) ? <>asd</> : (blubb) ? <>asd</> : <></> }</> }
2+
3+
{(name == "world") ? <>
4+
{(bla) ? <>asd</> : <></>}
5+
{(bla) ? <>
6+
asd
7+
</> : <>
8+
bar
9+
</> }
10+
{(bla) ? <>
11+
asd
12+
</> : (blubb) ? <>
13+
bar
14+
</> : <></> }
15+
{(bla) ? <>
16+
asd
17+
</> : (blubb) ? <>
18+
bar
19+
</> : <>
20+
foo
21+
</> }
22+
</> : (foo) ? <>
23+
{(bla) ? <>asd</> : <></>}
24+
{(bla) ? <>
25+
asd
26+
</> : <>
27+
bar
28+
</> }
29+
{(bla) ? <>
30+
asd
31+
</> : (blubb) ? <>
32+
bar
33+
</> : <></> }
34+
{(bla) ? <>
35+
asd
36+
</> : (blubb) ? <>
37+
bar
38+
</> : <>
39+
foo
40+
</> }
41+
</> : <>
42+
{(bla) ? <>asd</> : <></>}
43+
{(bla) ? <>
44+
asd
45+
</> : <>
46+
bar
47+
</> }
48+
{(bla) ? <>
49+
asd
50+
</> : (blubb) ? <>
51+
bar
52+
</> : <></> }
53+
{(bla) ? <>
54+
asd
55+
</> : (blubb) ? <>
56+
bar
57+
</> : <>
58+
foo
59+
</> }
60+
</> }</>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{#if name == "world"}{#if bla}asd{/if}{#if bla}asd{/if}{:else if foo}{#if bla}asd{:else}bar{/if}{:else}{#if bla}asd{:else if blubb}asd{/if}{/if}
2+
3+
{#if name == "world"}
4+
{#if bla}asd{/if}
5+
{#if bla}
6+
asd
7+
{:else}
8+
bar
9+
{/if}
10+
{#if bla}
11+
asd
12+
{:else if blubb}
13+
bar
14+
{/if}
15+
{#if bla}
16+
asd
17+
{:else if blubb}
18+
bar
19+
{:else}
20+
foo
21+
{/if}
22+
{:else if foo}
23+
{#if bla}asd{/if}
24+
{#if bla}
25+
asd
26+
{:else}
27+
bar
28+
{/if}
29+
{#if bla}
30+
asd
31+
{:else if blubb}
32+
bar
33+
{/if}
34+
{#if bla}
35+
asd
36+
{:else if blubb}
37+
bar
38+
{:else}
39+
foo
40+
{/if}
41+
{:else}
42+
{#if bla}asd{/if}
43+
{#if bla}
44+
asd
45+
{:else}
46+
bar
47+
{/if}
48+
{#if bla}
49+
asd
50+
{:else if blubb}
51+
bar
52+
{/if}
53+
{#if bla}
54+
asd
55+
{:else if blubb}
56+
bar
57+
{:else}
58+
foo
59+
{/if}
60+
{/if}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<>{() => {if (name == "world"){<>
1+
<>{(name == "world") ? <>
22
<h1>Hello {name}</h1>
3-
</>}else{<>
3+
</> : <>
44
<h2>hello {name}</h2>
5-
</>}}}</>
5+
</> }</>
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<>{() => {if (name1 == "world"){<>
1+
<>{(name1 == "world") ? <>
22
<h1>Hello {name2}</h1>
3-
</>}else if (name3 == "person"){<>
3+
</> : (name3 == "person") ? <>
44
<h2>hello {name4}</h2>
5-
</>}}}</>
5+
</> : <></> }</>

0 commit comments

Comments
 (0)