pull/9482/head
Rich Harris 3 years ago
parent 7a04cdfbc0
commit 87b322bbe2

@ -13,6 +13,7 @@ export function parse(source) {
const { onComment, add_comments } = get_comment_handlers(source);
const ast = /** @type {import('estree').Program} */ (
strip_types(
source,
// @ts-expect-error
ParserWithTS.parse(source, {
onComment,
@ -37,6 +38,7 @@ export function parse_expression_at(source, index) {
const { onComment, add_comments } = get_comment_handlers(source);
const ast = /** @type {import('estree').Expression} */ (
strip_types(
source,
// @ts-expect-error
ParserWithTS.parseExpressionAt(source, index, {
onComment,

@ -2,6 +2,7 @@ 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';
const regex_whitespace_with_closing_curly_brace = /^\s*}/;
@ -261,6 +262,18 @@ function open(parser) {
const context = parser.match(')') ? null : read_context(parser);
parser.allow_whitespace();
if (context && parser.eat(':')) {
// we need to trick Acorn into parsing the type annotation
const insert = '_ as ';
let a = parser.index - insert.length;
const template = ' '.repeat(a) + insert + parser.template.slice(parser.index);
const expression = parse_expression_at(template, a);
context.typeAnnotation = /** @type {any} */ (expression).typeAnnotation;
parser.index = /** @type {number} */ (expression.end);
}
parser.allow_whitespace();
parser.eat(')', true);

@ -2,45 +2,24 @@ import { walk } from 'zimmerframe';
import * as b from '../../utils/builders.js';
/**
* @param {string} source
* @param {import('estree').Node} node
*/
export function strip_types(node) {
export function strip_types(source, node) {
return walk(node, null, {
_(node, context) {
// @ts-expect-error
if (node.exportKind === 'type' || node.importKind === 'type') {
console.log('>>>', node);
return b.empty;
}
// @ts-expect-error
delete node.loc.start.index;
// @ts-expect-error
delete node.loc.end.index;
// // @ts-expect-error
// delete node.returnType;
// // @ts-expect-error
// delete node.importKind;
// // @ts-expect-error
// delete node.exportKind;
// // @ts-expect-error
// delete node.typeAnnotation;
// // @ts-expect-error
// delete node.typeParameters;
// if (node.type.startsWith('TS')) {
// const ts_node = /** @type {any} */ (node);
// switch (ts_node.type) {
// case 'TSAsExpression':
// case 'TSNonNullExpression':
// // hack to make sure parser skips over the type assertion
// ts_node.expression.end = ts_node.end;
// return context.visit(ts_node.expression);
// default:
// return b.empty;
// }
// }
if (/** @type {any} */ (node).typeAnnotation && node.end === undefined) {
// i think there might be a bug in acorn-typescript that prevents
// `end` from being assigned when there's a type annotation
let end = /** @type {any} */ (node).typeAnnotation.start;
while (/\s/.test(source[end - 1])) end -= 1;
node.end = end;
}
context.next();
}

@ -1,5 +1,5 @@
{#snippet foo()}
<p>hello</p>
{#snippet foo(msg: string)}
<p>{msg}</p>
{/snippet}
{@render foo()}
{@render foo(msg)}

@ -2,7 +2,7 @@
"css": null,
"js": [],
"start": 0,
"end": 58,
"end": 72,
"type": "Root",
"fragment": {
"type": "Fragment",
@ -10,39 +10,73 @@
{
"type": "SnippetBlock",
"start": 0,
"end": 41,
"end": 52,
"expression": {
"type": "Identifier",
"start": 10,
"end": 13,
"name": "foo"
},
"context": null,
"context": {
"type": "Identifier",
"name": "msg",
"start": 14,
"end": 17,
"typeAnnotation": {
"type": "TSStringKeyword",
"start": 19,
"end": 25,
"loc": {
"start": {
"line": 1,
"column": 19
},
"end": {
"line": 1,
"column": 25
}
}
}
},
"body": {
"type": "Fragment",
"nodes": [
{
"type": "Text",
"start": 16,
"end": 18,
"start": 27,
"end": 29,
"raw": "\n\t",
"data": "\n\t"
},
{
"type": "RegularElement",
"start": 18,
"end": 30,
"start": 29,
"end": 41,
"name": "p",
"attributes": [],
"fragment": {
"type": "Fragment",
"nodes": [
{
"type": "Text",
"start": 21,
"end": 26,
"raw": "hello",
"data": "hello"
"type": "ExpressionTag",
"start": 32,
"end": 37,
"expression": {
"type": "Identifier",
"start": 33,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 8
}
},
"name": "msg"
}
}
],
"transparent": true
@ -50,8 +84,8 @@
},
{
"type": "Text",
"start": 30,
"end": 31,
"start": 41,
"end": 42,
"raw": "\n",
"data": "\n"
}
@ -61,19 +95,19 @@
},
{
"type": "Text",
"start": 41,
"end": 43,
"start": 52,
"end": 54,
"raw": "\n\n",
"data": "\n\n"
},
{
"type": "RenderTag",
"start": 43,
"end": 58,
"start": 54,
"end": 72,
"expression": {
"type": "Identifier",
"start": 52,
"end": 55,
"start": 63,
"end": 66,
"loc": {
"start": {
"line": 5,
@ -86,7 +120,22 @@
},
"name": "foo"
},
"argument": null
"argument": {
"type": "Identifier",
"start": 67,
"end": 70,
"loc": {
"start": {
"line": 5,
"column": 13
},
"end": {
"line": 5,
"column": 16
}
},
"name": "msg"
}
}
],
"transparent": false

@ -0,0 +1,10 @@
<script>
let count = $state(0);
</script>
<button
on:click={(e: MouseEvent) => {
const next: number = count + 1;
count = next;
}}
>clicks: {count}</button>

@ -0,0 +1,482 @@
{
"css": null,
"js": [],
"start": 44,
"end": 163,
"type": "Root",
"fragment": {
"type": "Fragment",
"nodes": [
{
"type": "Text",
"start": 42,
"end": 44,
"raw": "\n\n",
"data": "\n\n"
},
{
"type": "RegularElement",
"start": 44,
"end": 163,
"name": "button",
"attributes": [
{
"start": 53,
"end": 137,
"type": "OnDirective",
"name": "click",
"modifiers": [],
"expression": {
"type": "ArrowFunctionExpression",
"start": 63,
"end": 136,
"loc": {
"start": {
"line": 6,
"column": 11
},
"end": {
"line": 9,
"column": 2
}
},
"id": null,
"expression": false,
"generator": false,
"async": false,
"params": [
{
"type": "Identifier",
"start": 64,
"end": 65,
"loc": {
"start": {
"line": 6,
"column": 12
},
"end": 77
},
"name": "e",
"typeAnnotation": {
"type": "TSTypeAnnotation",
"start": 65,
"end": 77,
"loc": {
"start": {
"line": 6,
"column": 13
},
"end": {
"line": 6,
"column": 25
}
},
"typeAnnotation": {
"type": "TSTypeReference",
"start": 67,
"end": 77,
"loc": {
"start": {
"line": 6,
"column": 15
},
"end": {
"line": 6,
"column": 25
}
},
"typeName": {
"type": "Identifier",
"start": 67,
"end": 77,
"loc": {
"start": {
"line": 6,
"column": 15
},
"end": {
"line": 6,
"column": 25
}
},
"name": "MouseEvent"
}
}
}
}
],
"body": {
"type": "BlockStatement",
"start": 82,
"end": 136,
"loc": {
"start": {
"line": 6,
"column": 30
},
"end": {
"line": 9,
"column": 2
}
},
"body": [
{
"type": "VariableDeclaration",
"start": 86,
"end": 117,
"loc": {
"start": {
"line": 7,
"column": 2
},
"end": {
"line": 7,
"column": 33
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 92,
"end": 116,
"loc": {
"start": {
"line": 7,
"column": 8
},
"end": {
"line": 7,
"column": 32
}
},
"id": {
"type": "Identifier",
"start": 92,
"end": 20,
"loc": {
"start": {
"line": 7,
"column": 8
},
"end": {
"line": 7,
"column": 20
}
},
"name": "next",
"typeAnnotation": {
"type": "TSTypeAnnotation",
"start": 96,
"end": 104,
"loc": {
"start": {
"line": 7,
"column": 12
},
"end": {
"line": 7,
"column": 20
}
},
"typeAnnotation": {
"type": "TSNumberKeyword",
"start": 98,
"end": 104,
"loc": {
"start": {
"line": 7,
"column": 14
},
"end": {
"line": 7,
"column": 20
}
}
}
}
},
"init": {
"type": "BinaryExpression",
"start": 107,
"end": 116,
"loc": {
"start": {
"line": 7,
"column": 23
},
"end": {
"line": 7,
"column": 32
}
},
"left": {
"type": "Identifier",
"start": 107,
"end": 112,
"loc": {
"start": {
"line": 7,
"column": 23
},
"end": {
"line": 7,
"column": 28
}
},
"name": "count"
},
"operator": "+",
"right": {
"type": "Literal",
"start": 115,
"end": 116,
"loc": {
"start": {
"line": 7,
"column": 31
},
"end": {
"line": 7,
"column": 32
}
},
"value": 1,
"raw": "1"
}
}
}
],
"kind": "const"
},
{
"type": "ExpressionStatement",
"start": 120,
"end": 133,
"loc": {
"start": {
"line": 8,
"column": 2
},
"end": {
"line": 8,
"column": 15
}
},
"expression": {
"type": "AssignmentExpression",
"start": 120,
"end": 132,
"loc": {
"start": {
"line": 8,
"column": 2
},
"end": {
"line": 8,
"column": 14
}
},
"operator": "=",
"left": {
"type": "Identifier",
"start": 120,
"end": 125,
"loc": {
"start": {
"line": 8,
"column": 2
},
"end": {
"line": 8,
"column": 7
}
},
"name": "count"
},
"right": {
"type": "Identifier",
"start": 128,
"end": 132,
"loc": {
"start": {
"line": 8,
"column": 10
},
"end": {
"line": 8,
"column": 14
}
},
"name": "next"
}
}
}
]
}
}
}
],
"fragment": {
"type": "Fragment",
"nodes": [
{
"type": "Text",
"start": 139,
"end": 147,
"raw": "clicks: ",
"data": "clicks: "
},
{
"type": "ExpressionTag",
"start": 147,
"end": 154,
"expression": {
"type": "Identifier",
"start": 148,
"end": 153,
"loc": {
"start": {
"line": 10,
"column": 10
},
"end": {
"line": 10,
"column": 15
}
},
"name": "count"
}
}
],
"transparent": true
}
}
],
"transparent": false
},
"options": null,
"instance": {
"type": "Script",
"start": 0,
"end": 42,
"context": "default",
"content": {
"type": "Program",
"start": 8,
"end": 33,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 0
}
},
"body": [
{
"type": "VariableDeclaration",
"start": 10,
"end": 32,
"loc": {
"start": {
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 23
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 14,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 22
}
},
"id": {
"type": "Identifier",
"start": 14,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 10
}
},
"name": "count"
},
"init": {
"type": "CallExpression",
"start": 22,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 22
}
},
"callee": {
"type": "Identifier",
"start": 22,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 19
}
},
"name": "$state"
},
"arguments": [
{
"type": "Literal",
"start": 29,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 20
},
"end": {
"line": 2,
"column": 21
}
},
"value": 0,
"raw": "0"
}
],
"optional": false
}
}
],
"kind": "let"
}
],
"sourceType": "module"
}
}
}

@ -2,7 +2,7 @@
let count = $state(0);
</script>
{#snippet foo(n)}
{#snippet foo(n: number)}
<p>clicks: {n}</p>
{/snippet}

Loading…
Cancel
Save