fix: allow leading and trailing comments in mustache tag (#11866)

Fixes #7456

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/12450/head
BlueGreenMagick 2 months ago committed by GitHub
parent a8dc96eb43
commit 81ed425b5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: allow leading and trailing comments in mustache expression

@ -129,6 +129,11 @@ function transform(name, dest) {
}
});
if (comments.length > 0) {
// @ts-expect-error
(ast.trailingComments ||= []).push(...comments);
}
const category = messages[name];
// find the `export function CODE` node

@ -30,6 +30,7 @@ export function parse(source, typescript) {
* @param {string} source
* @param {boolean} typescript
* @param {number} index
* @returns {acorn.Expression & { leadingComments?: CommentWithLocation[]; trailingComments?: CommentWithLocation[]; }}
*/
export function parse_expression_at(source, typescript, index) {
const parser = typescript ? ParserWithTS : acorn.Parser;
@ -92,7 +93,7 @@ function get_comment_handlers(source) {
if (comments.length === 0) return;
walk(ast, null, {
_(node, { next }) {
_(node, { next, path }) {
let comment;
while (comments[0] && comments[0].start < node.start) {
@ -103,14 +104,20 @@ function get_comment_handlers(source) {
next();
if (comments[0]) {
const slice = source.slice(node.end, comments[0].start);
const parent = path.at(-1);
if (parent === undefined || node.end !== parent.end) {
const slice = source.slice(node.end, comments[0].start);
if (/^[,) \t]*$/.test(slice)) {
node.trailingComments = [/** @type {CommentWithLocation} */ (comments.shift())];
if (/^[,) \t]*$/.test(slice)) {
node.trailingComments = [/** @type {CommentWithLocation} */ (comments.shift())];
}
}
}
}
});
if (comments.length > 0) {
(ast.trailingComments ||= []).push(...comments.splice(0));
}
}
};
}

@ -17,6 +17,10 @@ export default function read_expression(parser) {
}
let index = /** @type {number} */ (node.end);
if (node.trailingComments !== undefined && node.trailingComments.length > 0) {
index = node.trailingComments.at(-1).end;
}
while (num_parens > 0) {
const char = parser.template[index];

@ -15,9 +15,14 @@ export default function tag(parser) {
parser.allow_whitespace();
if (parser.eat('#')) return open(parser);
if (parser.eat('/')) return close(parser);
if (parser.eat(':')) return next(parser);
if (parser.eat('@')) return special(parser);
if (parser.match('/')) {
if (!parser.match('/*') && !parser.match('//')) {
parser.eat('/');
return close(parser);
}
}
const expression = read_expression(parser);

@ -1,6 +1,7 @@
<script>
// a leading comment
const a = true; // a trailing comment
const a = 1; // a trailing comment
const b = 2;
/** a comment */
function asd() {
@ -14,4 +15,10 @@
/* another comment */
fn();
}}
></button>
>
{/* leading block comment */ a}
</button>
{ // leading line comment
a + b // trailing line comment
/* trailing block comment */
}

@ -1,39 +1,39 @@
{
"html": {
"type": "Fragment",
"start": 122,
"end": 207,
"start": 133,
"end": 341,
"children": [
{
"type": "Text",
"start": 120,
"end": 122,
"start": 131,
"end": 133,
"raw": "\n\n",
"data": "\n\n"
},
{
"type": "Element",
"start": 122,
"end": 207,
"start": 133,
"end": 251,
"name": "button",
"attributes": [
{
"start": 131,
"end": 196,
"start": 142,
"end": 207,
"type": "EventHandler",
"name": "click",
"modifiers": [],
"expression": {
"type": "ArrowFunctionExpression",
"start": 153,
"end": 195,
"start": 164,
"end": 206,
"loc": {
"start": {
"line": 13,
"line": 14,
"column": 1
},
"end": {
"line": 16,
"line": 17,
"column": 2
}
},
@ -44,58 +44,58 @@
"params": [],
"body": {
"type": "BlockStatement",
"start": 159,
"end": 195,
"start": 170,
"end": 206,
"loc": {
"start": {
"line": 13,
"line": 14,
"column": 7
},
"end": {
"line": 16,
"line": 17,
"column": 2
}
},
"body": [
{
"type": "ExpressionStatement",
"start": 187,
"end": 192,
"start": 198,
"end": 203,
"loc": {
"start": {
"line": 15,
"line": 16,
"column": 2
},
"end": {
"line": 15,
"line": 16,
"column": 7
}
},
"expression": {
"type": "CallExpression",
"start": 187,
"end": 191,
"start": 198,
"end": 202,
"loc": {
"start": {
"line": 15,
"line": 16,
"column": 2
},
"end": {
"line": 15,
"line": 16,
"column": 6
}
},
"callee": {
"type": "Identifier",
"start": 187,
"end": 189,
"start": 198,
"end": 200,
"loc": {
"start": {
"line": 15,
"line": 16,
"column": 2
},
"end": {
"line": 15,
"line": 16,
"column": 4
}
},
@ -108,8 +108,8 @@
{
"type": "Block",
"value": " another comment ",
"start": 163,
"end": 184
"start": 174,
"end": 195
}
]
}
@ -119,33 +119,159 @@
{
"type": "Line",
"value": " comment",
"start": 141,
"end": 151
"start": 152,
"end": 162
}
]
}
}
],
"children": []
"children": [
{
"type": "Text",
"start": 209,
"end": 210,
"raw": "\n",
"data": "\n"
},
{
"type": "MustacheTag",
"start": 210,
"end": 241,
"expression": {
"type": "Identifier",
"start": 239,
"end": 240,
"loc": {
"start": {
"line": 19,
"column": 29
},
"end": {
"line": 19,
"column": 30
}
},
"name": "a",
"leadingComments": [
{
"type": "Block",
"value": " leading block comment ",
"start": 211,
"end": 238
}
]
}
},
{
"type": "Text",
"start": 241,
"end": 242,
"raw": "\n",
"data": "\n"
}
]
},
{
"type": "Text",
"start": 251,
"end": 252,
"raw": "\n",
"data": "\n"
},
{
"type": "MustacheTag",
"start": 252,
"end": 341,
"expression": {
"type": "BinaryExpression",
"start": 279,
"end": 284,
"loc": {
"start": {
"line": 22,
"column": 1
},
"end": {
"line": 22,
"column": 6
}
},
"left": {
"type": "Identifier",
"start": 279,
"end": 280,
"loc": {
"start": {
"line": 22,
"column": 1
},
"end": {
"line": 22,
"column": 2
}
},
"name": "a"
},
"operator": "+",
"right": {
"type": "Identifier",
"start": 283,
"end": 284,
"loc": {
"start": {
"line": 22,
"column": 5
},
"end": {
"line": 22,
"column": 6
}
},
"name": "b"
},
"leadingComments": [
{
"type": "Line",
"value": " leading line comment",
"start": 254,
"end": 277
}
],
"trailingComments": [
{
"type": "Line",
"value": " trailing line comment",
"start": 285,
"end": 309
},
{
"type": "Block",
"value": " trailing block comment ",
"start": 311,
"end": 339
}
]
}
}
]
},
"instance": {
"type": "Script",
"start": 0,
"end": 120,
"end": 131,
"context": "default",
"content": {
"type": "Program",
"start": 8,
"end": 111,
"end": 122,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 9,
"line": 10,
"column": 0
}
},
@ -153,7 +279,7 @@
{
"type": "VariableDeclaration",
"start": 32,
"end": 47,
"end": 44,
"loc": {
"start": {
"line": 3,
@ -161,14 +287,14 @@
},
"end": {
"line": 3,
"column": 16
"column": 13
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 38,
"end": 46,
"end": 43,
"loc": {
"start": {
"line": 3,
@ -176,7 +302,7 @@
},
"end": {
"line": 3,
"column": 15
"column": 12
}
},
"id": {
@ -198,7 +324,7 @@
"init": {
"type": "Literal",
"start": 42,
"end": 46,
"end": 43,
"loc": {
"start": {
"line": 3,
@ -206,11 +332,11 @@
},
"end": {
"line": 3,
"column": 15
"column": 12
}
},
"value": true,
"raw": "true"
"value": 1,
"raw": "1"
}
}
],
@ -227,36 +353,102 @@
{
"type": "Line",
"value": " a trailing comment",
"start": 48,
"end": 69
"start": 45,
"end": 66
}
]
},
{
"type": "VariableDeclaration",
"start": 68,
"end": 80,
"loc": {
"start": {
"line": 4,
"column": 1
},
"end": {
"line": 4,
"column": 13
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 74,
"end": 79,
"loc": {
"start": {
"line": 4,
"column": 7
},
"end": {
"line": 4,
"column": 12
}
},
"id": {
"type": "Identifier",
"start": 74,
"end": 75,
"loc": {
"start": {
"line": 4,
"column": 7
},
"end": {
"line": 4,
"column": 8
}
},
"name": "b"
},
"init": {
"type": "Literal",
"start": 78,
"end": 79,
"loc": {
"start": {
"line": 4,
"column": 11
},
"end": {
"line": 4,
"column": 12
}
},
"value": 2,
"raw": "2"
}
}
],
"kind": "const"
},
{
"type": "FunctionDeclaration",
"start": 90,
"end": 110,
"start": 101,
"end": 121,
"loc": {
"start": {
"line": 6,
"line": 7,
"column": 1
},
"end": {
"line": 8,
"line": 9,
"column": 2
}
},
"id": {
"type": "Identifier",
"start": 99,
"end": 102,
"start": 110,
"end": 113,
"loc": {
"start": {
"line": 6,
"line": 7,
"column": 10
},
"end": {
"line": 6,
"line": 7,
"column": 13
}
},
@ -268,15 +460,15 @@
"params": [],
"body": {
"type": "BlockStatement",
"start": 105,
"end": 110,
"start": 116,
"end": 121,
"loc": {
"start": {
"line": 6,
"line": 7,
"column": 16
},
"end": {
"line": 8,
"line": 9,
"column": 2
}
},
@ -286,8 +478,8 @@
{
"type": "Block",
"value": "* a comment ",
"start": 72,
"end": 88
"start": 83,
"end": 99
}
]
}

Loading…
Cancel
Save