Skip to content

Commit 83e4471

Browse files
authored
Breaking change the AST. (#21)
* Breaking change the AST. - Make some ASTs similar to JSX ASTs. - SvelteSpreadAttribute - Accept MemberExpression as the name of the component element. * fix
1 parent 0fa6d1b commit 83e4471

File tree

63 files changed

+2235
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2235
-96
lines changed

src/ast.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export interface SvelteHTMLElement extends BaseSvelteElement {
141141
export interface SvelteComponentElement extends BaseSvelteElement {
142142
type: "SvelteElement"
143143
kind: "component"
144-
name: ESTree.Identifier
144+
name: ESTree.Identifier | SvelteMemberExpressionName
145145
attributes: (
146146
| SvelteAttribute
147147
| SvelteShorthandAttribute
@@ -194,6 +194,15 @@ export interface SvelteName extends BaseNode {
194194
| SvelteScriptElement
195195
| SvelteStyleElement
196196
| SvelteAttribute
197+
| SvelteMemberExpressionName
198+
}
199+
200+
/** Nodes that may be used in component names. The component names separated by dots. */
201+
export interface SvelteMemberExpressionName extends BaseNode {
202+
type: "SvelteMemberExpressionName"
203+
object: SvelteMemberExpressionName | ESTree.Identifier
204+
property: SvelteName
205+
parent: SvelteComponentElement
197206
}
198207

199208
type Child =
@@ -237,7 +246,7 @@ interface BaseSvelteMustacheTag extends BaseNode {
237246
| SvelteKeyBlock
238247
| SvelteAttribute
239248
}
240-
/** Node of mustache tag. e.g. `{...}`, `{@html ...}` */
249+
/** Node of mustache tag. e.g. `{...}`, `{@html ...}`. Like JSXExpressionContainer */
241250
export interface SvelteMustacheTag extends BaseSvelteMustacheTag {
242251
type: "SvelteMustacheTag"
243252
kind: "text" | "raw"
@@ -376,10 +385,10 @@ export interface SvelteShorthandAttribute extends BaseNode {
376385
value: ESTree.Identifier
377386
parent: SvelteElement | SvelteScriptElement | SvelteStyleElement
378387
}
379-
/** Node of spread attribute. e.g. `<Info {...pkg}/>` */
388+
/** Node of spread attribute. e.g. `<Info {...pkg}/>`. Like JSXSpreadAttribute */
380389
export interface SvelteSpreadAttribute extends BaseNode {
381390
type: "SvelteSpreadAttribute"
382-
expression: ESTree.Expression
391+
argument: ESTree.Expression
383392
parent: SvelteElement | SvelteScriptElement | SvelteStyleElement
384393
}
385394

src/parser/converts/attr.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ function convertSpreadAttribute(
161161
): SvelteSpreadAttribute {
162162
const attribute: SvelteSpreadAttribute = {
163163
type: "SvelteSpreadAttribute",
164-
expression: null as any,
164+
argument: null as any,
165165
parent,
166166
...ctx.getConvertLocation(node),
167167
}
@@ -174,7 +174,7 @@ function convertSpreadAttribute(
174174

175175
const es = convertESNode(node.expression, attribute, ctx)!
176176
analyzeExpressionScope(es, ctx)
177-
attribute.expression = es
177+
attribute.argument = es
178178

179179
return attribute
180180
}

src/parser/converts/element.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
SvelteHTMLElement,
1313
SvelteIfBlock,
1414
SvelteKeyBlock,
15+
SvelteMemberExpressionName,
1516
SvelteMustacheTag,
1617
SvelteName,
1718
SvelteProgram,
@@ -188,6 +189,7 @@ function convertHTMLElement(
188189

189190
extractElementTokens(element, ctx, {
190191
buildNameNode: (openTokenRange) => {
192+
ctx.addToken("HTMLIdentifier", openTokenRange)
191193
const name: SvelteName = {
192194
type: "SvelteName",
193195
name: node.name,
@@ -263,6 +265,7 @@ function convertSpecialElement(
263265

264266
extractElementTokens(element, ctx, {
265267
buildNameNode: (openTokenRange) => {
268+
ctx.addToken("HTMLIdentifier", openTokenRange)
266269
const name: SvelteName = {
267270
type: "SvelteName",
268271
name: node.name,
@@ -296,17 +299,51 @@ function convertComponentElement(
296299

297300
extractElementTokens(element, ctx, {
298301
buildNameNode: (openTokenRange) => {
299-
const name: ESTree.Identifier = {
302+
const chains = node.name.split(".")
303+
const id = chains.shift()!
304+
const idRange = {
305+
start: openTokenRange.start,
306+
end: openTokenRange.start + id.length,
307+
}
308+
ctx.addToken("Identifier", idRange)
309+
const identifier: ESTree.Identifier = {
300310
type: "Identifier",
301-
name: node.name,
311+
name: id,
302312
// @ts-expect-error -- ignore
303313
parent: element,
304-
...ctx.getConvertLocation(openTokenRange),
314+
...ctx.getConvertLocation(idRange),
305315
}
306-
return name
316+
let object: SvelteComponentElement["name"] = identifier
317+
318+
let start = idRange.end + 1
319+
for (const name of chains) {
320+
const range = { start, end: start + name.length }
321+
ctx.addToken("HTMLIdentifier", range)
322+
const men: SvelteMemberExpressionName = {
323+
type: "SvelteMemberExpressionName",
324+
object,
325+
property: {
326+
type: "SvelteName",
327+
name,
328+
parent: null as any,
329+
...ctx.getConvertLocation(range),
330+
},
331+
parent: element,
332+
...ctx.getConvertLocation({
333+
start: openTokenRange.start,
334+
end: range.end,
335+
}),
336+
}
337+
men.property.parent = men
338+
;(object as any).parent = men
339+
object = men
340+
start = range.end + 1
341+
}
342+
343+
analyzeExpressionScope(identifier, ctx)
344+
return object
307345
},
308346
})
309-
analyzeExpressionScope(element.name, ctx)
310347
return element
311348
}
312349

@@ -388,7 +425,7 @@ export function extractElementTokens<
388425
start: element.range[0] + 1,
389426
end: startTagNameEnd,
390427
}
391-
const openToken = ctx.addToken("HTMLIdentifier", openTokenRange)
428+
392429
element.name = options.buildNameNode(openTokenRange)
393430

394431
if (ctx.code[element.range[1] - 1] !== ">") {
@@ -402,7 +439,7 @@ export function extractElementTokens<
402439

403440
const attrEnd = element.attributes.length
404441
? element.attributes[element.attributes.length - 1].range[1]
405-
: openToken.range[1]
442+
: openTokenRange.end
406443

407444
const endTagOpen = ctx.code.lastIndexOf("<", element.range[1] - 1)
408445
if (endTagOpen <= attrEnd) {

src/parser/converts/root.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export function convertSvelteRoot(
4646
extractAttributes(script, ctx)
4747
extractElementTokens(script, ctx, {
4848
buildNameNode: (openTokenRange) => {
49+
ctx.addToken("HTMLIdentifier", openTokenRange)
4950
const name: SvelteName = {
5051
type: "SvelteName",
5152
name: "script",
@@ -70,6 +71,7 @@ export function convertSvelteRoot(
7071
extractAttributes(script, ctx)
7172
extractElementTokens(script, ctx, {
7273
buildNameNode: (openTokenRange) => {
74+
ctx.addToken("HTMLIdentifier", openTokenRange)
7375
const name: SvelteName = {
7476
type: "SvelteName",
7577
name: "script",
@@ -94,6 +96,7 @@ export function convertSvelteRoot(
9496
extractAttributes(style, ctx)
9597
extractElementTokens(style, ctx, {
9698
buildNameNode: (openTokenRange) => {
99+
ctx.addToken("HTMLIdentifier", openTokenRange)
97100
const name: SvelteName = {
98101
type: "SvelteName",
99102
name: "script",

src/visitor-keys.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const svelteKeys: SvelteKeysType = {
3434
SvelteKeyBlock: ["expression", "children"],
3535
SvelteAttribute: ["key", "value"],
3636
SvelteShorthandAttribute: ["key", "value"],
37-
SvelteSpreadAttribute: ["expression"],
37+
SvelteSpreadAttribute: ["argument"],
3838
SvelteDirective: ["expression"],
3939
SvelteReactiveStatement: ["label", "body"],
4040
SvelteText: [],

tests/fixtures/parser/ast/components01-output.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@
443443
}
444444
},
445445
{
446-
"type": "HTMLIdentifier",
446+
"type": "Identifier",
447447
"value": "MyComponent",
448448
"range": [
449449
70,

tests/fixtures/parser/ast/components02-output.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@
518518
}
519519
},
520520
{
521-
"type": "HTMLIdentifier",
521+
"type": "Identifier",
522522
"value": "MyComponent",
523523
"range": [
524524
70,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script>
2+
import * as MyComponents from './MyComponents';
3+
</script>
4+
5+
<MyComponents.MyComponent>
6+
contents<div></div>
7+
</MyComponents.MyComponent>
8+
<OtherComponents.OtherComponent>
9+
contents<div></div>
10+
</OtherComponents.OtherComponent>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"ruleId": "no-undef",
4+
"code": "OtherComponents",
5+
"line": 8,
6+
"column": 2
7+
}
8+
]

0 commit comments

Comments
 (0)