Skip to content

Commit

Permalink
fix: support each without as (#2615)
Browse files Browse the repository at this point in the history
  • Loading branch information
dummdidumm authored Dec 3, 2024
1 parent 131f78a commit 02db54d
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 10 deletions.
4 changes: 2 additions & 2 deletions packages/svelte-vscode/syntaxes/svelte.tmLanguage.src.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,11 @@ repository:
patterns:
# Start expression.
- begin: \G\s*?(?=\S)
end: (?=(?:^\s*|\s+)(as))
end: (?=(?:(?:^\s*|\s+)(as))|\s*(}|,))
contentName: meta.embedded.expression.svelte source.ts
patterns: [ include: source.ts ]
# 'as' token and onwards.
- begin: (as)
- begin: (as)|(?=}|,)
beginCaptures: { 1: { name: keyword.control.as.svelte } }
end: (?=})
patterns:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@
{#each showGroups as [key, items] (key)}

{/each}

{#each v}
this should be seen as text
{/each}

{#each v }
this should be seen as text
{/each}

{#each v, i}
this should be seen as text
{/each}

{#each v , i}
this should be seen as text
{/each}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,70 @@
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
>
>{#each v}
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
> this should be seen as text
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
>{/each}
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
>
>{#each v }
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
> this should be seen as text
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
>{/each}
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
>
>{#each v, i}
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.separator.svelte
# ^^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
> this should be seen as text
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
>{/each}
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
>
>{#each v , i}
#^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.start.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.separator.svelte
# ^^ source.svelte meta.special.each.svelte meta.special.start.svelte meta.embedded.expression.svelte source.ts
# ^ source.svelte meta.special.each.svelte meta.special.start.svelte punctuation.definition.block.end.svelte
> this should be seen as text
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.svelte text.svelte
>{/each}
#^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.begin.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.keyword.svelte
# ^^^^ source.svelte meta.special.each.svelte meta.special.end.svelte keyword.control.svelte
# ^ source.svelte meta.special.each.svelte meta.special.end.svelte punctuation.definition.block.end.svelte
>
4 changes: 3 additions & 1 deletion packages/svelte-vscode/test/grammar/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ async function snapShotTest() {
];

const code = await promisifySpawn(process.platform === 'win32' ? 'npx.cmd' : 'npx', args, {
stdio: 'inherit'
stdio: 'inherit',
// 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
shell: true
});

if (code > 0) {
Expand Down
22 changes: 15 additions & 7 deletions packages/svelte2tsx/src/htmlxtojsx_v2/nodes/EachBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,44 @@ import { getEnd, transform, TransformationArray } from '../utils/node-utils';
* `ensureArray` will error that there are more args than expected
*/
export function handleEach(str: MagicString, eachBlock: BaseNode): void {
const startEnd = str.original.indexOf('}', eachBlock.key?.end || eachBlock.context.end) + 1;
const startEnd =
str.original.indexOf(
'}',
eachBlock.key?.end || eachBlock.context?.end || eachBlock.expression.end
) + 1;
let transforms: TransformationArray;
// {#each true, [1,2]} is valid but for (const x of true, [1,2]) is not if not wrapped with braces
const containsComma = str.original
.substring(eachBlock.expression.start, eachBlock.expression.end)
.includes(',');
const expressionEnd = getEnd(eachBlock.expression);
const contextEnd = getEnd(eachBlock.context);
const contextEnd = eachBlock.context && getEnd(eachBlock.context);
const arrayAndItemVarTheSame =
!!eachBlock.context &&
str.original.substring(eachBlock.expression.start, expressionEnd) ===
str.original.substring(eachBlock.context.start, contextEnd);
str.original.substring(eachBlock.context.start, contextEnd);
if (arrayAndItemVarTheSame) {
transforms = [
`{ const $$_each = __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
[eachBlock.expression.start, eachBlock.expression.end],
`${containsComma ? ')' : ''}); for(let `,
[eachBlock.context.start, contextEnd],
[eachBlock.context!.start, contextEnd!],
' of $$_each){'
];
} else {
transforms = [
'for(let ',
[eachBlock.context.start, contextEnd],
eachBlock.context ? [eachBlock.context.start, contextEnd] : '$$each_item',
` of __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
[eachBlock.expression.start, eachBlock.expression.end],
`${containsComma ? ')' : ''})){`
`${containsComma ? ')' : ''})){${eachBlock.context ? '' : '$$each_item;'}`
];
}
if (eachBlock.index) {
const indexStart = str.original.indexOf(eachBlock.index, eachBlock.context.end);
const indexStart = str.original.indexOf(
eachBlock.index,
eachBlock.context?.end || eachBlock.expression.end
);
const indexEnd = indexStart + eachBlock.index.length;
transforms.push('let ', [indexStart, indexEnd], ' = 1;');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
for(let $$each_item of __sveltets_2_ensureArray({ length: 5 })){$$each_item; }

for(let $$each_item of __sveltets_2_ensureArray({ length: 5 })){$$each_item;let index = 1;
index;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{#each { length: 5 }}
hi
{/each}

{#each { length: 5 }, index}
{index}
{/each}

0 comments on commit 02db54d

Please sign in to comment.