Skip to content

Commit c374681

Browse files
committed
fix: changed so that if Compiler.SvelteOptions does not have __raw__ property, we parse it ourselves
1 parent 70f0d06 commit c374681

File tree

8 files changed

+798
-352
lines changed

8 files changed

+798
-352
lines changed

src/context/index.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import type * as SvAST from "../parser/svelte-ast-types";
1515
import type * as Compiler from "svelte/compiler";
1616
import { ScriptLetContext } from "./script-let";
1717
import { LetDirectiveCollections } from "./let-directive-collection";
18-
import type { AttributeToken } from "../parser/html";
1918
import { parseAttributes } from "../parser/html";
2019
import { sortedLastIndex } from "../utils";
2120
import {
@@ -204,8 +203,16 @@ export class Context {
204203
if (block.selfClosing) {
205204
continue;
206205
}
207-
const lang = block.attrs.find((attr) => attr.key.name === "lang");
208-
if (!lang || !lang.value || lang.value.value === "html") {
206+
const lang = block.attrs.find((attr) => attr.name === "lang");
207+
if (!lang || !Array.isArray(lang.value)) {
208+
continue;
209+
}
210+
const langValue = lang.value[0];
211+
if (
212+
!langValue ||
213+
langValue.type !== "Text" ||
214+
langValue.data === "html"
215+
) {
209216
continue;
210217
}
211218
}
@@ -235,7 +242,13 @@ export class Context {
235242
spaces.slice(start, block.contentRange[0]) +
236243
code.slice(...block.contentRange);
237244
for (const attr of block.attrs) {
238-
scriptAttrs[attr.key.name] = attr.value?.value;
245+
if (Array.isArray(attr.value)) {
246+
const attrValue = attr.value[0];
247+
scriptAttrs[attr.name] =
248+
attrValue && attrValue.type === "Text"
249+
? attrValue.data
250+
: undefined;
251+
}
239252
}
240253
} else {
241254
scriptCode += spaces.slice(start, block.contentRange[1]);
@@ -361,7 +374,7 @@ type Block =
361374
| {
362375
tag: "script" | "style" | "template";
363376
originalTag: string;
364-
attrs: AttributeToken[];
377+
attrs: Compiler.Attribute[];
365378
selfClosing?: false;
366379
contentRange: [number, number];
367380
startTagRange: [number, number];
@@ -372,7 +385,7 @@ type Block =
372385
type SelfClosingBlock = {
373386
tag: "script" | "style" | "template";
374387
originalTag: string;
375-
attrs: AttributeToken[];
388+
attrs: Compiler.Attribute[];
376389
selfClosing: true;
377390
startTagRange: [number, number];
378391
};
@@ -394,7 +407,7 @@ function* extractBlocks(code: string): IterableIterator<Block> {
394407

395408
const lowerTag = tag.toLowerCase() as "script" | "style" | "template";
396409

397-
let attrs: AttributeToken[] = [];
410+
let attrs: Compiler.Attribute[] = [];
398411
if (!nextChar.trim()) {
399412
const attrsData = parseAttributes(code, startTagOpenRe.lastIndex);
400413
attrs = attrsData.attributes;

src/parser/compat.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type ESTree from "estree";
33
import type * as SvAST from "./svelte-ast-types";
44
import type * as Compiler from "svelte/compiler";
5+
import { parseAttributes } from "./html";
56

67
export type Child =
78
| Compiler.Text
@@ -30,8 +31,18 @@ export function getModuleFromRoot(
3031
}
3132
export function getOptionsFromRoot(
3233
svelteAst: Compiler.Root | SvAST.AstLegacy,
34+
code: string,
3335
): Compiler.SvelteOptionsRaw | null {
34-
return (svelteAst as any).options?.__raw__ ?? null;
36+
const root = svelteAst as Compiler.Root;
37+
if (root.options) {
38+
if ((root.options as any).__raw__) {
39+
return (root.options as any).__raw__;
40+
}
41+
// If there is no `__raw__` property in the `SvelteOptions` node,
42+
// we will parse `<svelte:options>` ourselves.
43+
return parseSvelteOptions(root.options, code);
44+
}
45+
return null;
3546
}
3647

3748
export function getChildren(
@@ -228,3 +239,40 @@ export function getDeclaratorFromConstTag(
228239
(node as SvAST.ConstTag).expression
229240
);
230241
}
242+
243+
function parseSvelteOptions(
244+
options: Compiler.SvelteOptions,
245+
code: string,
246+
): Compiler.SvelteOptionsRaw {
247+
const { start, end } = options;
248+
const nameEndName = start + "<svelte:options".length;
249+
const { attributes, index: tagEndIndex } = parseAttributes(
250+
code,
251+
nameEndName + 1,
252+
);
253+
const fragment: Compiler.Fragment = {
254+
type: "Fragment",
255+
nodes: [],
256+
transparent: true,
257+
};
258+
if (code.startsWith(">", tagEndIndex)) {
259+
const childEndIndex = code.indexOf("</svelte:options", tagEndIndex);
260+
fragment.nodes.push({
261+
type: "Text",
262+
data: code.slice(tagEndIndex + 1, childEndIndex),
263+
start: tagEndIndex + 1,
264+
end: childEndIndex,
265+
raw: code.slice(tagEndIndex + 1, childEndIndex),
266+
parent: fragment,
267+
});
268+
}
269+
return {
270+
type: "SvelteOptions",
271+
name: "svelte:options",
272+
attributes,
273+
fragment,
274+
start,
275+
end,
276+
parent: null as any,
277+
};
278+
}

src/parser/converts/attr.ts

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,9 @@ import type * as SvAST from "../svelte-ast-types";
2727
import type * as Compiler from "svelte/compiler";
2828
import { getWithLoc, indexOf } from "./common";
2929
import { convertMustacheTag } from "./mustache";
30-
import {
31-
convertAttributeValueTokenToLiteral,
32-
convertTextToLiteral,
33-
} from "./text";
30+
import { convertTextToLiteral } from "./text";
3431
import { ParseError } from "../../errors";
3532
import type { ScriptLetCallback } from "../../context/script-let";
36-
import type { AttributeToken } from "../html";
3733
import { svelteVersion } from "../svelte-version";
3834
import { hasTypeInfo } from "../../utils";
3935
import { getModifiers } from "../compat";
@@ -125,42 +121,6 @@ export function* convertAttributes(
125121
}
126122
}
127123

128-
/** Convert for attribute tokens */
129-
export function* convertAttributeTokens(
130-
attributes: AttributeToken[],
131-
parent: SvelteStartTag,
132-
ctx: Context,
133-
): IterableIterator<SvelteAttribute> {
134-
for (const attr of attributes) {
135-
const attribute: SvelteAttribute = {
136-
type: "SvelteAttribute",
137-
boolean: false,
138-
key: null as any,
139-
value: [],
140-
parent,
141-
...ctx.getConvertLocation({
142-
start: attr.key.start,
143-
end: attr.value?.end ?? attr.key.end,
144-
}),
145-
};
146-
attribute.key = {
147-
type: "SvelteName",
148-
name: attr.key.name,
149-
parent: attribute,
150-
...ctx.getConvertLocation(attr.key),
151-
};
152-
ctx.addToken("HTMLIdentifier", attr.key);
153-
if (attr.value == null) {
154-
attribute.boolean = true;
155-
} else {
156-
attribute.value.push(
157-
convertAttributeValueTokenToLiteral(attr.value, attribute, ctx),
158-
);
159-
}
160-
yield attribute;
161-
}
162-
}
163-
164124
/** Convert for Attribute */
165125
function convertAttribute(
166126
node: SvAST.Attribute | Compiler.Attribute,

src/parser/converts/root.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
import {} from "./common";
1313
import type { Context } from "../../context";
1414
import { convertChildren, extractElementTags } from "./element";
15-
import { convertAttributeTokens } from "./attr";
15+
import { convertAttributes } from "./attr";
1616
import type { Scope } from "eslint-scope";
1717
import { parseScriptWithoutAnalyzeScope } from "../script";
1818
import type { TSESParseForESLintResult } from "../typescript/types";
@@ -47,7 +47,7 @@ export function convertSvelteRoot(
4747
const fragment = getFragmentFromRoot(svelteAst);
4848
if (fragment) {
4949
let children = getChildren(fragment);
50-
const options = getOptionsFromRoot(svelteAst);
50+
const options = getOptionsFromRoot(svelteAst, ctx.code);
5151
if (options) {
5252
children = [...children];
5353
if (
@@ -212,7 +212,7 @@ function extractAttributes(
212212
const block = ctx.findBlock(element);
213213
if (block) {
214214
element.startTag.attributes.push(
215-
...convertAttributeTokens(block.attrs, element.startTag, ctx),
215+
...convertAttributes(block.attrs, element.startTag, ctx),
216216
);
217217
}
218218
}

src/parser/converts/text.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { SvelteLiteral, SvelteText } from "../../ast";
22
import type { Context } from "../../context";
3-
import type { AttributeValueToken } from "../html";
43
import type * as SvAST from "../svelte-ast-types";
54
/** Convert for Text */
65
export function convertText(
@@ -34,25 +33,6 @@ export function convertTextToLiteral(
3433
return text;
3534
}
3635

37-
/** Convert for AttributeValueToken to Literal */
38-
export function convertAttributeValueTokenToLiteral(
39-
node: AttributeValueToken,
40-
parent: SvelteLiteral["parent"],
41-
ctx: Context,
42-
): SvelteLiteral {
43-
const valueLoc = node.quote
44-
? { start: node.start + 1, end: node.end - 1 }
45-
: node;
46-
const text: SvelteLiteral = {
47-
type: "SvelteLiteral",
48-
value: node.value,
49-
parent,
50-
...ctx.getConvertLocation(valueLoc),
51-
};
52-
extractTextTokens(valueLoc, ctx);
53-
return text;
54-
}
55-
5636
/** Extract tokens */
5737
function extractTextTokens(
5838
node: { start: number; end: number },

0 commit comments

Comments
 (0)