Skip to content

Commit 02db54d

Browse files
authored
fix: support each without as (#2615)
1 parent 131f78a commit 02db54d

File tree

7 files changed

+114
-10
lines changed

7 files changed

+114
-10
lines changed

packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,11 @@ repository:
260260
patterns:
261261
# Start expression.
262262
- begin: \G\s*?(?=\S)
263-
end: (?=(?:^\s*|\s+)(as))
263+
end: (?=(?:(?:^\s*|\s+)(as))|\s*(}|,))
264264
contentName: meta.embedded.expression.svelte source.ts
265265
patterns: [ include: source.ts ]
266266
# 'as' token and onwards.
267-
- begin: (as)
267+
- begin: (as)|(?=}|,)
268268
beginCaptures: { 1: { name: keyword.control.as.svelte } }
269269
end: (?=})
270270
patterns:

packages/svelte-vscode/test/grammar/samples/each-block/input.svelte

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,19 @@
77
{#each showGroups as [key, items] (key)}
88

99
{/each}
10+
11+
{#each v}
12+
this should be seen as text
13+
{/each}
14+
15+
{#each v }
16+
this should be seen as text
17+
{/each}
18+
19+
{#each v, i}
20+
this should be seen as text
21+
{/each}
22+
23+
{#each v , i}
24+
this should be seen as text
25+
{/each}

packages/svelte-vscode/test/grammar/samples/each-block/input.svelte.snap

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,70 @@
6161
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
6262
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
6363
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
64+
>
65+
>{#each v}
66+
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
67+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
68+
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
69+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
70+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
71+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
72+
> this should be seen as text
73+
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
74+
>{/each}
75+
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
76+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
77+
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
78+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
79+
>
80+
>{#each v }
81+
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
82+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
83+
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
84+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
85+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
86+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
87+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
88+
> this should be seen as text
89+
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
90+
>{/each}
91+
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
92+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
93+
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
94+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
95+
>
96+
>{#each v, i}
97+
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
98+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
99+
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
100+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
101+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
102+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.separator.svelte
103+
# ^^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
104+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
105+
> this should be seen as text
106+
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
107+
>{/each}
108+
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
109+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
110+
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
111+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
112+
>
113+
>{#each v , i}
114+
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
115+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
116+
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
117+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
118+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
119+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
120+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.separator.svelte
121+
# ^^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
122+
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
123+
> this should be seen as text
124+
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
125+
>{/each}
126+
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
127+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
128+
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
129+
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
64130
>

packages/svelte-vscode/test/grammar/test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ async function snapShotTest() {
4848
];
4949

5050
const code = await promisifySpawn(process.platform === 'win32' ? 'npx.cmd' : 'npx', args, {
51-
stdio: 'inherit'
51+
stdio: 'inherit',
52+
// https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2#command-injection-via-args-parameter-of-child_processspawn-without-shell-option-enabled-on-windows-cve-2024-27980---high
53+
shell: true
5254
});
5355

5456
if (code > 0) {

packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,44 @@ import { getEnd, transform, TransformationArray } from '../utils/node-utils';
2121
* `ensureArray` will error that there are more args than expected
2222
*/
2323
export function handleEach(str: MagicString, eachBlock: BaseNode): void {
24-
const startEnd = str.original.indexOf('}', eachBlock.key?.end || eachBlock.context.end) + 1;
24+
const startEnd =
25+
str.original.indexOf(
26+
'}',
27+
eachBlock.key?.end || eachBlock.context?.end || eachBlock.expression.end
28+
) + 1;
2529
let transforms: TransformationArray;
2630
// {#each true, [1,2]} is valid but for (const x of true, [1,2]) is not if not wrapped with braces
2731
const containsComma = str.original
2832
.substring(eachBlock.expression.start, eachBlock.expression.end)
2933
.includes(',');
3034
const expressionEnd = getEnd(eachBlock.expression);
31-
const contextEnd = getEnd(eachBlock.context);
35+
const contextEnd = eachBlock.context && getEnd(eachBlock.context);
3236
const arrayAndItemVarTheSame =
37+
!!eachBlock.context &&
3338
str.original.substring(eachBlock.expression.start, expressionEnd) ===
34-
str.original.substring(eachBlock.context.start, contextEnd);
39+
str.original.substring(eachBlock.context.start, contextEnd);
3540
if (arrayAndItemVarTheSame) {
3641
transforms = [
3742
`{ const $$_each = __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
3843
[eachBlock.expression.start, eachBlock.expression.end],
3944
`${containsComma ? ')' : ''}); for(let `,
40-
[eachBlock.context.start, contextEnd],
45+
[eachBlock.context!.start, contextEnd!],
4146
' of $$_each){'
4247
];
4348
} else {
4449
transforms = [
4550
'for(let ',
46-
[eachBlock.context.start, contextEnd],
51+
eachBlock.context ? [eachBlock.context.start, contextEnd] : '$$each_item',
4752
` of __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
4853
[eachBlock.expression.start, eachBlock.expression.end],
49-
`${containsComma ? ')' : ''})){`
54+
`${containsComma ? ')' : ''})){${eachBlock.context ? '' : '$$each_item;'}`
5055
];
5156
}
5257
if (eachBlock.index) {
53-
const indexStart = str.original.indexOf(eachBlock.index, eachBlock.context.end);
58+
const indexStart = str.original.indexOf(
59+
eachBlock.index,
60+
eachBlock.context?.end || eachBlock.expression.end
61+
);
5462
const indexEnd = indexStart + eachBlock.index.length;
5563
transforms.push('let ', [indexStart, indexEnd], ' = 1;');
5664
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
for(let $$each_item of __sveltets_2_ensureArray({ length: 5 })){$$each_item; }
2+
3+
for(let $$each_item of __sveltets_2_ensureArray({ length: 5 })){$$each_item;let index = 1;
4+
index;
5+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{#each { length: 5 }}
2+
hi
3+
{/each}
4+
5+
{#each { length: 5 }, index}
6+
{index}
7+
{/each}

0 commit comments

Comments
 (0)