support type for const tag

pull/9609/head
baseballyama 3 years ago
parent d83bd7f7c1
commit 5e307451dd

@ -0,0 +1,5 @@
---
'svelte': minor
---
feat: support type definition in {@const}

@ -2,8 +2,8 @@ import read_context from '../read/context.js';
import read_expression from '../read/expression.js';
import { error } from '../../../errors.js';
import { create_fragment } from '../utils/create.js';
import { parse_expression_at } from '../acorn.js';
import { walk } from 'zimmerframe';
import { parse } from '../acorn.js';
const regex_whitespace_with_closing_curly_brace = /^\s*}/;
@ -532,13 +532,40 @@ function special(parser) {
// {@const a = b}
parser.require_whitespace();
const expression = read_expression(parser);
const CONST_LENGTH = 'const '.length;
parser.index = parser.index - CONST_LENGTH;
let end_index = parser.index;
/** @type {import('estree').VariableDeclaration | undefined} */
let declaration = undefined;
if (!(expression.type === 'AssignmentExpression' && expression.operator === '=')) {
const dummy_spaces = parser.template.substring(0, parser.index).replace(/[^\n]/g, ' ');
while (true) {
end_index = parser.template.indexOf('}', end_index + 1);
if (end_index === -1) break;
try {
const node = parse(
dummy_spaces + parser.template.substring(parser.index, end_index),
parser.ts
).body[0];
if (node?.type === 'VariableDeclaration') {
declaration = node;
break;
}
} catch (e) {
continue;
}
}
if (
declaration === undefined ||
declaration.declarations.length !== 1 ||
declaration.declarations[0].init === undefined
) {
error(start, 'invalid-const');
}
parser.allow_whitespace();
parser.index = end_index;
parser.eat('}', true);
parser.append(
@ -546,7 +573,14 @@ function special(parser) {
type: 'ConstTag',
start,
end: parser.index,
expression
expression: {
type: 'AssignmentExpression',
start: (declaration.start ?? 0) + CONST_LENGTH,
end: declaration.end ?? 0,
operator: '=',
left: declaration.declarations[0].id,
right: declaration.declarations[0].init
}
})
);
}

@ -11,7 +11,8 @@ import type {
Node,
ObjectExpression,
Pattern,
Program
Program,
VariableDeclaration
} from 'estree';
export interface BaseNode {

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: '<p>10 * 10 = 100</p><p>20 * 20 = 400</p>'
});

@ -0,0 +1,8 @@
<script lang="ts">
const boxes = [ { width: 10, height: 10 }, { width: 20, height: 20 } ];
</script>
{#each boxes as box}
{@const area: number = box.width * box.height}
<p>{box.width} * {box.height} = {area}</p>
{/each}

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: '<p>{}</p>'
});

@ -0,0 +1,5 @@
<script lang="ts">
</script>
{@const name: string = "{}"}
<p>{name}</p>
Loading…
Cancel
Save