Skip to content

Commit

Permalink
fix: handle updated @render tag AST shape
Browse files Browse the repository at this point in the history
fixes #428
  • Loading branch information
dummdidumm committed Feb 14, 2024
1 parent c8317eb commit 96049c6
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# prettier-plugin-svelte changelog

## 3.2.1

- (fix) handle updated `@render` tag AST shape

## 3.2.0

- (feat) format JSON script tags
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "prettier-plugin-svelte",
"version": "3.2.0",
"version": "3.2.1",
"description": "Svelte plugin for prettier",
"main": "plugin.js",
"files": [
Expand Down
42 changes: 29 additions & 13 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
isTypeScript,
printRaw,
} from './print/node-helpers';
import { CommentNode, ElementNode, Node, ScriptNode, StyleNode } from './print/nodes';
import { BaseNode, CommentNode, ElementNode, Node, ScriptNode, StyleNode } from './print/nodes';
import { extractAttributes } from './lib/extractAttributes';
import { base64ToString } from './base64-string';

Expand Down Expand Up @@ -105,7 +105,8 @@ export function embed(path: FastPath, _options: Options) {
) + 1;
parent.context = null;
parent.parameters = null;
printSvelteBlockJS('expression');
node.isJS = true;
node.asFunction = true;
}
break;
case 'Element':
Expand All @@ -129,7 +130,9 @@ export function embed(path: FastPath, _options: Options) {
parent.expression.end =
options.originalText.indexOf(
')',
parent.argument?.end ?? parent.expression.end,
parent.argument?.end ?? // TODO: remove at some point, snippet API changed in .next-..
parent.arguments?.[parent.arguments.length - 1]?.end ??
parent.expression.end,
) + 1;
parent.argument = null;
printJS(parent, false, false, false, 'expression');
Expand Down Expand Up @@ -157,14 +160,14 @@ export function embed(path: FastPath, _options: Options) {
// so we need to have another public parser and defer to that
parser: 'svelteExpressionParser',
singleQuote: node.forceSingleQuote ? true : options.singleQuote,
_svelte_asFunction: node.asFunction,
};

// If we have snipped content, it was done wrongly and we need to unsnip it.
// This happens for example for {@html `<script>{foo}</script>`}
const text = getText(node, options, true);
let docs = await textToDoc(
forceIntoExpression(
// If we have snipped content, it was done wrongly and we need to unsnip it.
// This happens for example for {@html `<script>{foo}</script>`}
getText(node, options, true),
),
node.asFunction ? forceIntoFunction(text) : forceIntoExpression(text),
embeddedOptions,
);
if (node.forceSingleLine) {
Expand All @@ -173,6 +176,14 @@ export function embed(path: FastPath, _options: Options) {
if (node.removeParentheses) {
docs = removeParentheses(docs);
}
if (node.asFunction) {
if (Array.isArray(docs) && typeof docs[0] === 'string') {
docs[0] = docs[0].replace('function ', '');
docs.splice(-1, 1);
} else {
throw new Error('Prettier AST changed, asFunction logic needs to change');
}
}
return docs;
} catch (e) {
return getText(node, options, true);
Expand Down Expand Up @@ -240,6 +251,10 @@ function forceIntoExpression(statement: string) {
return `(${statement}\n)`;
}

function forceIntoFunction(statement: string) {
return `function ${statement} {}`;
}

function preformattedBody(str: string): Doc {
if (!str) {
return '';
Expand Down Expand Up @@ -382,11 +397,12 @@ function printJS(
removeParentheses: boolean,
name: string,
) {
if (!node[name] || typeof node[name] !== 'object') {
const part = node[name] as BaseNode | undefined;
if (!part || typeof part !== 'object') {
return;
}
node[name].isJS = true;
node[name].forceSingleQuote = forceSingleQuote;
node[name].forceSingleLine = forceSingleLine;
node[name].removeParentheses = removeParentheses;
part.isJS = true;
part.forceSingleQuote = forceSingleQuote;
part.forceSingleLine = forceSingleLine;
part.removeParentheses = removeParentheses;
}
7 changes: 6 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ export const parsers: Record<string, Parser> = {
parse: (text: string, options: any) => {
const ast = babelParser.parse(text, options);

return { ...ast, program: ast.program.body[0].expression };
let program = ast.program.body[0];
if (!options._svelte_asFunction) {
program = program.expression;
}

return { ...ast, program };
},
},
};
Expand Down
9 changes: 8 additions & 1 deletion src/print/nodes.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
export interface BaseNode {
start: number;
end: number;
/** Whether this node is JS (not HTML/Svelte stuff) */
isJS?: boolean;
/** Whether or not to print this node as a function */
asFunction?: boolean;
/** Whether or not to force single quotes when printing as JS */
forceSingleQuote?: boolean;
/** Whether or not to force a single line when printing as JS */
forceSingleLine?: boolean;
/** Whether or not to remove outer `()` when printing as JS */
removeParentheses?: boolean;
}

Expand Down Expand Up @@ -302,7 +308,8 @@ export interface SnippetBlock extends BaseNode {
export interface RenderTag extends BaseNode {
type: 'RenderTag';
expression: IdentifierNode;
argument: null | any;
argument?: BaseNode | null;
arguments: BaseNode[] | null;
}

export type Node =
Expand Down
22 changes: 22 additions & 0 deletions test/printer/samples/snippet.html.skip
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,27 @@
<p>bar</p>
{/snippet}

{#snippet baz(a, b, c = 1)}
<p>baz</p>
{/snippet}

<div>
{#snippet loooongFunction(
a,
lot,
_of,
parameters,
that,
make,
the,
lines,
_break,
)}
<p>baz</p>
{/snippet}
</div>

{@render foo()}
{@render bar(x)}
{@render test((() => "a")())}
{@render test(t())}

0 comments on commit 96049c6

Please sign in to comment.