Skip to content

Commit 96049c6

Browse files
committed
fix: handle updated @render tag AST shape
fixes #428
1 parent c8317eb commit 96049c6

File tree

7 files changed

+72
-18
lines changed

7 files changed

+72
-18
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# prettier-plugin-svelte changelog
22

3+
## 3.2.1
4+
5+
- (fix) handle updated `@render` tag AST shape
6+
37
## 3.2.0
48

59
- (feat) format JSON script tags

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "prettier-plugin-svelte",
3-
"version": "3.2.0",
3+
"version": "3.2.1",
44
"description": "Svelte plugin for prettier",
55
"main": "plugin.js",
66
"files": [

src/embed.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
isTypeScript,
2020
printRaw,
2121
} from './print/node-helpers';
22-
import { CommentNode, ElementNode, Node, ScriptNode, StyleNode } from './print/nodes';
22+
import { BaseNode, CommentNode, ElementNode, Node, ScriptNode, StyleNode } from './print/nodes';
2323
import { extractAttributes } from './lib/extractAttributes';
2424
import { base64ToString } from './base64-string';
2525

@@ -105,7 +105,8 @@ export function embed(path: FastPath, _options: Options) {
105105
) + 1;
106106
parent.context = null;
107107
parent.parameters = null;
108-
printSvelteBlockJS('expression');
108+
node.isJS = true;
109+
node.asFunction = true;
109110
}
110111
break;
111112
case 'Element':
@@ -129,7 +130,9 @@ export function embed(path: FastPath, _options: Options) {
129130
parent.expression.end =
130131
options.originalText.indexOf(
131132
')',
132-
parent.argument?.end ?? parent.expression.end,
133+
parent.argument?.end ?? // TODO: remove at some point, snippet API changed in .next-..
134+
parent.arguments?.[parent.arguments.length - 1]?.end ??
135+
parent.expression.end,
133136
) + 1;
134137
parent.argument = null;
135138
printJS(parent, false, false, false, 'expression');
@@ -157,14 +160,14 @@ export function embed(path: FastPath, _options: Options) {
157160
// so we need to have another public parser and defer to that
158161
parser: 'svelteExpressionParser',
159162
singleQuote: node.forceSingleQuote ? true : options.singleQuote,
163+
_svelte_asFunction: node.asFunction,
160164
};
161165

166+
// If we have snipped content, it was done wrongly and we need to unsnip it.
167+
// This happens for example for {@html `<script>{foo}</script>`}
168+
const text = getText(node, options, true);
162169
let docs = await textToDoc(
163-
forceIntoExpression(
164-
// If we have snipped content, it was done wrongly and we need to unsnip it.
165-
// This happens for example for {@html `<script>{foo}</script>`}
166-
getText(node, options, true),
167-
),
170+
node.asFunction ? forceIntoFunction(text) : forceIntoExpression(text),
168171
embeddedOptions,
169172
);
170173
if (node.forceSingleLine) {
@@ -173,6 +176,14 @@ export function embed(path: FastPath, _options: Options) {
173176
if (node.removeParentheses) {
174177
docs = removeParentheses(docs);
175178
}
179+
if (node.asFunction) {
180+
if (Array.isArray(docs) && typeof docs[0] === 'string') {
181+
docs[0] = docs[0].replace('function ', '');
182+
docs.splice(-1, 1);
183+
} else {
184+
throw new Error('Prettier AST changed, asFunction logic needs to change');
185+
}
186+
}
176187
return docs;
177188
} catch (e) {
178189
return getText(node, options, true);
@@ -240,6 +251,10 @@ function forceIntoExpression(statement: string) {
240251
return `(${statement}\n)`;
241252
}
242253

254+
function forceIntoFunction(statement: string) {
255+
return `function ${statement} {}`;
256+
}
257+
243258
function preformattedBody(str: string): Doc {
244259
if (!str) {
245260
return '';
@@ -382,11 +397,12 @@ function printJS(
382397
removeParentheses: boolean,
383398
name: string,
384399
) {
385-
if (!node[name] || typeof node[name] !== 'object') {
400+
const part = node[name] as BaseNode | undefined;
401+
if (!part || typeof part !== 'object') {
386402
return;
387403
}
388-
node[name].isJS = true;
389-
node[name].forceSingleQuote = forceSingleQuote;
390-
node[name].forceSingleLine = forceSingleLine;
391-
node[name].removeParentheses = removeParentheses;
404+
part.isJS = true;
405+
part.forceSingleQuote = forceSingleQuote;
406+
part.forceSingleLine = forceSingleLine;
407+
part.removeParentheses = removeParentheses;
392408
}

src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ export const parsers: Record<string, Parser> = {
6464
parse: (text: string, options: any) => {
6565
const ast = babelParser.parse(text, options);
6666

67-
return { ...ast, program: ast.program.body[0].expression };
67+
let program = ast.program.body[0];
68+
if (!options._svelte_asFunction) {
69+
program = program.expression;
70+
}
71+
72+
return { ...ast, program };
6873
},
6974
},
7075
};

src/print/nodes.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
export interface BaseNode {
22
start: number;
33
end: number;
4+
/** Whether this node is JS (not HTML/Svelte stuff) */
45
isJS?: boolean;
6+
/** Whether or not to print this node as a function */
7+
asFunction?: boolean;
8+
/** Whether or not to force single quotes when printing as JS */
59
forceSingleQuote?: boolean;
10+
/** Whether or not to force a single line when printing as JS */
611
forceSingleLine?: boolean;
12+
/** Whether or not to remove outer `()` when printing as JS */
713
removeParentheses?: boolean;
814
}
915

@@ -302,7 +308,8 @@ export interface SnippetBlock extends BaseNode {
302308
export interface RenderTag extends BaseNode {
303309
type: 'RenderTag';
304310
expression: IdentifierNode;
305-
argument: null | any;
311+
argument?: BaseNode | null;
312+
arguments: BaseNode[] | null;
306313
}
307314

308315
export type Node =

test/printer/samples/snippet.html.skip

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,27 @@
66
<p>bar</p>
77
{/snippet}
88

9+
{#snippet baz(a, b, c = 1)}
10+
<p>baz</p>
11+
{/snippet}
12+
13+
<div>
14+
{#snippet loooongFunction(
15+
a,
16+
lot,
17+
_of,
18+
parameters,
19+
that,
20+
make,
21+
the,
22+
lines,
23+
_break,
24+
)}
25+
<p>baz</p>
26+
{/snippet}
27+
</div>
28+
929
{@render foo()}
1030
{@render bar(x)}
31+
{@render test((() => "a")())}
32+
{@render test(t())}

0 commit comments

Comments
 (0)