Skip to content

Commit 968fa41

Browse files
authored
Fix wrong parent node (#31)
1 parent e825a63 commit 968fa41

File tree

7 files changed

+75
-45
lines changed

7 files changed

+75
-45
lines changed

src/context/let-directive-collection.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { SvelteLetDirective } from "../ast"
1+
import type { SvelteLetDirective, SvelteNode } from "../ast"
22
import type * as ESTree from "estree"
33
import type { ScriptLetCallback, ScriptLetCallbackOption } from "./script-let"
44

@@ -19,14 +19,19 @@ export class LetDirectiveCollection {
1919
return this.list.map((d) => d.pattern)
2020
}
2121

22+
public getParents(): SvelteNode[] {
23+
return this.list.map((d) => d.directive)
24+
}
25+
2226
public getCallback(): (
2327
nodes: ESTree.Pattern[],
2428
options: ScriptLetCallbackOption,
2529
) => void {
2630
return (nodes, options) => {
2731
for (let index = 0; index < nodes.length; index++) {
2832
const node = nodes[index]
29-
for (const callback of this.list[index].callbacks) {
33+
const { callbacks } = this.list[index]
34+
for (const callback of callbacks) {
3035
callback(node, options)
3136
}
3237
}

src/context/script-let.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ export class ScriptLetContext {
301301
public nestBlock(
302302
block: SvelteNode,
303303
params: ESTree.Pattern[],
304+
parents: SvelteNode[],
304305
callback: (
305306
nodes: ESTree.Pattern[],
306307
options: ScriptLetCallbackOption,
@@ -311,6 +312,7 @@ export class ScriptLetContext {
311312
public nestBlock(
312313
block: SvelteNode,
313314
params?: ESTree.Pattern[],
315+
parents?: SvelteNode[],
314316
callback?: (
315317
nodes: ESTree.Pattern[],
316318
options: ScriptLetCallbackOption,
@@ -372,8 +374,9 @@ export class ScriptLetContext {
372374

373375
// Process for nodes
374376
callback!(fn.params, result)
375-
for (const p of fn.params) {
376-
;(p as any).parent = block
377+
for (let index = 0; index < fn.params.length; index++) {
378+
const p = fn.params[index]
379+
;(p as any).parent = parents![index]
377380
}
378381

379382
// Process for scope

src/parser/converts/attr.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ function convertAttribute(
123123
loc: attribute.loc,
124124
range: attribute.range,
125125
}
126+
;(key as any).parent = sAttr
126127
ctx.scriptLet.addExpression(key, sAttr, null, (es) => {
127-
sAttr.key = es
128128
sAttr.value = es
129129
})
130130
return sAttr
@@ -386,11 +386,12 @@ function convertLetDirective(
386386
? undefined
387387
: (name) => {
388388
// shorthand
389-
return ctx.letDirCollections
389+
ctx.letDirCollections
390390
.getCollection()
391391
.addPattern(name, directive, "any", (es) => {
392392
directive.expression = es
393393
})
394+
return []
394395
},
395396
)
396397
return directive
@@ -451,22 +452,18 @@ function processDirective<
451452
getWithLoc(node.expression).end === nameRange.end
452453
processExpression(node.expression).push((es) => {
453454
directive.expression = es
454-
455-
if (isShorthand) {
456-
directive.name = directive.expression as ESTree.Identifier
457-
}
458455
})
459456
}
460457

461458
// put name
459+
directive.name = {
460+
type: "Identifier",
461+
name: node.name,
462+
// @ts-expect-error -- ignore
463+
parent: directive,
464+
...ctx.getConvertLocation(nameRange),
465+
}
462466
if (!isShorthand) {
463-
directive.name = {
464-
type: "Identifier",
465-
name: node.name,
466-
// @ts-expect-error -- ignore
467-
parent: directive,
468-
...ctx.getConvertLocation(nameRange),
469-
}
470467
if (processName) {
471468
processName(directive.name).push((es) => {
472469
directive.name = es

src/parser/converts/block.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ export function convertAwaitBlock(
224224
ctx.scriptLet.nestBlock(
225225
thenBlock,
226226
[node.value],
227+
[thenBlock],
227228
([value]) => {
228229
thenBlock.value = value
229230
},
@@ -264,6 +265,7 @@ export function convertAwaitBlock(
264265
ctx.scriptLet.nestBlock(
265266
catchBlock,
266267
[node.error],
268+
[catchBlock],
267269
([error]) => {
268270
catchBlock.error = error
269271
},

src/parser/converts/element.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ function convertHTMLElement(
211211
ctx.scriptLet.nestBlock(
212212
element,
213213
lets.getLetParams(),
214+
lets.getParents(),
214215
lets.getCallback(),
215216
lets.getTypes(),
216217
)
@@ -283,6 +284,7 @@ function convertSpecialElement(
283284
ctx.scriptLet.nestBlock(
284285
element,
285286
lets.getLetParams(),
287+
lets.getParents(),
286288
lets.getCallback(),
287289
lets.getTypes(),
288290
)
@@ -385,6 +387,7 @@ function convertComponentElement(
385387
ctx.scriptLet.nestBlock(
386388
element,
387389
lets.getLetParams(),
390+
lets.getParents(),
388391
lets.getCallback(),
389392
lets.getTypes(),
390393
)

tests/src/parser/eslint-rules.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,21 @@ describe("svelte-eslint-parser with ESLint rules", () => {
4646
for (const rule of RULES) {
4747
it(rule, () => {
4848
const outputFileName = getRuleOutputFileName(rule)
49-
const messages = linter.verify(input, {
50-
parser: "svelte-eslint-parser",
51-
parserOptions: BASIC_PARSER_OPTIONS,
52-
rules: {
53-
[rule]: "error",
49+
const messages = linter.verify(
50+
input,
51+
{
52+
parser: "svelte-eslint-parser",
53+
parserOptions: BASIC_PARSER_OPTIONS,
54+
rules: {
55+
[rule]: "error",
56+
},
57+
env: {
58+
browser: true,
59+
es2021: true,
60+
},
5461
},
55-
env: {
56-
browser: true,
57-
es2021: true,
58-
},
59-
})
62+
inputFileName,
63+
)
6064

6165
if (messages.length === 0) {
6266
assert.strictEqual(

tests/src/parser/parser.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,26 +105,42 @@ function checkLoc(ast: SvelteProgram, fileName: string, code: string) {
105105
`No range on "${token.type} line:${token.loc.start.line} col:${token.loc.start.column}" in ${fileName}`,
106106
)
107107
}
108+
const set = new Set<any>()
108109
traverseNodes(ast, {
109110
enterNode(node, parent) {
110-
// assert.ok(
111-
// node.parent?.type === parent?.type,
112-
// `Parent type mismatch [${node.parent?.type} : ${
113-
// parent?.type
114-
// }] @${JSON.stringify(node, replacer)}`,
115-
// )
116-
// assert.ok(
117-
// node.parent?.range?.[0] === parent?.range[0],
118-
// `Parent range mismatch [${node.parent?.range?.[0]} : ${
119-
// parent?.range[0]
120-
// }] @${JSON.stringify(node, replacer)}`,
121-
// )
122-
// assert.ok(
123-
// node.parent?.range?.[1] === parent?.range[1],
124-
// `Parent range mismatch [${node.parent?.range?.[1]} : ${
125-
// parent?.range[1]
126-
// }] @${JSON.stringify(node, replacer)}`,
127-
// )
111+
if (
112+
(node.type.startsWith("Svelte") ||
113+
parent?.type.startsWith("Svelte")) &&
114+
set.has(node)
115+
) {
116+
assert.fail(
117+
`Duplicate node @parent: ${parent?.type}, ${JSON.stringify(
118+
node,
119+
nodeReplacer,
120+
)}`,
121+
)
122+
}
123+
set.add(node)
124+
if (parent?.type.startsWith("Svelte")) {
125+
assert.ok(
126+
node.parent?.type === parent?.type,
127+
`Parent type mismatch [${node.parent?.type} : ${
128+
parent?.type
129+
}] @${JSON.stringify(node, nodeReplacer)}`,
130+
)
131+
}
132+
assert.ok(
133+
node.parent?.range?.[0] === parent?.range[0],
134+
`Parent range mismatch [${node.parent?.range?.[0]} : ${
135+
parent?.range[0]
136+
}] @${JSON.stringify(node, nodeReplacer)}`,
137+
)
138+
assert.ok(
139+
node.parent?.range?.[1] === parent?.range[1],
140+
`Parent range mismatch [${node.parent?.range?.[1]} : ${
141+
parent?.range[1]
142+
}] @${JSON.stringify(node, nodeReplacer)}`,
143+
)
128144
assert.ok(
129145
node.range[0] < node.range[1],
130146
`No range on "${node.type} line:${node.loc.start.line} col:${node.loc.start.column}" in ${fileName}`,

0 commit comments

Comments
 (0)