Skip to content

Commit

Permalink
feat: add support {#each} without as (svelte v5.4.0) (#617)
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi authored Dec 9, 2024
1 parent 1cede6c commit 1e0b874
Show file tree
Hide file tree
Showing 17 changed files with 4,071 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/witty-hairs-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-eslint-parser": minor
---

feat: add support `{#each}` without `as` (svelte v5.4.0)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"prettier-plugin-svelte": "^3.3.2",
"rimraf": "^6.0.1",
"semver": "^7.6.3",
"svelte": "^5.3.1",
"svelte": "^5.9.0",
"svelte2tsx": "^0.7.28",
"tsx": "^4.19.2",
"typescript": "~5.7.2",
Expand Down
2 changes: 1 addition & 1 deletion src/ast/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ export interface SvelteElseBlockElseIf extends BaseSvelteElseBlock {
export interface SvelteEachBlock extends BaseNode {
type: "SvelteEachBlock";
expression: ESTree.Expression;
context: ESTree.Pattern;
context: ESTree.Pattern | null;
index: ESTree.Identifier | null;
key: ESTree.Expression | null;
children: Child[];
Expand Down
32 changes: 23 additions & 9 deletions src/context/script-let.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,22 +433,26 @@ export class ScriptLetContext {

public nestEachBlock(
expression: ESTree.Expression,
context: ESTree.Pattern,
context: ESTree.Pattern | null,
indexRange: { start: number; end: number } | null,
eachBlock: SvelteEachBlock,
callback: (
expr: ESTree.Expression,
ctx: ESTree.Pattern,
ctx: ESTree.Pattern | null,
index: ESTree.Identifier | null,
) => void,
): void {
const exprRange = getNodeRange(expression);
const ctxRange = getNodeRange(context);
const ctxRange = context && getNodeRange(context);
let source = "Array.from(";
const exprOffset = source.length;
source += `${this.ctx.code.slice(...exprRange)}).forEach((`;
const ctxOffset = source.length;
source += this.ctx.code.slice(...ctxRange);
if (ctxRange) {
source += this.ctx.code.slice(...ctxRange);
} else {
source += "__$ctx__";
}
let idxOffset: number | null = null;
if (indexRange) {
source += ",";
Expand All @@ -473,7 +477,7 @@ export class ScriptLetContext {
const scope = result.getScope(fn.body);

// Process for nodes
callback(expr, ctx, idx);
callback(expr, context ? ctx : null, idx);

// Process for scope
result.registerNodeToScope(eachBlock, scope);
Expand All @@ -484,6 +488,10 @@ export class ScriptLetContext {
}
}
}
if (!context) {
// remove `__$ctx__` variable
removeIdentifierVariable(ctx, scope);
}
// remove Array reference
const arrayId = (callArrayFrom.callee as ESTree.MemberExpression)
.object;
Expand Down Expand Up @@ -512,18 +520,24 @@ export class ScriptLetContext {
tokens.pop(); // )
tokens.pop(); // ;

const map = [
const map: {
offset: number;
range: [number, number];
newNode: ESTree.Expression | ESTree.Pattern;
}[] = [
{
offset: exprOffset,
range: exprRange,
newNode: expr,
},
{
];
if (ctxRange) {
map.push({
offset: ctxOffset,
range: ctxRange,
newNode: ctx,
},
];
});
}
if (indexRange) {
map.push({
offset: idxOffset!,
Expand Down
21 changes: 13 additions & 8 deletions src/parser/converts/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export function convertEachBlock(
const eachBlock: SvelteEachBlock = {
type: "SvelteEachBlock",
expression: null as any,
context: null as any,
context: null,
index: null,
key: null,
children: [],
Expand All @@ -281,7 +281,10 @@ export function convertEachBlock(
let indexRange: null | { start: number; end: number } = null;

if (node.index) {
const start = ctx.code.indexOf(node.index, getWithLoc(node.context).end);
const start = ctx.code.indexOf(
node.index,
getWithLoc(node.context ?? node.expression).end,
);
indexRange = {
start,
end: start + node.index.length,
Expand All @@ -300,11 +303,13 @@ export function convertEachBlock(
},
);

const asStart = ctx.code.indexOf("as", getWithLoc(node.expression).end);
ctx.addToken("Keyword", {
start: asStart,
end: asStart + 2,
});
if (node.context) {
const asStart = ctx.code.indexOf("as", getWithLoc(node.expression).end);
ctx.addToken("Keyword", {
start: asStart,
end: asStart + 2,
});
}

if (node.key) {
ctx.scriptLet.addExpression(node.key, eachBlock, null, (key) => {
Expand Down Expand Up @@ -335,7 +340,7 @@ export function convertEachBlock(
const elseStart = startBlockIndexForElse(
fallbackFragment,
body,
node.key || indexRange || node.context,
node.key || indexRange || node.context || node.expression,
ctx,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{#each expression}...{/each}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"ruleId": "no-undef",
"code": "expression",
"line": 1,
"column": 8
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
{
"type": "Program",
"body": [
{
"type": "SvelteEachBlock",
"expression": {
"type": "Identifier",
"name": "expression",
"range": [
7,
17
],
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 17
}
}
},
"context": null,
"index": null,
"key": null,
"children": [
{
"type": "SvelteText",
"value": "...",
"range": [
18,
21
],
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 21
}
}
}
],
"else": null,
"range": [
0,
28
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 28
}
}
}
],
"sourceType": "module",
"comments": [],
"tokens": [
{
"type": "Punctuator",
"value": "{",
"range": [
0,
1
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 1
}
}
},
{
"type": "MustacheKeyword",
"value": "#each",
"range": [
1,
6
],
"loc": {
"start": {
"line": 1,
"column": 1
},
"end": {
"line": 1,
"column": 6
}
}
},
{
"type": "Identifier",
"value": "expression",
"range": [
7,
17
],
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 17
}
}
},
{
"type": "Punctuator",
"value": "}",
"range": [
17,
18
],
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 18
}
}
},
{
"type": "HTMLText",
"value": "...",
"range": [
18,
21
],
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 21
}
}
},
{
"type": "Punctuator",
"value": "{",
"range": [
21,
22
],
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 22
}
}
},
{
"type": "MustacheKeyword",
"value": "/each",
"range": [
22,
27
],
"loc": {
"start": {
"line": 1,
"column": 22
},
"end": {
"line": 1,
"column": 27
}
}
},
{
"type": "Punctuator",
"value": "}",
"range": [
27,
28
],
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
}
}
}
],
"range": [
0,
29
],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 0
}
}
}
Loading

0 comments on commit 1e0b874

Please sign in to comment.