Skip to content

Commit

Permalink
(feat) support const tag in if block in the old transformation (#1478)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonlyu123 committed May 13, 2022
1 parent f11c429 commit db20058
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 18 deletions.
@@ -0,0 +1,46 @@
[
{
"range": {
"start": { "line": 21, "character": 19 },
"end": { "line": 21, "character": 26 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?",
"code": 2551,
"tags": []
},
{
"range": {
"start": { "line": 21, "character": 40 },
"end": { "line": 21, "character": 47 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?",
"code": 2551,
"tags": []
},
{
"range": {
"start": { "line": 23, "character": 11 },
"end": { "line": 23, "character": 20 }
},
"severity": 1,
"source": "ts",
"message": "Property 'substring' does not exist on type 'number'.",
"code": 2339,
"tags": []
},
{
"range": {
"start": { "line": 25, "character": 11 },
"end": { "line": 25, "character": 18 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'boolean'.",
"code": 2339,
"tags": []
}
]
@@ -0,0 +1,46 @@
[
{
"range": {
"start": { "line": 21, "character": 19 },
"end": { "line": 21, "character": 26 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?",
"code": 2551,
"tags": []
},
{
"range": {
"start": { "line": 21, "character": 40 },
"end": { "line": 21, "character": 47 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'string'. Did you mean 'fixed'?",
"code": 2551,
"tags": []
},
{
"range": {
"start": { "line": 23, "character": 11 },
"end": { "line": 23, "character": 20 }
},
"severity": 1,
"source": "ts",
"message": "Property 'substring' does not exist on type 'number'.",
"code": 2339,
"tags": []
},
{
"range": {
"start": { "line": 25, "character": 11 },
"end": { "line": 25, "character": 18 }
},
"severity": 1,
"source": "ts",
"message": "Property 'toFixed' does not exist on type 'boolean'.",
"code": 2339,
"tags": []
}
]
@@ -0,0 +1,27 @@
<script lang="ts">
let value: string | number | boolean;
</script>

<!-- valid -->
{#if typeof value === 'string'}
{@const valueStr = value}
{@const valueStr2 = valueStr}

<div>{valueStr.substring(0)}{valueStr2.substring(0)}</div>

<button on:click={() => {valueStr.substring(0)}}></button>
{:else if typeof value === 'number'}
{value.toFixed()}
{/if}

<!-- invalid -->
{#if typeof value === 'string'}
{@const valueStr = value}
{@const valueStr2 = valueStr}

<div>{valueStr.toFixed()}{valueStr2.toFixed()}</div>
{:else if typeof value === 'number'}
{value.substring(0)}
{:else}
{value.toFixed()}
{/if}
73 changes: 63 additions & 10 deletions packages/svelte2tsx/src/htmlxtojsx/nodes/if-else.ts
Expand Up @@ -2,6 +2,7 @@ import MagicString from 'magic-string';
import { IfScope } from './if-scope';
import { BaseNode } from '../../interfaces';
import { withTrailingPropertyAccess } from '../utils/node-utils';
import { extractConstTags } from './const-tag';

/**
* {# if ...}...{/if} ---> {() => {if(...){<>...</>}}}
Expand All @@ -13,33 +14,58 @@ export function handleIf(
ifScope: IfScope
): void {
const endIf = htmlx.lastIndexOf('{', ifBlock.end - 1);
const constTags = extractConstTags(ifBlock.children);
const ifConditionEnd = htmlx.indexOf('}', ifBlock.expression.end) + 1;
const hasConstTags = !!constTags.length;
const endIIFE = createEndIIFE(hasConstTags);
const startIIFE = createStartIIFE(hasConstTags);

if (hasConstTags) {
// {@const hi = exp} <div>{hi}> -> {(() => { const hi = exp; return <> <div>{hi}<div></> })}

constTags.forEach((constTag) => {
constTag(ifConditionEnd, str);
});

str.appendRight(ifConditionEnd, 'return <>');

if (ifBlock.else) {
// {:else} -> </>})()}</> : <>
const elseWord = htmlx.lastIndexOf(':else', ifBlock.else.start);
const elseStart = htmlx.lastIndexOf('{', elseWord);
str.appendLeft(elseStart, endIIFE);
}
}

if (ifBlock.elseif) {
// {:else if expr} -> : (expr) ? <>
// {:else if expr}{@const ...} -> : (expr) ? <>{(() => {const ...; return <>
const elseIfStart = htmlx.lastIndexOf('{', ifBlock.expression.start);
const elseIfConditionEnd = htmlx.indexOf('}', ifBlock.expression.end) + 1;
str.overwrite(elseIfStart, ifBlock.expression.start, '</> : (', { contentOnly: true });
str.overwrite(elseIfStart, ifBlock.expression.start, '</> : (', {
contentOnly: true
});
str.overwrite(
withTrailingPropertyAccess(str.original, ifBlock.expression.end),
elseIfConditionEnd,
') ? <>'
ifConditionEnd,
') ? <>' + startIIFE
);

ifScope.addElseIf(ifBlock.expression, str);

if (!ifBlock.else) {
str.appendLeft(endIf, '</> : <>');
str.appendLeft(endIf, endIIFE + '</> : <>');
}
return;
}

// {#if expr} -> {(expr) ? <>
// {#if expr}{@const ...} -> {(expr) ? <>{(() => {const ...; return <>
str.overwrite(ifBlock.start, ifBlock.expression.start, '{(', { contentOnly: true });
const end = htmlx.indexOf('}', ifBlock.expression.end);

str.overwrite(
withTrailingPropertyAccess(str.original, ifBlock.expression.end),
end + 1,
') ? <>',
ifConditionEnd,
') ? <>' + startIIFE,
{ contentOnly: true }
);

Expand All @@ -50,12 +76,24 @@ export function handleIf(
str.overwrite(endIf, ifBlock.end, '</> }', { contentOnly: true });
} else {
// {/if} -> </> : <></>}
str.overwrite(endIf, ifBlock.end, '</> : <></>}', { contentOnly: true });
// {@const ...} -> </>})()}</> : <></>}
str.overwrite(endIf, ifBlock.end, endIIFE + '</> : <></>}', {
contentOnly: true
});
}
}

function createStartIIFE(hasConstTags: boolean) {
return hasConstTags ? '{(() => {' : '';
}

function createEndIIFE(hasConstTags: boolean) {
return hasConstTags ? '</>})()}' : '';
}

/**
* {:else} ---> </> : <>
* {:else} {@const ...} -> </> : <>{(() => { const ...; return<>
*/
export function handleElse(
htmlx: string,
Expand All @@ -70,10 +108,25 @@ export function handleElse(
) {
return;
}

const elseEnd = htmlx.lastIndexOf('}', elseBlock.start);
const elseword = htmlx.lastIndexOf(':else', elseEnd);
const elseStart = htmlx.lastIndexOf('{', elseword);
str.overwrite(elseStart, elseEnd + 1, '</> : <>');
const constTags = extractConstTags(elseBlock.children);
const hasConstTags = !!constTags.length;

str.overwrite(elseStart, elseEnd + 1, '</> : <>' + createStartIIFE(hasConstTags));

ifScope.addElse();

if (!hasConstTags) {
return;
}

constTags.forEach((constTag) => {
constTag(elseEnd + 1, str);
});

str.appendRight(elseEnd + 1, 'return <>');
str.appendLeft(elseBlock.end, createEndIIFE(true));
}
@@ -1,10 +1,28 @@
<>{(name == "world") ? <>
{@const hello = name}
<>{(name == "world") ? <>{(() => {const hello = name;return <>
{ }
<h1>Hello {hello}</h1>
</> : (true) ? <>
{@const hello = name}
</>})()}</> : (true) ? <>{(() => {const hello = name;return <>
{ }
<h1>Hello {hello}</h1>
</> : <>
{@const hello = name}
</>})()}</> : <>{(() => {const hello = name;return <>
{ }
<h1>Hello {hello}</h1>
</> }</>
</>})()}</> }

{(typeof a === 'string') ? <>{(() => {const aStr = a;const aStr2 = aStr;return <>
{ }
{ }

{a}
</>})()}</> : (typeof a === 'number') ? <>{(() => {const aNum = a;return <>
{ }
</>})()}</> : <></> }

{(typeof a === 'string') ? <>{(() => {const aStr = a;return <>
{ }
</>})()}</> : <></>}

{(typeof a === 'string') ? <>{(() => {const aStr = a;return <>
{ }
</>})()}</> : <>
</> }</>
Expand Up @@ -7,4 +7,22 @@ if(name == "world"){
}else{
const hello = name;
{ svelteHTML.createElement("h1", {}); hello; }
}
}

if(typeof a === 'string'){
const aStr = a;
const aStr2 = aStr;

a;
} else if (typeof a === 'number'){
const aNum = a;
}

if(typeof a === 'string'){
const aStr = a;
}

if(typeof a === 'string'){
const aStr = a;
}else{
}
Expand Up @@ -8,3 +8,21 @@
{@const hello = name}
<h1>Hello {hello}</h1>
{/if}

{#if typeof a === 'string'}
{@const aStr = a}
{@const aStr2 = aStr}

{a}
{:else if typeof a === 'number'}
{@const aNum = a}
{/if}

{#if typeof a === 'string'}
{@const aStr = a}
{/if}

{#if typeof a === 'string'}
{@const aStr = a}
{:else}
{/if}

0 comments on commit db20058

Please sign in to comment.