diff --git a/.changeset/young-clouds-fly.md b/.changeset/young-clouds-fly.md new file mode 100644 index 00000000..8ade5dc3 --- /dev/null +++ b/.changeset/young-clouds-fly.md @@ -0,0 +1,5 @@ +--- +"svelte-eslint-parser": patch +--- + +fix: parsing error for nesting `{#snippet}` diff --git a/src/context/script-let.ts b/src/context/script-let.ts index ad638218..cfe9ac8e 100644 --- a/src/context/script-let.ts +++ b/src/context/script-let.ts @@ -102,9 +102,12 @@ function getNodeRange( ]; } +type StatementNodeType = `${TSESTree.Statement["type"]}`; + type RestoreCallback = { start: number; end: number; + nodeType: StatementNodeType; callback: ScriptLetRestoreCallback; }; @@ -167,6 +170,7 @@ export class ScriptLetContext { `(${part})${isTS ? `as (${typing})` : ""};`, range[0] - 1, this.currentScriptScopeKind, + "ExpressionStatement", (st, tokens, comments, result) => { const exprSt = st as ESTree.ExpressionStatement; const tsAs: TSAsExpression | null = isTS @@ -223,6 +227,7 @@ export class ScriptLetContext { `({${part}});`, range[0] - 2, this.currentScriptScopeKind, + "ExpressionStatement", (st, tokens, _comments, result) => { const exprSt = st as ESTree.ExpressionStatement; const objectExpression: ESTree.ObjectExpression = @@ -262,6 +267,7 @@ export class ScriptLetContext { `const ${part};`, range[0] - 6, this.currentScriptScopeKind, + "VariableDeclaration", (st, tokens, _comments, result) => { const decl = st as ESTree.VariableDeclaration; const node = decl.declarations[0]; @@ -309,6 +315,7 @@ export class ScriptLetContext { scriptLet, ranges.idRange[0] - 5, "generics", + "TSTypeAliasDeclaration", (st, tokens, _comments, result) => { const decl = st as any as TSESTree.TSTypeAliasDeclaration; const id = decl.id; @@ -361,6 +368,7 @@ export class ScriptLetContext { scriptLet, ranges.defaultRange[0] - 5 - id.length - 1, "generics", + "TSTypeAliasDeclaration", (st, tokens, _comments, result) => { const decl = st as any as TSESTree.TSTypeAliasDeclaration; const typeAnnotation = decl.typeAnnotation; @@ -396,6 +404,7 @@ export class ScriptLetContext { `if(${part}){`, range[0] - 3, this.currentScriptScopeKind, + "IfStatement", (st, tokens, _comments, result) => { const ifSt = st as ESTree.IfStatement; const node = ifSt.test; @@ -451,6 +460,7 @@ export class ScriptLetContext { source, exprRange[0] - exprOffset, this.currentScriptScopeKind, + "ExpressionStatement", (st, tokens, comments, result) => { const expSt = st as ESTree.ExpressionStatement; const call = expSt.expression as ESTree.CallExpression; @@ -534,15 +544,18 @@ export class ScriptLetContext { id: ESTree.Identifier, closeParentIndex: number, snippetBlock: SvelteSnippetBlock, - kind: "snippet" | "render", + // If set to null, `currentScriptScopeKind` will be used. + kind: "snippet" | null, callback: (id: ESTree.Identifier, params: ESTree.Pattern[]) => void, ): void { + const scopeKind = kind || this.currentScriptScopeKind; const idRange = getNodeRange(id); const part = this.ctx.code.slice(idRange[0], closeParentIndex + 1); const restore = this.appendScript( `function ${part}{`, idRange[0] - 9, - kind, + scopeKind, + "FunctionDeclaration", (st, tokens, _comments, result) => { const fnDecl = st as ESTree.FunctionDeclaration; const idNode = fnDecl.id; @@ -568,7 +581,7 @@ export class ScriptLetContext { fnDecl.params = []; }, ); - this.pushScope(restore, "}", kind); + this.pushScope(restore, "}", scopeKind); } public nestBlock( @@ -577,7 +590,7 @@ export class ScriptLetContext { | ScriptLetBlockParam[] | ((helper: TypeGenHelper | null) => { param: ScriptLetBlockParam; - preparationScript?: string[]; + preparationScript?: { script: string; nodeType: StatementNodeType }[]; }), ): void { let resolvedParams; @@ -590,8 +603,9 @@ export class ScriptLetContext { if (generatedTypes.preparationScript) { for (const preparationScript of generatedTypes.preparationScript) { this.appendScriptWithoutOffset( - preparationScript, + preparationScript.script, this.currentScriptScopeKind, + preparationScript.nodeType, (node, tokens, comments, result) => { tokens.length = 0; comments.length = 0; @@ -612,6 +626,7 @@ export class ScriptLetContext { `{`, block.range[0], this.currentScriptScopeKind, + "BlockStatement", (st, tokens, _comments, result) => { const blockSt = st as ESTree.BlockStatement; @@ -668,6 +683,7 @@ export class ScriptLetContext { `(${source})=>{`, maps[0].range[0] - 1, this.currentScriptScopeKind, + "ExpressionStatement", (st, tokens, comments, result) => { const exprSt = st as ESTree.ExpressionStatement; const fn = exprSt.expression as ESTree.ArrowFunctionExpression; @@ -742,6 +758,7 @@ export class ScriptLetContext { text: string, offset: number, kind: "generics" | "snippet" | "render", + nodeType: StatementNodeType, callback: ( node: ESTree.Node, tokens: Token[], @@ -752,6 +769,7 @@ export class ScriptLetContext { const resultCallback = this.appendScriptWithoutOffset( text, kind, + nodeType, (node, tokens, comments, result) => { fixLocations( node, @@ -770,6 +788,7 @@ export class ScriptLetContext { private appendScriptWithoutOffset( text: string, kind: "generics" | "snippet" | "render", + nodeType: StatementNodeType, callback: ( node: ESTree.Node, tokens: Token[], @@ -785,6 +804,7 @@ export class ScriptLetContext { const restoreCallback: RestoreCallback = { start: startOffset, end: endOffset, + nodeType, callback, }; this.restoreCallbacks.push(restoreCallback); @@ -918,6 +938,7 @@ export class ScriptLetContext { return; } if ( + orderedRestoreCallback.nodeType === node.type && orderedRestoreCallback.start <= node.range![0] && node.range![1] <= orderedRestoreCallback.end ) { diff --git a/src/parser/converts/block.ts b/src/parser/converts/block.ts index 699f4a21..445ba8f1 100644 --- a/src/parser/converts/block.ts +++ b/src/parser/converts/block.ts @@ -488,7 +488,10 @@ export function convertAwaitBlock( const id = typeCtx.generateUniqueId(expression); return { preparationScript: [ - `const ${id} = ${expression};`, + { + script: `const ${id} = ${expression};`, + nodeType: "VariableDeclaration", + }, generateAwaitThenValueType(idAwaitThenValue), ], param: { @@ -655,7 +658,11 @@ export function convertSnippetBlock( ).end, ); - const scopeKind = parent.type === "Program" ? "snippet" : "render"; + const scopeKind = + parent.type === "Program" + ? "snippet" + : // use currentScriptScopeKind + null; ctx.scriptLet.nestSnippetBlock( node.expression, @@ -735,13 +742,16 @@ function extractMustacheBlockTokens( /** Generate Awaited like type code */ function generateAwaitThenValueType(id: string) { - return `type ${id} = T extends null | undefined + return { + script: `type ${id} = T extends null | undefined ? T : T extends { then(value: infer F): any } ? F extends (value: infer V, ...args: any) => any ? ${id} : never - : T;`; + : T;`, + nodeType: "TSTypeAliasDeclaration" as const, + }; } /** Checks whether the given name identifier is exists or not. */ diff --git a/tests/fixtures/parser/ast/svelte5/snippet02-nesting-input.svelte b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-input.svelte new file mode 100644 index 00000000..29f43492 --- /dev/null +++ b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-input.svelte @@ -0,0 +1,10 @@ + + +{#snippet foo()} + {#snippet bar()} Bar {/snippet} + Foo {@render bar()} +{/snippet} + + diff --git a/tests/fixtures/parser/ast/svelte5/snippet02-nesting-output.json b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-output.json new file mode 100644 index 00000000..3c68cab8 --- /dev/null +++ b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-output.json @@ -0,0 +1,1400 @@ +{ + "type": "Program", + "body": [ + { + "type": "SvelteScriptElement", + "name": { + "type": "SvelteName", + "name": "script", + "range": [ + 1, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + "startTag": { + "type": "SvelteStartTag", + "attributes": [], + "selfClosing": false, + "range": [ + 0, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + "body": [ + { + "type": "ImportDeclaration", + "source": { + "type": "Literal", + "raw": "'$lib/foo.svelte'", + "value": "$lib/foo.svelte", + "range": [ + 26, + 43 + ], + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 34 + } + } + }, + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + } + ], + "range": [ + 10, + 44 + ], + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 35 + } + } + } + ], + "endTag": { + "type": "SvelteEndTag", + "range": [ + 45, + 54 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + "range": [ + 0, + 54 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + { + "type": "SvelteText", + "value": "\n\n", + "range": [ + 54, + 56 + ], + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 5, + "column": 0 + } + } + }, + { + "type": "SvelteSnippetBlock", + "id": { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + }, + "params": [], + "children": [ + { + "type": "SvelteSnippetBlock", + "id": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + }, + "params": [], + "children": [ + { + "type": "SvelteText", + "value": "Bar", + "range": [ + 90, + 95 + ], + "loc": { + "start": { + "line": 6, + "column": 17 + }, + "end": { + "line": 6, + "column": 22 + } + } + } + ], + "range": [ + 74, + 105 + ], + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 32 + } + } + }, + { + "type": "SvelteText", + "value": "\n\tFoo ", + "range": [ + 105, + 111 + ], + "loc": { + "start": { + "line": 6, + "column": 32 + }, + "end": { + "line": 7, + "column": 5 + } + } + }, + { + "type": "SvelteRenderTag", + "expression": { + "type": "CallExpression", + "arguments": [], + "callee": { + "type": "Identifier", + "name": "bar", + "range": [ + 120, + 123 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 17 + } + } + }, + "optional": false, + "range": [ + 120, + 125 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 19 + } + } + }, + "range": [ + 111, + 126 + ], + "loc": { + "start": { + "line": 7, + "column": 5 + }, + "end": { + "line": 7, + "column": 20 + } + } + } + ], + "range": [ + 56, + 137 + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 8, + "column": 10 + } + } + }, + { + "type": "SvelteText", + "value": "\n\n", + "range": [ + 137, + 139 + ], + "loc": { + "start": { + "line": 8, + "column": 10 + }, + "end": { + "line": 10, + "column": 0 + } + } + }, + { + "type": "SvelteElement", + "kind": "component", + "name": { + "type": "Identifier", + "name": "Foo", + "range": [ + 140, + 143 + ], + "loc": { + "start": { + "line": 10, + "column": 1 + }, + "end": { + "line": 10, + "column": 4 + } + } + }, + "startTag": { + "type": "SvelteStartTag", + "attributes": [ + { + "type": "SvelteShorthandAttribute", + "key": { + "type": "Identifier", + "name": "foo", + "range": [ + 145, + 148 + ], + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 9 + } + } + }, + "value": { + "type": "Identifier", + "name": "foo", + "range": [ + 145, + 148 + ], + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 9 + } + } + }, + "range": [ + 144, + 149 + ], + "loc": { + "start": { + "line": 10, + "column": 5 + }, + "end": { + "line": 10, + "column": 10 + } + } + } + ], + "selfClosing": true, + "range": [ + 139, + 152 + ], + "loc": { + "start": { + "line": 10, + "column": 0 + }, + "end": { + "line": 10, + "column": 13 + } + } + }, + "children": [], + "endTag": null, + "range": [ + 139, + 152 + ], + "loc": { + "start": { + "line": 10, + "column": 0 + }, + "end": { + "line": 10, + "column": 13 + } + } + } + ], + "sourceType": "module", + "comments": [], + "tokens": [ + { + "type": "Punctuator", + "value": "<", + "range": [ + 0, + 1 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "HTMLIdentifier", + "value": "script", + "range": [ + 1, + 7 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 7 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 7, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + { + "type": "Keyword", + "value": "import", + "range": [ + 10, + 16 + ], + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 7 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + { + "type": "Identifier", + "value": "from", + "range": [ + 21, + 25 + ], + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 16 + } + } + }, + { + "type": "String", + "value": "'$lib/foo.svelte'", + "range": [ + 26, + 43 + ], + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 34 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 43, + 44 + ], + "loc": { + "start": { + "line": 2, + "column": 34 + }, + "end": { + "line": 2, + "column": 35 + } + } + }, + { + "type": "Punctuator", + "value": "<", + "range": [ + 45, + 46 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + { + "type": "Punctuator", + "value": "/", + "range": [ + 46, + 47 + ], + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 2 + } + } + }, + { + "type": "HTMLIdentifier", + "value": "script", + "range": [ + 47, + 53 + ], + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 53, + 54 + ], + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + { + "type": "HTMLText", + "value": "\n\n", + "range": [ + 54, + 56 + ], + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 5, + "column": 0 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 56, + 57 + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + } + }, + { + "type": "MustacheKeyword", + "value": "#snippet", + "range": [ + 57, + 65 + ], + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 9 + } + } + }, + { + "type": "Identifier", + "value": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 69, + 70 + ], + "loc": { + "start": { + "line": 5, + "column": 13 + }, + "end": { + "line": 5, + "column": 14 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 70, + 71 + ], + "loc": { + "start": { + "line": 5, + "column": 14 + }, + "end": { + "line": 5, + "column": 15 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 71, + 72 + ], + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 5, + "column": 16 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 74, + 75 + ], + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 2 + } + } + }, + { + "type": "MustacheKeyword", + "value": "#snippet", + "range": [ + 75, + 83 + ], + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 10 + } + } + }, + { + "type": "Identifier", + "value": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 87, + 88 + ], + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 15 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 88, + 89 + ], + "loc": { + "start": { + "line": 6, + "column": 15 + }, + "end": { + "line": 6, + "column": 16 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 89, + 90 + ], + "loc": { + "start": { + "line": 6, + "column": 16 + }, + "end": { + "line": 6, + "column": 17 + } + } + }, + { + "type": "HTMLText", + "value": " ", + "range": [ + 90, + 91 + ], + "loc": { + "start": { + "line": 6, + "column": 17 + }, + "end": { + "line": 6, + "column": 18 + } + } + }, + { + "type": "HTMLText", + "value": "Bar", + "range": [ + 91, + 94 + ], + "loc": { + "start": { + "line": 6, + "column": 18 + }, + "end": { + "line": 6, + "column": 21 + } + } + }, + { + "type": "HTMLText", + "value": " ", + "range": [ + 94, + 95 + ], + "loc": { + "start": { + "line": 6, + "column": 21 + }, + "end": { + "line": 6, + "column": 22 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 95, + 96 + ], + "loc": { + "start": { + "line": 6, + "column": 22 + }, + "end": { + "line": 6, + "column": 23 + } + } + }, + { + "type": "MustacheKeyword", + "value": "/snippet", + "range": [ + 96, + 104 + ], + "loc": { + "start": { + "line": 6, + "column": 23 + }, + "end": { + "line": 6, + "column": 31 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 104, + 105 + ], + "loc": { + "start": { + "line": 6, + "column": 31 + }, + "end": { + "line": 6, + "column": 32 + } + } + }, + { + "type": "HTMLText", + "value": "\n\t", + "range": [ + 105, + 107 + ], + "loc": { + "start": { + "line": 6, + "column": 32 + }, + "end": { + "line": 7, + "column": 1 + } + } + }, + { + "type": "HTMLText", + "value": "Foo", + "range": [ + 107, + 110 + ], + "loc": { + "start": { + "line": 7, + "column": 1 + }, + "end": { + "line": 7, + "column": 4 + } + } + }, + { + "type": "HTMLText", + "value": " ", + "range": [ + 110, + 111 + ], + "loc": { + "start": { + "line": 7, + "column": 4 + }, + "end": { + "line": 7, + "column": 5 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 111, + 112 + ], + "loc": { + "start": { + "line": 7, + "column": 5 + }, + "end": { + "line": 7, + "column": 6 + } + } + }, + { + "type": "MustacheKeyword", + "value": "@render", + "range": [ + 112, + 119 + ], + "loc": { + "start": { + "line": 7, + "column": 6 + }, + "end": { + "line": 7, + "column": 13 + } + } + }, + { + "type": "Identifier", + "value": "bar", + "range": [ + 120, + 123 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 17 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 123, + 124 + ], + "loc": { + "start": { + "line": 7, + "column": 17 + }, + "end": { + "line": 7, + "column": 18 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 124, + 125 + ], + "loc": { + "start": { + "line": 7, + "column": 18 + }, + "end": { + "line": 7, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 125, + 126 + ], + "loc": { + "start": { + "line": 7, + "column": 19 + }, + "end": { + "line": 7, + "column": 20 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 127, + 128 + ], + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + } + }, + { + "type": "MustacheKeyword", + "value": "/snippet", + "range": [ + 128, + 136 + ], + "loc": { + "start": { + "line": 8, + "column": 1 + }, + "end": { + "line": 8, + "column": 9 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 136, + 137 + ], + "loc": { + "start": { + "line": 8, + "column": 9 + }, + "end": { + "line": 8, + "column": 10 + } + } + }, + { + "type": "HTMLText", + "value": "\n\n", + "range": [ + 137, + 139 + ], + "loc": { + "start": { + "line": 8, + "column": 10 + }, + "end": { + "line": 10, + "column": 0 + } + } + }, + { + "type": "Punctuator", + "value": "<", + "range": [ + 139, + 140 + ], + "loc": { + "start": { + "line": 10, + "column": 0 + }, + "end": { + "line": 10, + "column": 1 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 140, + 143 + ], + "loc": { + "start": { + "line": 10, + "column": 1 + }, + "end": { + "line": 10, + "column": 4 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 144, + 145 + ], + "loc": { + "start": { + "line": 10, + "column": 5 + }, + "end": { + "line": 10, + "column": 6 + } + } + }, + { + "type": "Identifier", + "value": "foo", + "range": [ + 145, + 148 + ], + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 9 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 148, + 149 + ], + "loc": { + "start": { + "line": 10, + "column": 9 + }, + "end": { + "line": 10, + "column": 10 + } + } + }, + { + "type": "Punctuator", + "value": "/", + "range": [ + 150, + 151 + ], + "loc": { + "start": { + "line": 10, + "column": 11 + }, + "end": { + "line": 10, + "column": 12 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 151, + 152 + ], + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 13 + } + } + } + ], + "range": [ + 0, + 153 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 11, + "column": 0 + } + } +} \ No newline at end of file diff --git a/tests/fixtures/parser/ast/svelte5/snippet02-nesting-scope-output.json b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-scope-output.json new file mode 100644 index 00000000..7953e6fe --- /dev/null +++ b/tests/fixtures/parser/ast/svelte5/snippet02-nesting-scope-output.json @@ -0,0 +1,750 @@ +{ + "type": "global", + "variables": [ + { + "name": "$$slots", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$$props", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$$restProps", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$state", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$derived", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$effect", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$props", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$bindable", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$inspect", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "$host", + "identifiers": [], + "defs": [], + "references": [] + } + ], + "references": [], + "childScopes": [ + { + "type": "module", + "variables": [ + { + "name": "Foo", + "identifiers": [ + { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + } + ], + "defs": [ + { + "type": "ImportBinding", + "name": { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "node": { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + } + } + ], + "references": [ + { + "identifier": { + "type": "Identifier", + "name": "Foo", + "range": [ + 140, + 143 + ], + "loc": { + "start": { + "line": 10, + "column": 1 + }, + "end": { + "line": 10, + "column": 4 + } + } + }, + "from": "module", + "init": null, + "resolved": { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + } + } + ] + }, + { + "name": "foo", + "identifiers": [ + { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + } + ], + "defs": [ + { + "type": "FunctionName", + "name": { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + }, + "node": { + "type": "SvelteSnippetBlock", + "id": { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + }, + "params": [], + "children": [ + { + "type": "SvelteSnippetBlock", + "id": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + }, + "params": [], + "children": [ + { + "type": "SvelteText", + "value": "Bar", + "range": [ + 90, + 95 + ], + "loc": { + "start": { + "line": 6, + "column": 17 + }, + "end": { + "line": 6, + "column": 22 + } + } + } + ], + "range": [ + 74, + 105 + ], + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 32 + } + } + }, + { + "type": "SvelteText", + "value": "\n\tFoo ", + "range": [ + 105, + 111 + ], + "loc": { + "start": { + "line": 6, + "column": 32 + }, + "end": { + "line": 7, + "column": 5 + } + } + }, + { + "type": "SvelteRenderTag", + "expression": { + "type": "CallExpression", + "arguments": [], + "callee": { + "type": "Identifier", + "name": "bar", + "range": [ + 120, + 123 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 17 + } + } + }, + "optional": false, + "range": [ + 120, + 125 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 19 + } + } + }, + "range": [ + 111, + 126 + ], + "loc": { + "start": { + "line": 7, + "column": 5 + }, + "end": { + "line": 7, + "column": 20 + } + } + } + ], + "range": [ + 56, + 137 + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 8, + "column": 10 + } + } + } + } + ], + "references": [ + { + "identifier": { + "type": "Identifier", + "name": "foo", + "range": [ + 145, + 148 + ], + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 9 + } + } + }, + "from": "module", + "init": null, + "resolved": { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + } + } + ] + } + ], + "references": [ + { + "identifier": { + "type": "Identifier", + "name": "foo", + "range": [ + 145, + 148 + ], + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 9 + } + } + }, + "from": "module", + "init": null, + "resolved": { + "type": "Identifier", + "name": "foo", + "range": [ + 66, + 69 + ], + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 13 + } + } + } + }, + { + "identifier": { + "type": "Identifier", + "name": "Foo", + "range": [ + 140, + 143 + ], + "loc": { + "start": { + "line": 10, + "column": 1 + }, + "end": { + "line": 10, + "column": 4 + } + } + }, + "from": "module", + "init": null, + "resolved": { + "type": "Identifier", + "name": "Foo", + "range": [ + 17, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 11 + } + } + } + } + ], + "childScopes": [ + { + "type": "function", + "variables": [ + { + "name": "arguments", + "identifiers": [], + "defs": [], + "references": [] + }, + { + "name": "bar", + "identifiers": [ + { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + } + ], + "defs": [ + { + "type": "FunctionName", + "name": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + }, + "node": { + "type": "SvelteSnippetBlock", + "id": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + }, + "params": [], + "children": [ + { + "type": "SvelteText", + "value": "Bar", + "range": [ + 90, + 95 + ], + "loc": { + "start": { + "line": 6, + "column": 17 + }, + "end": { + "line": 6, + "column": 22 + } + } + } + ], + "range": [ + 74, + 105 + ], + "loc": { + "start": { + "line": 6, + "column": 1 + }, + "end": { + "line": 6, + "column": 32 + } + } + } + } + ], + "references": [ + { + "identifier": { + "type": "Identifier", + "name": "bar", + "range": [ + 120, + 123 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 17 + } + } + }, + "from": "function", + "init": null, + "resolved": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + } + } + ] + } + ], + "references": [ + { + "identifier": { + "type": "Identifier", + "name": "bar", + "range": [ + 120, + 123 + ], + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 17 + } + } + }, + "from": "function", + "init": null, + "resolved": { + "type": "Identifier", + "name": "bar", + "range": [ + 84, + 87 + ], + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 14 + } + } + } + } + ], + "childScopes": [ + { + "type": "function", + "variables": [ + { + "name": "arguments", + "identifiers": [], + "defs": [], + "references": [] + } + ], + "references": [], + "childScopes": [], + "through": [] + } + ], + "through": [] + } + ], + "through": [] + } + ], + "through": [] +} \ No newline at end of file