astro-eslint-parser 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +345 -9
- package/lib/index.js +1745 -42
- package/lib/index.mjs +1719 -0
- package/package.json +9 -7
- package/lib/ast/astro.d.ts +0 -49
- package/lib/ast/astro.js +0 -2
- package/lib/ast/base.d.ts +0 -6
- package/lib/ast/base.js +0 -2
- package/lib/ast/index.d.ts +0 -8
- package/lib/ast/index.js +0 -18
- package/lib/ast/jsx.d.ts +0 -91
- package/lib/ast/jsx.js +0 -2
- package/lib/astro/index.d.ts +0 -56
- package/lib/astro/index.js +0 -357
- package/lib/astro-tools/index.d.ts +0 -21
- package/lib/astro-tools/index.js +0 -26
- package/lib/context/index.d.ts +0 -55
- package/lib/context/index.js +0 -158
- package/lib/context/parser-options.d.ts +0 -8
- package/lib/context/parser-options.js +0 -77
- package/lib/context/resolve-parser/espree.d.ts +0 -6
- package/lib/context/resolve-parser/espree.js +0 -41
- package/lib/context/resolve-parser/index.d.ts +0 -7
- package/lib/context/resolve-parser/index.js +0 -34
- package/lib/context/resolve-parser/parser-object.d.ts +0 -33
- package/lib/context/resolve-parser/parser-object.js +0 -27
- package/lib/context/script.d.ts +0 -34
- package/lib/context/script.js +0 -178
- package/lib/debug.d.ts +0 -2
- package/lib/debug.js +0 -8
- package/lib/errors.d.ts +0 -14
- package/lib/errors.js +0 -20
- package/lib/parser/astro-parser/astrojs-compiler-service.d.ts +0 -5
- package/lib/parser/astro-parser/astrojs-compiler-service.js +0 -12
- package/lib/parser/astro-parser/astrojs-compiler-worker.d.ts +0 -1
- package/lib/parser/astro-parser/astrojs-compiler-worker.js +0 -11
- package/lib/parser/astro-parser/parse.d.ts +0 -6
- package/lib/parser/astro-parser/parse.js +0 -270
- package/lib/parser/index.d.ts +0 -21
- package/lib/parser/index.js +0 -72
- package/lib/parser/lru-cache.d.ts +0 -7
- package/lib/parser/lru-cache.js +0 -32
- package/lib/parser/process-template.d.ts +0 -7
- package/lib/parser/process-template.js +0 -390
- package/lib/parser/script.d.ts +0 -7
- package/lib/parser/script.js +0 -44
- package/lib/parser/sort.d.ts +0 -6
- package/lib/parser/sort.js +0 -15
- package/lib/parser/template.d.ts +0 -10
- package/lib/parser/template.js +0 -102
- package/lib/parser/ts-patch.d.ts +0 -8
- package/lib/parser/ts-patch.js +0 -65
- package/lib/traverse.d.ts +0 -27
- package/lib/traverse.js +0 -93
- package/lib/types.d.ts +0 -17
- package/lib/types.js +0 -2
- package/lib/visitor-keys.d.ts +0 -2
- package/lib/visitor-keys.js +0 -14
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,1719 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw new Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/visitor-keys.ts
|
|
10
|
+
import { unionWith } from "eslint-visitor-keys";
|
|
11
|
+
var astroKeys = {
|
|
12
|
+
Program: ["body"],
|
|
13
|
+
AstroFragment: ["children"],
|
|
14
|
+
AstroHTMLComment: [],
|
|
15
|
+
AstroDoctype: [],
|
|
16
|
+
AstroShorthandAttribute: ["name", "value"],
|
|
17
|
+
AstroTemplateLiteralAttribute: ["name", "value"],
|
|
18
|
+
AstroRawText: []
|
|
19
|
+
};
|
|
20
|
+
var KEYS = unionWith(
|
|
21
|
+
astroKeys
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// src/parser/index.ts
|
|
25
|
+
import { AST_TOKEN_TYPES as AST_TOKEN_TYPES2 } from "@typescript-eslint/types";
|
|
26
|
+
|
|
27
|
+
// src/debug.ts
|
|
28
|
+
import debugFactory from "debug";
|
|
29
|
+
var debug = debugFactory("astro-eslint-parser");
|
|
30
|
+
|
|
31
|
+
// src/parser/ts-patch.ts
|
|
32
|
+
import { createRequire } from "module";
|
|
33
|
+
import path from "path";
|
|
34
|
+
import fs from "fs";
|
|
35
|
+
function tsPatch(scriptParserOptions) {
|
|
36
|
+
let targetExt = ".astro";
|
|
37
|
+
if (scriptParserOptions.filePath) {
|
|
38
|
+
const ext = path.extname(scriptParserOptions.filePath);
|
|
39
|
+
if (ext) {
|
|
40
|
+
targetExt = ext;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const cwd = process.cwd();
|
|
45
|
+
const relativeTo = path.join(cwd, "__placeholder__.js");
|
|
46
|
+
const ts = createRequire(relativeTo)("typescript");
|
|
47
|
+
const { ensureScriptKind, getScriptKindFromFileName } = ts;
|
|
48
|
+
if (typeof ensureScriptKind === "function" && typeof getScriptKindFromFileName === "function") {
|
|
49
|
+
ts.ensureScriptKind = function(fileName, ...args) {
|
|
50
|
+
if (fileName.endsWith(targetExt)) {
|
|
51
|
+
return ts.ScriptKind.TSX;
|
|
52
|
+
}
|
|
53
|
+
return ensureScriptKind.call(this, fileName, ...args);
|
|
54
|
+
};
|
|
55
|
+
ts.getScriptKindFromFileName = function(fileName, ...args) {
|
|
56
|
+
if (fileName.endsWith(targetExt)) {
|
|
57
|
+
return ts.ScriptKind.TSX;
|
|
58
|
+
}
|
|
59
|
+
return getScriptKindFromFileName.call(this, fileName, ...args);
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
terminate() {
|
|
63
|
+
ts.ensureScriptKind = ensureScriptKind;
|
|
64
|
+
ts.getScriptKindFromFileName = getScriptKindFromFileName;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
const tsxFilePath = `${scriptParserOptions.filePath}.tsx`;
|
|
71
|
+
scriptParserOptions.filePath = tsxFilePath;
|
|
72
|
+
if (!fs.existsSync(tsxFilePath)) {
|
|
73
|
+
fs.writeFileSync(tsxFilePath, "/* temp for astro-eslint-parser */");
|
|
74
|
+
return {
|
|
75
|
+
terminate() {
|
|
76
|
+
fs.unlinkSync(tsxFilePath);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/context/resolve-parser/parser-object.ts
|
|
84
|
+
function isParserObject(value) {
|
|
85
|
+
return isEnhancedParserObject(value) || isBasicParserObject(value);
|
|
86
|
+
}
|
|
87
|
+
function isEnhancedParserObject(value) {
|
|
88
|
+
return Boolean(value && typeof value.parseForESLint === "function");
|
|
89
|
+
}
|
|
90
|
+
function isBasicParserObject(value) {
|
|
91
|
+
return Boolean(value && typeof value.parse === "function");
|
|
92
|
+
}
|
|
93
|
+
function maybeTSESLintParserObject(value) {
|
|
94
|
+
return isEnhancedParserObject(value) && isBasicParserObject(value) && typeof value.createProgram === "function" && typeof value.clearCaches === "function" && typeof value.version === "string";
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/parser/script.ts
|
|
98
|
+
function parseScript(code, _ctx, parserOptions) {
|
|
99
|
+
const parser = parserOptions.getParser();
|
|
100
|
+
let patchResult;
|
|
101
|
+
try {
|
|
102
|
+
const scriptParserOptions = {
|
|
103
|
+
...parserOptions.parserOptions
|
|
104
|
+
};
|
|
105
|
+
scriptParserOptions.ecmaFeatures = {
|
|
106
|
+
...scriptParserOptions.ecmaFeatures || {},
|
|
107
|
+
jsx: true
|
|
108
|
+
};
|
|
109
|
+
if (parserOptions.isTypeScript() && scriptParserOptions.filePath && scriptParserOptions.project) {
|
|
110
|
+
patchResult = tsPatch(scriptParserOptions);
|
|
111
|
+
}
|
|
112
|
+
const result = isEnhancedParserObject(parser) ? parser.parseForESLint(code, scriptParserOptions) : parser.parse(code, scriptParserOptions);
|
|
113
|
+
if ("ast" in result && result.ast != null) {
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
return { ast: result };
|
|
117
|
+
} catch (e) {
|
|
118
|
+
debug(
|
|
119
|
+
"[script] parsing error:",
|
|
120
|
+
e.message,
|
|
121
|
+
`@ ${JSON.stringify(code)}
|
|
122
|
+
|
|
123
|
+
${code}`
|
|
124
|
+
);
|
|
125
|
+
throw e;
|
|
126
|
+
} finally {
|
|
127
|
+
patchResult == null ? void 0 : patchResult.terminate();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/parser/sort.ts
|
|
132
|
+
function sort(tokens) {
|
|
133
|
+
return tokens.sort((a, b) => {
|
|
134
|
+
if (a.range[0] !== b.range[0]) {
|
|
135
|
+
return a.range[0] - b.range[0];
|
|
136
|
+
}
|
|
137
|
+
return a.range[1] - b.range[1];
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/parser/process-template.ts
|
|
142
|
+
import { AST_TOKEN_TYPES, AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
143
|
+
|
|
144
|
+
// src/errors.ts
|
|
145
|
+
var ParseError = class extends SyntaxError {
|
|
146
|
+
constructor(message, offset, ctx) {
|
|
147
|
+
super(message);
|
|
148
|
+
this.index = offset;
|
|
149
|
+
const loc = ctx.getLocFromIndex(offset);
|
|
150
|
+
this.lineNumber = loc.line;
|
|
151
|
+
this.column = loc.column;
|
|
152
|
+
this.originalAST = ctx.originalAST;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// src/astro/index.ts
|
|
157
|
+
function isTag(node) {
|
|
158
|
+
return node.type === "element" || node.type === "custom-element" || node.type === "component" || node.type === "fragment";
|
|
159
|
+
}
|
|
160
|
+
function isParent(node) {
|
|
161
|
+
return Array.isArray(node.children);
|
|
162
|
+
}
|
|
163
|
+
function walkElements(parent, code, enter, leave, parents = []) {
|
|
164
|
+
const children = getSortedChildren(parent, code);
|
|
165
|
+
const currParents = [parent, ...parents];
|
|
166
|
+
for (const node of children) {
|
|
167
|
+
enter(node, currParents);
|
|
168
|
+
if (isParent(node)) {
|
|
169
|
+
walkElements(node, code, enter, leave, currParents);
|
|
170
|
+
}
|
|
171
|
+
leave(node, currParents);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function walk(parent, code, enter, leave) {
|
|
175
|
+
walkElements(
|
|
176
|
+
parent,
|
|
177
|
+
code,
|
|
178
|
+
(node, parents) => {
|
|
179
|
+
enter(node, parents);
|
|
180
|
+
if (isTag(node)) {
|
|
181
|
+
const attrParents = [node, ...parents];
|
|
182
|
+
for (const attr of node.attributes) {
|
|
183
|
+
enter(attr, attrParents);
|
|
184
|
+
leave(attr, attrParents);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
leave
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
function calcStartTagEndOffset(node, ctx) {
|
|
192
|
+
const lastAttr = node.attributes[node.attributes.length - 1];
|
|
193
|
+
let beforeCloseIndex;
|
|
194
|
+
if (lastAttr) {
|
|
195
|
+
beforeCloseIndex = calcAttributeEndOffset(lastAttr, ctx);
|
|
196
|
+
} else {
|
|
197
|
+
const info2 = getTokenInfo(
|
|
198
|
+
ctx,
|
|
199
|
+
[`<${node.name}`],
|
|
200
|
+
node.position.start.offset
|
|
201
|
+
);
|
|
202
|
+
beforeCloseIndex = info2.index + info2.match.length;
|
|
203
|
+
}
|
|
204
|
+
const info = getTokenInfo(ctx, [[">", "/>"]], beforeCloseIndex);
|
|
205
|
+
return info.index + info.match.length;
|
|
206
|
+
}
|
|
207
|
+
function calcAttributeEndOffset(node, ctx) {
|
|
208
|
+
let info;
|
|
209
|
+
if (node.kind === "empty") {
|
|
210
|
+
info = getTokenInfo(ctx, [node.name], node.position.start.offset);
|
|
211
|
+
} else if (node.kind === "quoted") {
|
|
212
|
+
info = getTokenInfo(
|
|
213
|
+
ctx,
|
|
214
|
+
[[`"${node.value}"`, `'${node.value}'`, node.value]],
|
|
215
|
+
calcAttributeValueStartOffset(node, ctx)
|
|
216
|
+
);
|
|
217
|
+
} else if (node.kind === "expression") {
|
|
218
|
+
info = getTokenInfo(
|
|
219
|
+
ctx,
|
|
220
|
+
["{", node.value, "}"],
|
|
221
|
+
calcAttributeValueStartOffset(node, ctx)
|
|
222
|
+
);
|
|
223
|
+
} else if (node.kind === "shorthand") {
|
|
224
|
+
info = getTokenInfo(
|
|
225
|
+
ctx,
|
|
226
|
+
["{", node.name, "}"],
|
|
227
|
+
node.position.start.offset
|
|
228
|
+
);
|
|
229
|
+
} else if (node.kind === "spread") {
|
|
230
|
+
info = getTokenInfo(
|
|
231
|
+
ctx,
|
|
232
|
+
["{", "...", node.name, "}"],
|
|
233
|
+
node.position.start.offset
|
|
234
|
+
);
|
|
235
|
+
} else if (node.kind === "template-literal") {
|
|
236
|
+
info = getTokenInfo(
|
|
237
|
+
ctx,
|
|
238
|
+
[`\`${node.value}\``],
|
|
239
|
+
calcAttributeValueStartOffset(node, ctx)
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
throw new ParseError(
|
|
243
|
+
`Unknown attr kind: ${node.kind}`,
|
|
244
|
+
node.position.start.offset,
|
|
245
|
+
ctx
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
return info.index + info.match.length;
|
|
249
|
+
}
|
|
250
|
+
function calcAttributeValueStartOffset(node, ctx) {
|
|
251
|
+
let info;
|
|
252
|
+
if (node.kind === "quoted") {
|
|
253
|
+
info = getTokenInfo(
|
|
254
|
+
ctx,
|
|
255
|
+
[node.name, "=", [`"`, `'`, node.value]],
|
|
256
|
+
node.position.start.offset
|
|
257
|
+
);
|
|
258
|
+
} else if (node.kind === "expression") {
|
|
259
|
+
info = getTokenInfo(
|
|
260
|
+
ctx,
|
|
261
|
+
[node.name, "=", "{"],
|
|
262
|
+
node.position.start.offset
|
|
263
|
+
);
|
|
264
|
+
} else if (node.kind === "template-literal") {
|
|
265
|
+
info = getTokenInfo(
|
|
266
|
+
ctx,
|
|
267
|
+
[node.name, "=", "`"],
|
|
268
|
+
node.position.start.offset
|
|
269
|
+
);
|
|
270
|
+
} else {
|
|
271
|
+
throw new ParseError(
|
|
272
|
+
`Unknown attr kind: ${node.kind}`,
|
|
273
|
+
node.position.start.offset,
|
|
274
|
+
ctx
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
return info.index;
|
|
278
|
+
}
|
|
279
|
+
function getEndOffset(node, ctx) {
|
|
280
|
+
var _a;
|
|
281
|
+
if (((_a = node.position.end) == null ? void 0 : _a.offset) != null) {
|
|
282
|
+
return node.position.end.offset;
|
|
283
|
+
}
|
|
284
|
+
if (isTag(node))
|
|
285
|
+
return calcTagEndOffset(node, ctx);
|
|
286
|
+
if (node.type === "expression")
|
|
287
|
+
return calcExpressionEndOffset(node, ctx);
|
|
288
|
+
if (node.type === "comment")
|
|
289
|
+
return calcCommentEndOffset(node, ctx);
|
|
290
|
+
if (node.type === "frontmatter") {
|
|
291
|
+
const start = node.position.start.offset;
|
|
292
|
+
return ctx.code.indexOf("---", start + 3) + 3;
|
|
293
|
+
}
|
|
294
|
+
if (node.type === "doctype") {
|
|
295
|
+
const start = node.position.start.offset;
|
|
296
|
+
return ctx.code.indexOf(">", start) + 1;
|
|
297
|
+
}
|
|
298
|
+
if (node.type === "text") {
|
|
299
|
+
const start = node.position.start.offset;
|
|
300
|
+
return start + node.value.length;
|
|
301
|
+
}
|
|
302
|
+
if (node.type === "root") {
|
|
303
|
+
return ctx.code.length;
|
|
304
|
+
}
|
|
305
|
+
throw new Error(`unknown type: ${node.type}`);
|
|
306
|
+
}
|
|
307
|
+
function calcContentEndOffset(parent, ctx) {
|
|
308
|
+
const code = ctx.code;
|
|
309
|
+
if (isTag(parent)) {
|
|
310
|
+
const end = getEndOffset(parent, ctx);
|
|
311
|
+
if (code[end - 1] !== ">") {
|
|
312
|
+
return end;
|
|
313
|
+
}
|
|
314
|
+
const index = code.lastIndexOf("</", end - 1);
|
|
315
|
+
if (index >= 0 && code.slice(index + 2, end - 1).trim() === parent.name) {
|
|
316
|
+
return index;
|
|
317
|
+
}
|
|
318
|
+
return end;
|
|
319
|
+
} else if (parent.type === "expression") {
|
|
320
|
+
const end = getEndOffset(parent, ctx);
|
|
321
|
+
return code.lastIndexOf("}", end);
|
|
322
|
+
} else if (parent.type === "root") {
|
|
323
|
+
return code.length;
|
|
324
|
+
}
|
|
325
|
+
throw new Error(`unknown type: ${parent.type}`);
|
|
326
|
+
}
|
|
327
|
+
function getSelfClosingTag(node, ctx) {
|
|
328
|
+
if (node.children.length > 0) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
const code = ctx.code;
|
|
332
|
+
const startTagEndOffset = calcStartTagEndOffset(node, ctx);
|
|
333
|
+
if (code.startsWith("/>", startTagEndOffset - 2)) {
|
|
334
|
+
return {
|
|
335
|
+
offset: startTagEndOffset,
|
|
336
|
+
end: "/>"
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
if (code.startsWith(`</${node.name}`, startTagEndOffset)) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
offset: startTagEndOffset,
|
|
344
|
+
end: ">"
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function getEndTag(node, ctx) {
|
|
348
|
+
let beforeIndex;
|
|
349
|
+
if (node.children.length) {
|
|
350
|
+
const lastChild = node.children[node.children.length - 1];
|
|
351
|
+
beforeIndex = getEndOffset(lastChild, ctx);
|
|
352
|
+
} else {
|
|
353
|
+
beforeIndex = calcStartTagEndOffset(node, ctx);
|
|
354
|
+
}
|
|
355
|
+
beforeIndex = skipSpaces(ctx.code, beforeIndex);
|
|
356
|
+
if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
|
|
357
|
+
const offset = beforeIndex;
|
|
358
|
+
beforeIndex = beforeIndex + 2 + node.name.length;
|
|
359
|
+
const info = getTokenInfo(ctx, [">"], beforeIndex);
|
|
360
|
+
const end = info.index + info.match.length;
|
|
361
|
+
return {
|
|
362
|
+
offset,
|
|
363
|
+
tag: ctx.code.slice(offset, end)
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
function calcCommentEndOffset(node, ctx) {
|
|
369
|
+
const info = getTokenInfo(
|
|
370
|
+
ctx,
|
|
371
|
+
["<!--", node.value, "-->"],
|
|
372
|
+
node.position.start.offset
|
|
373
|
+
);
|
|
374
|
+
return info.index + info.match.length;
|
|
375
|
+
}
|
|
376
|
+
function calcTagEndOffset(node, ctx) {
|
|
377
|
+
let beforeIndex;
|
|
378
|
+
if (node.children.length) {
|
|
379
|
+
const lastChild = node.children[node.children.length - 1];
|
|
380
|
+
beforeIndex = getEndOffset(lastChild, ctx);
|
|
381
|
+
} else {
|
|
382
|
+
beforeIndex = calcStartTagEndOffset(node, ctx);
|
|
383
|
+
}
|
|
384
|
+
beforeIndex = skipSpaces(ctx.code, beforeIndex);
|
|
385
|
+
if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
|
|
386
|
+
beforeIndex = beforeIndex + 2 + node.name.length;
|
|
387
|
+
const info = getTokenInfo(ctx, [">"], beforeIndex);
|
|
388
|
+
return info.index + info.match.length;
|
|
389
|
+
}
|
|
390
|
+
return beforeIndex;
|
|
391
|
+
}
|
|
392
|
+
function calcExpressionEndOffset(node, ctx) {
|
|
393
|
+
if (node.children.length) {
|
|
394
|
+
const lastChild = node.children[node.children.length - 1];
|
|
395
|
+
const beforeIndex = getEndOffset(lastChild, ctx);
|
|
396
|
+
const info2 = getTokenInfo(ctx, ["}"], beforeIndex);
|
|
397
|
+
return info2.index + info2.match.length;
|
|
398
|
+
}
|
|
399
|
+
const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
|
|
400
|
+
return info.index + info.match.length;
|
|
401
|
+
}
|
|
402
|
+
function getTokenInfo(ctx, tokens, position) {
|
|
403
|
+
let lastMatch;
|
|
404
|
+
for (const t of tokens) {
|
|
405
|
+
const index = lastMatch ? lastMatch.index + lastMatch.match.length : position;
|
|
406
|
+
const m = typeof t === "string" ? matchOfStr(t, index) : matchOfForMulti(t, index);
|
|
407
|
+
if (m == null) {
|
|
408
|
+
throw new ParseError(
|
|
409
|
+
`Unknown token at ${index}, expected: ${JSON.stringify(
|
|
410
|
+
t
|
|
411
|
+
)}, actual: ${JSON.stringify(ctx.code.slice(index, index + 10))}`,
|
|
412
|
+
index,
|
|
413
|
+
ctx
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
lastMatch = m;
|
|
417
|
+
}
|
|
418
|
+
return lastMatch;
|
|
419
|
+
function matchOfStr(search, position2) {
|
|
420
|
+
const index = search.trim() === search ? skipSpaces(ctx.code, position2) : position2;
|
|
421
|
+
if (ctx.code.startsWith(search, index)) {
|
|
422
|
+
return {
|
|
423
|
+
match: search,
|
|
424
|
+
index
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
function matchOfForMulti(search, position2) {
|
|
430
|
+
for (const s of search) {
|
|
431
|
+
const m = matchOfStr(s, position2);
|
|
432
|
+
if (m) {
|
|
433
|
+
return m;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
function skipSpaces(string, position) {
|
|
440
|
+
const re = /\s*/g;
|
|
441
|
+
re.lastIndex = position;
|
|
442
|
+
const match = re.exec(string);
|
|
443
|
+
if (match) {
|
|
444
|
+
return match.index + match[0].length;
|
|
445
|
+
}
|
|
446
|
+
return position;
|
|
447
|
+
}
|
|
448
|
+
function getSortedChildren(parent, code) {
|
|
449
|
+
var _a;
|
|
450
|
+
if (parent.type === "root" && ((_a = parent.children[0]) == null ? void 0 : _a.type) === "frontmatter") {
|
|
451
|
+
const children = [...parent.children];
|
|
452
|
+
if (children.every((n) => n.position)) {
|
|
453
|
+
return children.sort(
|
|
454
|
+
(a, b) => a.position.start.offset - b.position.start.offset
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
let start = skipSpaces(code, 0);
|
|
458
|
+
if (code.startsWith("<!", start)) {
|
|
459
|
+
const frontmatter = children.shift();
|
|
460
|
+
const before = [];
|
|
461
|
+
let first;
|
|
462
|
+
while (first = children.shift()) {
|
|
463
|
+
start = skipSpaces(code, start);
|
|
464
|
+
if (first.type === "comment" && code.startsWith("<!--", start)) {
|
|
465
|
+
start = code.indexOf("-->", start + 4) + 3;
|
|
466
|
+
before.push(first);
|
|
467
|
+
} else if (first.type === "doctype" && code.startsWith("<!", start)) {
|
|
468
|
+
start = code.indexOf(">", start + 2) + 1;
|
|
469
|
+
before.push(first);
|
|
470
|
+
} else {
|
|
471
|
+
children.unshift(first);
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return [...before, frontmatter, ...children];
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return parent.children;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// src/traverse.ts
|
|
482
|
+
function fallbackKeysFilter(key) {
|
|
483
|
+
let value = null;
|
|
484
|
+
return key !== "comments" && key !== "leadingComments" && key !== "loc" && key !== "parent" && key !== "range" && key !== "tokens" && key !== "trailingComments" && (value = this[key]) !== null && typeof value === "object" && (typeof value.type === "string" || Array.isArray(value));
|
|
485
|
+
}
|
|
486
|
+
function getFallbackKeys(node) {
|
|
487
|
+
return Object.keys(node).filter(fallbackKeysFilter, node);
|
|
488
|
+
}
|
|
489
|
+
function getKeys(node, visitorKeys) {
|
|
490
|
+
const keys = (visitorKeys || KEYS)[node.type] || getFallbackKeys(node);
|
|
491
|
+
return keys.filter((key) => !getNodes(node, key).next().done);
|
|
492
|
+
}
|
|
493
|
+
function* getNodes(node, key) {
|
|
494
|
+
const child = node[key];
|
|
495
|
+
if (Array.isArray(child)) {
|
|
496
|
+
for (const c of child) {
|
|
497
|
+
if (isNode(c)) {
|
|
498
|
+
yield c;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
} else if (isNode(child)) {
|
|
502
|
+
yield child;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function isNode(x) {
|
|
506
|
+
return x !== null && typeof x === "object" && typeof x.type === "string";
|
|
507
|
+
}
|
|
508
|
+
function traverse(node, parent, visitor) {
|
|
509
|
+
visitor.enterNode(node, parent);
|
|
510
|
+
const keys = getKeys(node, visitor.visitorKeys);
|
|
511
|
+
for (const key of keys) {
|
|
512
|
+
for (const child of getNodes(node, key)) {
|
|
513
|
+
traverse(child, node, visitor);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
visitor.leaveNode(node, parent);
|
|
517
|
+
}
|
|
518
|
+
function traverseNodes(node, visitor) {
|
|
519
|
+
traverse(node, null, visitor);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// src/context/script.ts
|
|
523
|
+
var RestoreNodeProcessContext = class {
|
|
524
|
+
constructor(result, parentMap) {
|
|
525
|
+
this.removeTokens = /* @__PURE__ */ new Set();
|
|
526
|
+
this.result = result;
|
|
527
|
+
this.parentMap = parentMap;
|
|
528
|
+
}
|
|
529
|
+
addRemoveToken(test) {
|
|
530
|
+
this.removeTokens.add(test);
|
|
531
|
+
}
|
|
532
|
+
getParent(node) {
|
|
533
|
+
return this.parentMap.get(node) || null;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var ScriptContext = class {
|
|
537
|
+
constructor(ctx) {
|
|
538
|
+
this.script = "";
|
|
539
|
+
this.consumedIndex = 0;
|
|
540
|
+
this.offsets = [];
|
|
541
|
+
this.fragments = [];
|
|
542
|
+
this.tokens = [];
|
|
543
|
+
this.restoreNodeProcesses = [];
|
|
544
|
+
this.ctx = ctx;
|
|
545
|
+
}
|
|
546
|
+
get originalCode() {
|
|
547
|
+
return this.ctx.code;
|
|
548
|
+
}
|
|
549
|
+
skipOriginalOffset(offset) {
|
|
550
|
+
this.consumedIndex += offset;
|
|
551
|
+
}
|
|
552
|
+
appendOriginal(index) {
|
|
553
|
+
if (this.consumedIndex >= index) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
this.offsets.push({
|
|
557
|
+
original: this.consumedIndex,
|
|
558
|
+
script: this.script.length
|
|
559
|
+
});
|
|
560
|
+
this.script += this.ctx.code.slice(this.consumedIndex, index);
|
|
561
|
+
this.consumedIndex = index;
|
|
562
|
+
}
|
|
563
|
+
appendScript(fragment) {
|
|
564
|
+
const start = this.script.length;
|
|
565
|
+
this.script += fragment;
|
|
566
|
+
this.fragments.push({ start, end: this.script.length });
|
|
567
|
+
}
|
|
568
|
+
addToken(type, range) {
|
|
569
|
+
if (range[0] >= range[1]) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
this.tokens.push(this.ctx.buildToken(type, range));
|
|
573
|
+
}
|
|
574
|
+
addRestoreNodeProcess(process2) {
|
|
575
|
+
this.restoreNodeProcesses.push(process2);
|
|
576
|
+
}
|
|
577
|
+
restore(result) {
|
|
578
|
+
var _a, _b;
|
|
579
|
+
const traversed = /* @__PURE__ */ new Map();
|
|
580
|
+
traverseNodes(result.ast, {
|
|
581
|
+
visitorKeys: result.visitorKeys,
|
|
582
|
+
enterNode: (node, p) => {
|
|
583
|
+
if (!traversed.has(node)) {
|
|
584
|
+
traversed.set(node, p);
|
|
585
|
+
this.remapLocation(node);
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
leaveNode: (_node) => {
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
const tokens = [...this.tokens];
|
|
592
|
+
for (const token of result.ast.tokens || []) {
|
|
593
|
+
if (this.fragments.some(
|
|
594
|
+
(f) => f.start <= token.range[0] && token.range[1] <= f.end
|
|
595
|
+
)) {
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
this.remapLocation(token);
|
|
599
|
+
tokens.push(token);
|
|
600
|
+
}
|
|
601
|
+
result.ast.tokens = tokens;
|
|
602
|
+
for (const token of result.ast.comments || []) {
|
|
603
|
+
this.remapLocation(token);
|
|
604
|
+
}
|
|
605
|
+
const context = new RestoreNodeProcessContext(result, traversed);
|
|
606
|
+
let restoreNodeProcesses = this.restoreNodeProcesses;
|
|
607
|
+
for (const [node, parent] of traversed) {
|
|
608
|
+
if (!parent)
|
|
609
|
+
continue;
|
|
610
|
+
restoreNodeProcesses = restoreNodeProcesses.filter(
|
|
611
|
+
(proc) => !proc(node, context)
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
if (context.removeTokens.size) {
|
|
615
|
+
const tokens2 = result.ast.tokens || [];
|
|
616
|
+
for (let index = tokens2.length - 1; index >= 0; index--) {
|
|
617
|
+
const token = tokens2[index];
|
|
618
|
+
for (const rt of context.removeTokens) {
|
|
619
|
+
if (rt(token)) {
|
|
620
|
+
tokens2.splice(index, 1);
|
|
621
|
+
context.removeTokens.delete(rt);
|
|
622
|
+
if (!context.removeTokens.size) {
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
const firstOffset = Math.min(
|
|
630
|
+
...[result.ast.body[0], (_a = result.ast.tokens) == null ? void 0 : _a[0], (_b = result.ast.comments) == null ? void 0 : _b[0]].filter(Boolean).map((t) => t.range[0])
|
|
631
|
+
);
|
|
632
|
+
if (firstOffset < result.ast.range[0]) {
|
|
633
|
+
result.ast.range[0] = firstOffset;
|
|
634
|
+
result.ast.loc.start = this.ctx.getLocFromIndex(firstOffset);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
remapLocation(node) {
|
|
638
|
+
let [start, end] = node.range;
|
|
639
|
+
const startFragment = this.fragments.find(
|
|
640
|
+
(f) => f.start <= start && start < f.end
|
|
641
|
+
);
|
|
642
|
+
if (startFragment) {
|
|
643
|
+
start = startFragment.end;
|
|
644
|
+
}
|
|
645
|
+
const endFragment = this.fragments.find(
|
|
646
|
+
(f) => f.start < end && end <= f.end
|
|
647
|
+
);
|
|
648
|
+
if (endFragment) {
|
|
649
|
+
end = endFragment.start;
|
|
650
|
+
}
|
|
651
|
+
if (end < start) {
|
|
652
|
+
const w = start;
|
|
653
|
+
start = end;
|
|
654
|
+
end = w;
|
|
655
|
+
}
|
|
656
|
+
const locs = this.ctx.getLocations(...this.getRemapRange(start, end));
|
|
657
|
+
node.loc = locs.loc;
|
|
658
|
+
node.range = locs.range;
|
|
659
|
+
if (node.start != null) {
|
|
660
|
+
delete node.start;
|
|
661
|
+
}
|
|
662
|
+
if (node.end != null) {
|
|
663
|
+
delete node.end;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
getRemapRange(start, end) {
|
|
667
|
+
if (!this.offsets.length) {
|
|
668
|
+
return [start, end];
|
|
669
|
+
}
|
|
670
|
+
let lastStart = this.offsets[0];
|
|
671
|
+
let lastEnd = this.offsets[0];
|
|
672
|
+
for (const offset of this.offsets) {
|
|
673
|
+
if (offset.script <= start) {
|
|
674
|
+
lastStart = offset;
|
|
675
|
+
}
|
|
676
|
+
if (offset.script < end) {
|
|
677
|
+
lastEnd = offset;
|
|
678
|
+
} else {
|
|
679
|
+
if (offset.script === end) {
|
|
680
|
+
const remapStart2 = lastStart.original + (start - lastStart.script);
|
|
681
|
+
if (this.tokens.some(
|
|
682
|
+
(t) => t.range[0] <= remapStart2 && offset.original <= t.range[1]
|
|
683
|
+
)) {
|
|
684
|
+
lastEnd = offset;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
const remapStart = lastStart.original + (start - lastStart.script);
|
|
691
|
+
const remapEnd = lastEnd.original + (end - lastEnd.script);
|
|
692
|
+
return [remapStart, remapEnd];
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/parser/process-template.ts
|
|
697
|
+
function processTemplate(ctx, resultTemplate) {
|
|
698
|
+
let uniqueIdSeq = 0;
|
|
699
|
+
const usedUniqueIds = /* @__PURE__ */ new Set();
|
|
700
|
+
const script = new ScriptContext(ctx);
|
|
701
|
+
let fragmentOpened = false;
|
|
702
|
+
function openRootFragment(startOffset) {
|
|
703
|
+
script.appendScript("<>");
|
|
704
|
+
fragmentOpened = true;
|
|
705
|
+
script.addRestoreNodeProcess((scriptNode, { result }) => {
|
|
706
|
+
if (scriptNode.type === AST_NODE_TYPES.ExpressionStatement && scriptNode.expression.type === AST_NODE_TYPES.JSXFragment && scriptNode.range[0] === startOffset && result.ast.body.includes(scriptNode)) {
|
|
707
|
+
const index = result.ast.body.indexOf(scriptNode);
|
|
708
|
+
const rootFragment = result.ast.body[index] = scriptNode.expression;
|
|
709
|
+
delete rootFragment.closingFragment;
|
|
710
|
+
delete rootFragment.openingFragment;
|
|
711
|
+
rootFragment.type = "AstroFragment";
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
return false;
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
walkElements(
|
|
718
|
+
resultTemplate.ast,
|
|
719
|
+
ctx.code,
|
|
720
|
+
(node, [parent]) => {
|
|
721
|
+
if (node.type === "frontmatter") {
|
|
722
|
+
const start = node.position.start.offset;
|
|
723
|
+
if (fragmentOpened) {
|
|
724
|
+
script.appendScript("</>;");
|
|
725
|
+
fragmentOpened = false;
|
|
726
|
+
}
|
|
727
|
+
script.appendOriginal(start);
|
|
728
|
+
script.skipOriginalOffset(3);
|
|
729
|
+
const end = getEndOffset(node, ctx);
|
|
730
|
+
const scriptStart = start + 3;
|
|
731
|
+
let scriptEnd = end - 3;
|
|
732
|
+
let endChar;
|
|
733
|
+
while (scriptStart < scriptEnd - 1 && (endChar = script.originalCode[scriptEnd - 1]) && !endChar.trim()) {
|
|
734
|
+
scriptEnd--;
|
|
735
|
+
}
|
|
736
|
+
script.appendOriginal(scriptEnd);
|
|
737
|
+
script.appendScript("\n;");
|
|
738
|
+
script.skipOriginalOffset(end - scriptEnd);
|
|
739
|
+
script.addRestoreNodeProcess((_scriptNode, { result }) => {
|
|
740
|
+
for (let index = 0; index < result.ast.body.length; index++) {
|
|
741
|
+
const st = result.ast.body[index];
|
|
742
|
+
if (st.type === AST_NODE_TYPES.EmptyStatement) {
|
|
743
|
+
if (st.range[0] === scriptEnd && st.range[1] <= end) {
|
|
744
|
+
result.ast.body.splice(index, 1);
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
return true;
|
|
750
|
+
});
|
|
751
|
+
script.addToken(AST_TOKEN_TYPES.Punctuator, [
|
|
752
|
+
node.position.start.offset,
|
|
753
|
+
node.position.start.offset + 3
|
|
754
|
+
]);
|
|
755
|
+
script.addToken(AST_TOKEN_TYPES.Punctuator, [end - 3, end]);
|
|
756
|
+
} else if (isTag(node)) {
|
|
757
|
+
if (parent.type === "expression") {
|
|
758
|
+
const index = parent.children.indexOf(node);
|
|
759
|
+
const before = parent.children[index - 1];
|
|
760
|
+
if (!before || !isTag(before)) {
|
|
761
|
+
const after = parent.children[index + 1];
|
|
762
|
+
if (after && (isTag(after) || after.type === "comment")) {
|
|
763
|
+
const start2 = node.position.start.offset;
|
|
764
|
+
script.appendOriginal(start2);
|
|
765
|
+
script.appendScript("<>");
|
|
766
|
+
script.addRestoreNodeProcess((scriptNode) => {
|
|
767
|
+
if (scriptNode.range[0] === start2 && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
|
|
768
|
+
delete scriptNode.openingFragment;
|
|
769
|
+
delete scriptNode.closingFragment;
|
|
770
|
+
const fragmentNode = scriptNode;
|
|
771
|
+
fragmentNode.type = "AstroFragment";
|
|
772
|
+
const last = fragmentNode.children[fragmentNode.children.length - 1];
|
|
773
|
+
if (fragmentNode.range[1] < last.range[1]) {
|
|
774
|
+
fragmentNode.range[1] = last.range[1];
|
|
775
|
+
fragmentNode.loc.end = ctx.getLocFromIndex(
|
|
776
|
+
fragmentNode.range[1]
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
return false;
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
const start = node.position.start.offset;
|
|
787
|
+
script.appendOriginal(start);
|
|
788
|
+
if (!fragmentOpened) {
|
|
789
|
+
openRootFragment(start);
|
|
790
|
+
}
|
|
791
|
+
for (const attr of node.attributes) {
|
|
792
|
+
if ((node.type === "component" || node.type === "fragment") && (attr.kind === "quoted" || attr.kind === "empty" || attr.kind === "expression" || attr.kind === "template-literal")) {
|
|
793
|
+
const colonIndex = attr.name.indexOf(":");
|
|
794
|
+
if (colonIndex >= 0) {
|
|
795
|
+
const start2 = attr.position.start.offset;
|
|
796
|
+
script.appendOriginal(start2 + colonIndex);
|
|
797
|
+
script.skipOriginalOffset(1);
|
|
798
|
+
script.appendScript(`_`);
|
|
799
|
+
script.addToken(AST_TOKEN_TYPES.JSXIdentifier, [
|
|
800
|
+
start2,
|
|
801
|
+
start2 + colonIndex
|
|
802
|
+
]);
|
|
803
|
+
script.addToken(AST_TOKEN_TYPES.Punctuator, [
|
|
804
|
+
start2 + colonIndex,
|
|
805
|
+
start2 + colonIndex + 1
|
|
806
|
+
]);
|
|
807
|
+
script.addToken(AST_TOKEN_TYPES.JSXIdentifier, [
|
|
808
|
+
start2 + colonIndex + 1,
|
|
809
|
+
start2 + attr.name.length
|
|
810
|
+
]);
|
|
811
|
+
script.addRestoreNodeProcess((scriptNode, context) => {
|
|
812
|
+
if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === start2) {
|
|
813
|
+
const baseNameNode = scriptNode.name;
|
|
814
|
+
const nsn = {
|
|
815
|
+
...baseNameNode,
|
|
816
|
+
type: AST_NODE_TYPES.JSXNamespacedName,
|
|
817
|
+
namespace: {
|
|
818
|
+
type: AST_NODE_TYPES.JSXIdentifier,
|
|
819
|
+
name: attr.name.slice(0, colonIndex),
|
|
820
|
+
...ctx.getLocations(
|
|
821
|
+
baseNameNode.range[0],
|
|
822
|
+
baseNameNode.range[0] + colonIndex
|
|
823
|
+
)
|
|
824
|
+
},
|
|
825
|
+
name: {
|
|
826
|
+
type: AST_NODE_TYPES.JSXIdentifier,
|
|
827
|
+
name: attr.name.slice(colonIndex + 1),
|
|
828
|
+
...ctx.getLocations(
|
|
829
|
+
baseNameNode.range[0] + colonIndex + 1,
|
|
830
|
+
baseNameNode.range[1]
|
|
831
|
+
)
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
scriptNode.name = nsn;
|
|
835
|
+
nsn.namespace.parent = nsn;
|
|
836
|
+
nsn.name.parent = nsn;
|
|
837
|
+
context.addRemoveToken(
|
|
838
|
+
(token) => token.range[0] === baseNameNode.range[0] && token.range[1] === baseNameNode.range[1]
|
|
839
|
+
);
|
|
840
|
+
return true;
|
|
841
|
+
}
|
|
842
|
+
return false;
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
if (attr.kind === "shorthand") {
|
|
847
|
+
const start2 = attr.position.start.offset;
|
|
848
|
+
script.appendOriginal(start2);
|
|
849
|
+
const jsxName = /[\s"'[\]{}]/u.test(attr.name) ? generateUniqueId(attr.name) : attr.name;
|
|
850
|
+
script.appendScript(`${jsxName}=`);
|
|
851
|
+
script.addRestoreNodeProcess((scriptNode) => {
|
|
852
|
+
if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === start2) {
|
|
853
|
+
const attrNode = scriptNode;
|
|
854
|
+
attrNode.type = "AstroShorthandAttribute";
|
|
855
|
+
const locs = ctx.getLocations(
|
|
856
|
+
...attrNode.value.expression.range
|
|
857
|
+
);
|
|
858
|
+
if (jsxName !== attr.name) {
|
|
859
|
+
attrNode.name.name = attr.name;
|
|
860
|
+
}
|
|
861
|
+
attrNode.name.range = locs.range;
|
|
862
|
+
attrNode.name.loc = locs.loc;
|
|
863
|
+
return true;
|
|
864
|
+
}
|
|
865
|
+
return false;
|
|
866
|
+
});
|
|
867
|
+
} else if (attr.kind === "template-literal") {
|
|
868
|
+
const attrStart = attr.position.start.offset;
|
|
869
|
+
const start2 = calcAttributeValueStartOffset(attr, ctx);
|
|
870
|
+
const end = calcAttributeEndOffset(attr, ctx);
|
|
871
|
+
script.appendOriginal(start2);
|
|
872
|
+
script.appendScript("{");
|
|
873
|
+
script.appendOriginal(end);
|
|
874
|
+
script.appendScript("}");
|
|
875
|
+
script.addRestoreNodeProcess((scriptNode) => {
|
|
876
|
+
if (scriptNode.type === AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === attrStart) {
|
|
877
|
+
const attrNode = scriptNode;
|
|
878
|
+
attrNode.type = "AstroTemplateLiteralAttribute";
|
|
879
|
+
return true;
|
|
880
|
+
}
|
|
881
|
+
return false;
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const closing = getSelfClosingTag(node, ctx);
|
|
886
|
+
if (closing && closing.end === ">") {
|
|
887
|
+
script.appendOriginal(closing.offset - 1);
|
|
888
|
+
script.appendScript("/");
|
|
889
|
+
}
|
|
890
|
+
if (node.name === "script" || node.name === "style") {
|
|
891
|
+
const text = node.children[0];
|
|
892
|
+
if (text && text.type === "text") {
|
|
893
|
+
const styleNodeStart = node.position.start.offset;
|
|
894
|
+
const start2 = text.position.start.offset;
|
|
895
|
+
script.appendOriginal(start2);
|
|
896
|
+
script.skipOriginalOffset(text.value.length);
|
|
897
|
+
script.addRestoreNodeProcess((scriptNode) => {
|
|
898
|
+
if (scriptNode.type === AST_NODE_TYPES.JSXElement && scriptNode.range[0] === styleNodeStart) {
|
|
899
|
+
const textNode = {
|
|
900
|
+
type: "AstroRawText",
|
|
901
|
+
value: text.value,
|
|
902
|
+
raw: text.value,
|
|
903
|
+
parent: scriptNode,
|
|
904
|
+
...ctx.getLocations(start2, start2 + text.value.length)
|
|
905
|
+
};
|
|
906
|
+
scriptNode.children = [textNode];
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
return false;
|
|
910
|
+
});
|
|
911
|
+
script.addToken(AST_TOKEN_TYPES.JSXText, [
|
|
912
|
+
start2,
|
|
913
|
+
start2 + text.value.length
|
|
914
|
+
]);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
} else if (node.type === "comment") {
|
|
918
|
+
const start = node.position.start.offset;
|
|
919
|
+
const end = getEndOffset(node, ctx);
|
|
920
|
+
const length = end - start;
|
|
921
|
+
script.appendOriginal(start);
|
|
922
|
+
if (!fragmentOpened) {
|
|
923
|
+
openRootFragment(start);
|
|
924
|
+
}
|
|
925
|
+
script.appendOriginal(start + 1);
|
|
926
|
+
script.appendScript(`></`);
|
|
927
|
+
script.skipOriginalOffset(length - 2);
|
|
928
|
+
script.appendOriginal(end);
|
|
929
|
+
script.addRestoreNodeProcess((scriptNode, context) => {
|
|
930
|
+
if (scriptNode.range[0] === start && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
|
|
931
|
+
delete scriptNode.children;
|
|
932
|
+
delete scriptNode.openingFragment;
|
|
933
|
+
delete scriptNode.closingFragment;
|
|
934
|
+
delete scriptNode.expression;
|
|
935
|
+
const commentNode = scriptNode;
|
|
936
|
+
commentNode.type = "AstroHTMLComment";
|
|
937
|
+
commentNode.value = node.value;
|
|
938
|
+
context.addRemoveToken(
|
|
939
|
+
(token) => token.value === "<" && token.range[0] === scriptNode.range[0]
|
|
940
|
+
);
|
|
941
|
+
context.addRemoveToken(
|
|
942
|
+
(token) => token.value === ">" && token.range[1] === scriptNode.range[1]
|
|
943
|
+
);
|
|
944
|
+
return true;
|
|
945
|
+
}
|
|
946
|
+
return false;
|
|
947
|
+
});
|
|
948
|
+
script.addToken("HTMLComment", [
|
|
949
|
+
start,
|
|
950
|
+
start + length
|
|
951
|
+
]);
|
|
952
|
+
} else if (node.type === "doctype") {
|
|
953
|
+
const start = node.position.start.offset;
|
|
954
|
+
const end = getEndOffset(node, ctx);
|
|
955
|
+
const length = end - start;
|
|
956
|
+
script.appendOriginal(start);
|
|
957
|
+
if (!fragmentOpened) {
|
|
958
|
+
openRootFragment(start);
|
|
959
|
+
}
|
|
960
|
+
script.appendOriginal(start + 1);
|
|
961
|
+
script.appendScript(`></`);
|
|
962
|
+
script.skipOriginalOffset(length - 2);
|
|
963
|
+
script.appendOriginal(end);
|
|
964
|
+
script.addRestoreNodeProcess((scriptNode, context) => {
|
|
965
|
+
if (scriptNode.range[0] === start && scriptNode.type === AST_NODE_TYPES.JSXFragment) {
|
|
966
|
+
delete scriptNode.children;
|
|
967
|
+
delete scriptNode.openingFragment;
|
|
968
|
+
delete scriptNode.closingFragment;
|
|
969
|
+
delete scriptNode.expression;
|
|
970
|
+
const doctypeNode = scriptNode;
|
|
971
|
+
doctypeNode.type = "AstroDoctype";
|
|
972
|
+
context.addRemoveToken(
|
|
973
|
+
(token) => token.value === "<" && token.range[0] === scriptNode.range[0]
|
|
974
|
+
);
|
|
975
|
+
context.addRemoveToken(
|
|
976
|
+
(token) => token.value === ">" && token.range[1] === scriptNode.range[1]
|
|
977
|
+
);
|
|
978
|
+
return true;
|
|
979
|
+
}
|
|
980
|
+
return false;
|
|
981
|
+
});
|
|
982
|
+
script.addToken("HTMLDocType", [start, end]);
|
|
983
|
+
} else {
|
|
984
|
+
const start = node.position.start.offset;
|
|
985
|
+
script.appendOriginal(start);
|
|
986
|
+
if (!fragmentOpened) {
|
|
987
|
+
openRootFragment(start);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
},
|
|
991
|
+
(node, [parent]) => {
|
|
992
|
+
if (isTag(node)) {
|
|
993
|
+
const closing = getSelfClosingTag(node, ctx);
|
|
994
|
+
if (!closing) {
|
|
995
|
+
const end = getEndTag(node, ctx);
|
|
996
|
+
if (!end) {
|
|
997
|
+
const offset = calcContentEndOffset(node, ctx);
|
|
998
|
+
script.appendOriginal(offset);
|
|
999
|
+
script.appendScript(`</${node.name}>`);
|
|
1000
|
+
script.addRestoreNodeProcess((scriptNode, context) => {
|
|
1001
|
+
const parent2 = context.getParent(scriptNode);
|
|
1002
|
+
if (scriptNode.range[0] === offset && scriptNode.type === AST_NODE_TYPES.JSXClosingElement && parent2.type === AST_NODE_TYPES.JSXElement) {
|
|
1003
|
+
parent2.closingElement = null;
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
return false;
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if ((isTag(node) || node.type === "comment") && parent.type === "expression") {
|
|
1012
|
+
const index = parent.children.indexOf(node);
|
|
1013
|
+
const after = parent.children[index + 1];
|
|
1014
|
+
if (!after || !isTag(after) && after.type !== "comment") {
|
|
1015
|
+
const before = parent.children[index - 1];
|
|
1016
|
+
if (before && (isTag(before) || before.type === "comment")) {
|
|
1017
|
+
const end = getEndOffset(node, ctx);
|
|
1018
|
+
script.appendOriginal(end);
|
|
1019
|
+
script.appendScript("</>");
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
);
|
|
1025
|
+
if (fragmentOpened) {
|
|
1026
|
+
const last = resultTemplate.ast.children[resultTemplate.ast.children.length - 1];
|
|
1027
|
+
const end = getEndOffset(last, ctx);
|
|
1028
|
+
script.appendOriginal(end);
|
|
1029
|
+
script.appendScript("</>");
|
|
1030
|
+
}
|
|
1031
|
+
script.appendOriginal(ctx.code.length);
|
|
1032
|
+
return script;
|
|
1033
|
+
function generateUniqueId(base) {
|
|
1034
|
+
let candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
|
|
1035
|
+
while (usedUniqueIds.has(candidate) || ctx.code.includes(candidate)) {
|
|
1036
|
+
candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
|
|
1037
|
+
}
|
|
1038
|
+
usedUniqueIds.add(candidate);
|
|
1039
|
+
return candidate;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// src/context/index.ts
|
|
1044
|
+
var Context = class {
|
|
1045
|
+
constructor(code) {
|
|
1046
|
+
this.locsMap = /* @__PURE__ */ new Map();
|
|
1047
|
+
this.state = {};
|
|
1048
|
+
this.locs = new LinesAndColumns(code);
|
|
1049
|
+
this.code = code;
|
|
1050
|
+
}
|
|
1051
|
+
getLocFromIndex(index) {
|
|
1052
|
+
let loc = this.locsMap.get(index);
|
|
1053
|
+
if (!loc) {
|
|
1054
|
+
loc = this.locs.getLocFromIndex(index);
|
|
1055
|
+
this.locsMap.set(index, loc);
|
|
1056
|
+
}
|
|
1057
|
+
return {
|
|
1058
|
+
line: loc.line,
|
|
1059
|
+
column: loc.column
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
getLocations(start, end) {
|
|
1063
|
+
return {
|
|
1064
|
+
range: [start, end],
|
|
1065
|
+
loc: {
|
|
1066
|
+
start: this.getLocFromIndex(start),
|
|
1067
|
+
end: this.getLocFromIndex(end)
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
buildToken(type, range) {
|
|
1072
|
+
return {
|
|
1073
|
+
type,
|
|
1074
|
+
value: this.getText(range),
|
|
1075
|
+
...this.getLocations(...range)
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
getText(range) {
|
|
1079
|
+
return this.code.slice(range[0], range[1]);
|
|
1080
|
+
}
|
|
1081
|
+
get originalAST() {
|
|
1082
|
+
return this.state.originalAST;
|
|
1083
|
+
}
|
|
1084
|
+
set originalAST(originalAST) {
|
|
1085
|
+
this.state.originalAST = originalAST;
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
var LinesAndColumns = class {
|
|
1089
|
+
constructor(origCode) {
|
|
1090
|
+
const len = origCode.length;
|
|
1091
|
+
const lineStartIndices = [0];
|
|
1092
|
+
const crs = [];
|
|
1093
|
+
let normalizedCode = "";
|
|
1094
|
+
for (let index = 0; index < len; ) {
|
|
1095
|
+
const c = origCode[index++];
|
|
1096
|
+
if (c === "\r") {
|
|
1097
|
+
const next = origCode[index++] || "";
|
|
1098
|
+
if (next === "\n") {
|
|
1099
|
+
normalizedCode += next;
|
|
1100
|
+
crs.push(index - 2);
|
|
1101
|
+
lineStartIndices.push(index);
|
|
1102
|
+
} else {
|
|
1103
|
+
normalizedCode += `
|
|
1104
|
+
${next}`;
|
|
1105
|
+
lineStartIndices.push(index - 1);
|
|
1106
|
+
}
|
|
1107
|
+
} else {
|
|
1108
|
+
normalizedCode += c;
|
|
1109
|
+
if (c === "\n") {
|
|
1110
|
+
lineStartIndices.push(index);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
this.lineStartIndices = lineStartIndices;
|
|
1115
|
+
this.normalizedLineFeed = new NormalizedLineFeed(normalizedCode, crs);
|
|
1116
|
+
}
|
|
1117
|
+
getLocFromIndex(index) {
|
|
1118
|
+
const lineNumber = sortedLastIndex(this.lineStartIndices, index);
|
|
1119
|
+
return {
|
|
1120
|
+
line: lineNumber,
|
|
1121
|
+
column: index - this.lineStartIndices[lineNumber - 1]
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
getIndexFromLoc(loc) {
|
|
1125
|
+
const lineStartIndex = this.lineStartIndices[loc.line - 1];
|
|
1126
|
+
const positionIndex = lineStartIndex + loc.column;
|
|
1127
|
+
return positionIndex;
|
|
1128
|
+
}
|
|
1129
|
+
getNormalizedLineFeed() {
|
|
1130
|
+
return this.normalizedLineFeed;
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
var NormalizedLineFeed = class {
|
|
1134
|
+
get needRemap() {
|
|
1135
|
+
return this.offsets.length > 0;
|
|
1136
|
+
}
|
|
1137
|
+
constructor(code, offsets) {
|
|
1138
|
+
this.code = code;
|
|
1139
|
+
this.offsets = offsets;
|
|
1140
|
+
if (offsets.length) {
|
|
1141
|
+
const cache = {};
|
|
1142
|
+
this.remapIndex = (index) => {
|
|
1143
|
+
let result = cache[index];
|
|
1144
|
+
if (result != null) {
|
|
1145
|
+
return result;
|
|
1146
|
+
}
|
|
1147
|
+
result = index;
|
|
1148
|
+
for (const offset of offsets) {
|
|
1149
|
+
if (offset < result) {
|
|
1150
|
+
result++;
|
|
1151
|
+
} else {
|
|
1152
|
+
break;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return cache[index] = result;
|
|
1156
|
+
};
|
|
1157
|
+
} else {
|
|
1158
|
+
this.remapIndex = (i) => i;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
function sortedLastIndex(array, value) {
|
|
1163
|
+
let lower = 0;
|
|
1164
|
+
let upper = array.length;
|
|
1165
|
+
while (lower < upper) {
|
|
1166
|
+
const mid = Math.floor(lower + (upper - lower) / 2);
|
|
1167
|
+
const target = array[mid];
|
|
1168
|
+
if (target < value) {
|
|
1169
|
+
lower = mid + 1;
|
|
1170
|
+
} else if (target > value) {
|
|
1171
|
+
upper = mid;
|
|
1172
|
+
} else {
|
|
1173
|
+
return mid + 1;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
return upper;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// src/parser/astro-parser/parse.ts
|
|
1180
|
+
import * as service from "astrojs-compiler-sync";
|
|
1181
|
+
function parse2(code, ctx) {
|
|
1182
|
+
const ast = service.parse(code, { position: true }).ast;
|
|
1183
|
+
if (!ast.children) {
|
|
1184
|
+
ast.children = [];
|
|
1185
|
+
}
|
|
1186
|
+
const htmlElement = ast.children.find(
|
|
1187
|
+
(n) => n.type === "element" && n.name === "html"
|
|
1188
|
+
);
|
|
1189
|
+
if (htmlElement) {
|
|
1190
|
+
adjustHTML(ast, htmlElement, ctx);
|
|
1191
|
+
}
|
|
1192
|
+
fixLocations(ast, ctx);
|
|
1193
|
+
return { ast };
|
|
1194
|
+
}
|
|
1195
|
+
function adjustHTML(ast, htmlElement, ctx) {
|
|
1196
|
+
var _a;
|
|
1197
|
+
const htmlEnd = ctx.code.indexOf("</html");
|
|
1198
|
+
if (htmlEnd == null) {
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
const hasTokenAfter = Boolean(ctx.code.slice(htmlEnd + 7).trim());
|
|
1202
|
+
const children = [...htmlElement.children];
|
|
1203
|
+
for (const child of children) {
|
|
1204
|
+
const offset = (_a = child.position) == null ? void 0 : _a.start.offset;
|
|
1205
|
+
if (hasTokenAfter && offset != null) {
|
|
1206
|
+
if (htmlEnd <= offset) {
|
|
1207
|
+
htmlElement.children.splice(htmlElement.children.indexOf(child), 1);
|
|
1208
|
+
ast.children.push(child);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
if (child.type === "element" && child.name === "body") {
|
|
1212
|
+
adjustHTMLBody(ast, htmlElement, htmlEnd, hasTokenAfter, child, ctx);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
function adjustHTMLBody(ast, htmlElement, htmlEnd, hasTokenAfterHtmlEnd, bodyElement, ctx) {
|
|
1217
|
+
var _a;
|
|
1218
|
+
const bodyEnd = ctx.code.indexOf("</body");
|
|
1219
|
+
if (bodyEnd == null) {
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
const hasTokenAfter = Boolean(ctx.code.slice(bodyEnd + 7, htmlEnd).trim());
|
|
1223
|
+
if (!hasTokenAfter && !hasTokenAfterHtmlEnd) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
const children = [...bodyElement.children];
|
|
1227
|
+
for (const child of children) {
|
|
1228
|
+
const offset = (_a = child.position) == null ? void 0 : _a.start.offset;
|
|
1229
|
+
if (offset != null) {
|
|
1230
|
+
if (bodyEnd <= offset) {
|
|
1231
|
+
if (hasTokenAfterHtmlEnd && htmlEnd <= offset) {
|
|
1232
|
+
bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
|
|
1233
|
+
ast.children.push(child);
|
|
1234
|
+
} else if (hasTokenAfter) {
|
|
1235
|
+
bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
|
|
1236
|
+
htmlElement.children.push(child);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
function fixLocations(node, ctx) {
|
|
1243
|
+
let start = 0;
|
|
1244
|
+
walk(
|
|
1245
|
+
node,
|
|
1246
|
+
ctx.code,
|
|
1247
|
+
(node2, [parent]) => {
|
|
1248
|
+
if (node2.type === "frontmatter") {
|
|
1249
|
+
start = node2.position.start.offset = tokenIndex(ctx, "---", start);
|
|
1250
|
+
if (!node2.position.end) {
|
|
1251
|
+
node2.position.end = {};
|
|
1252
|
+
}
|
|
1253
|
+
start = node2.position.end.offset = tokenIndex(ctx, "---", start + 3 + node2.value.length) + 3;
|
|
1254
|
+
} else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
|
|
1255
|
+
if (!node2.position) {
|
|
1256
|
+
node2.position = { start: {}, end: {} };
|
|
1257
|
+
}
|
|
1258
|
+
start = node2.position.start.offset = tokenIndex(ctx, "<", start);
|
|
1259
|
+
start += 1;
|
|
1260
|
+
start += node2.name.length;
|
|
1261
|
+
if (!node2.attributes.length) {
|
|
1262
|
+
start = calcStartTagEndOffset(node2, ctx);
|
|
1263
|
+
}
|
|
1264
|
+
} else if (node2.type === "attribute") {
|
|
1265
|
+
fixLocationForAttr(node2, ctx, start);
|
|
1266
|
+
start = calcAttributeEndOffset(node2, ctx);
|
|
1267
|
+
if (node2.position.end) {
|
|
1268
|
+
node2.position.end.offset = start;
|
|
1269
|
+
}
|
|
1270
|
+
} else if (node2.type === "comment") {
|
|
1271
|
+
node2.position.start.offset = tokenIndex(ctx, "<!--", start);
|
|
1272
|
+
start = calcCommentEndOffset(node2, ctx);
|
|
1273
|
+
if (node2.position.end) {
|
|
1274
|
+
node2.position.end.offset = start;
|
|
1275
|
+
}
|
|
1276
|
+
} else if (node2.type === "text") {
|
|
1277
|
+
if (parent.type === "element" && (parent.name === "script" || parent.name === "style")) {
|
|
1278
|
+
node2.position.start.offset = start;
|
|
1279
|
+
start = ctx.code.indexOf(`</${parent.name}`, start);
|
|
1280
|
+
if (start < 0) {
|
|
1281
|
+
start = ctx.code.length;
|
|
1282
|
+
}
|
|
1283
|
+
} else {
|
|
1284
|
+
const index = tokenIndexSafe(ctx.code, node2.value, start);
|
|
1285
|
+
if (index != null) {
|
|
1286
|
+
start = node2.position.start.offset = index;
|
|
1287
|
+
start += node2.value.length;
|
|
1288
|
+
} else {
|
|
1289
|
+
node2.position.start.offset = start;
|
|
1290
|
+
const value = node2.value.replace(/\s+/gu, "");
|
|
1291
|
+
for (const char of value) {
|
|
1292
|
+
const index2 = tokenIndex(ctx, char, start);
|
|
1293
|
+
start = index2 + 1;
|
|
1294
|
+
}
|
|
1295
|
+
start = skipSpaces(ctx.code, start);
|
|
1296
|
+
node2.value = ctx.code.slice(node2.position.start.offset, start);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
if (node2.position.end) {
|
|
1300
|
+
node2.position.end.offset = start;
|
|
1301
|
+
}
|
|
1302
|
+
} else if (node2.type === "expression") {
|
|
1303
|
+
start = node2.position.start.offset = tokenIndex(ctx, "{", start);
|
|
1304
|
+
start += 1;
|
|
1305
|
+
} else if (node2.type === "doctype") {
|
|
1306
|
+
if (!node2.position) {
|
|
1307
|
+
node2.position = { start: {}, end: {} };
|
|
1308
|
+
}
|
|
1309
|
+
if (!node2.position.end) {
|
|
1310
|
+
node2.position.end = {};
|
|
1311
|
+
}
|
|
1312
|
+
start = node2.position.start.offset = tokenIndex(ctx, "<!", start);
|
|
1313
|
+
start += 2;
|
|
1314
|
+
start = node2.position.end.offset = ctx.code.indexOf(">", start) + 1;
|
|
1315
|
+
} else if (node2.type === "root") {
|
|
1316
|
+
}
|
|
1317
|
+
},
|
|
1318
|
+
(node2, [parent]) => {
|
|
1319
|
+
if (node2.type === "attribute") {
|
|
1320
|
+
const attributes = parent.attributes;
|
|
1321
|
+
if (attributes[attributes.length - 1] === node2) {
|
|
1322
|
+
start = calcStartTagEndOffset(parent, ctx);
|
|
1323
|
+
}
|
|
1324
|
+
} else if (node2.type === "expression") {
|
|
1325
|
+
start = tokenIndex(ctx, "}", start) + 1;
|
|
1326
|
+
} else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
|
|
1327
|
+
if (!getSelfClosingTag(node2, ctx)) {
|
|
1328
|
+
const closeTagStart = tokenIndexSafe(
|
|
1329
|
+
ctx.code,
|
|
1330
|
+
`</${node2.name}`,
|
|
1331
|
+
start
|
|
1332
|
+
);
|
|
1333
|
+
if (closeTagStart != null) {
|
|
1334
|
+
start = closeTagStart + 2 + node2.name.length;
|
|
1335
|
+
start = tokenIndex(ctx, ">", start) + 1;
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
} else {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
if (node2.position.end) {
|
|
1342
|
+
node2.position.end.offset = start;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
function fixLocationForAttr(node, ctx, start) {
|
|
1348
|
+
if (node.kind === "empty") {
|
|
1349
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
1350
|
+
} else if (node.kind === "quoted") {
|
|
1351
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
1352
|
+
} else if (node.kind === "expression") {
|
|
1353
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
1354
|
+
} else if (node.kind === "shorthand") {
|
|
1355
|
+
node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
1356
|
+
} else if (node.kind === "spread") {
|
|
1357
|
+
node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
1358
|
+
} else if (node.kind === "template-literal") {
|
|
1359
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
1360
|
+
} else {
|
|
1361
|
+
throw new ParseError(
|
|
1362
|
+
`Unknown attr kind: ${node.kind}`,
|
|
1363
|
+
node.position.start.offset,
|
|
1364
|
+
ctx
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
function tokenIndex(ctx, token, position) {
|
|
1369
|
+
const index = tokenIndexSafe(ctx.code, token, position);
|
|
1370
|
+
if (index == null) {
|
|
1371
|
+
const start = token.trim() === token ? skipSpaces(ctx.code, position) : position;
|
|
1372
|
+
throw new ParseError(
|
|
1373
|
+
`Unknown token at ${start}, expected: ${JSON.stringify(
|
|
1374
|
+
token
|
|
1375
|
+
)}, actual: ${JSON.stringify(ctx.code.slice(start, start + 10))}`,
|
|
1376
|
+
start,
|
|
1377
|
+
ctx
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
return index;
|
|
1381
|
+
}
|
|
1382
|
+
function tokenIndexSafe(string, token, position) {
|
|
1383
|
+
const index = token.trim() === token ? skipSpaces(string, position) : position;
|
|
1384
|
+
if (string.startsWith(token, index)) {
|
|
1385
|
+
return index;
|
|
1386
|
+
}
|
|
1387
|
+
return null;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
// src/parser/lru-cache.ts
|
|
1391
|
+
var LruCache = class extends Map {
|
|
1392
|
+
constructor(capacity) {
|
|
1393
|
+
super();
|
|
1394
|
+
this.capacity = capacity;
|
|
1395
|
+
}
|
|
1396
|
+
get(key) {
|
|
1397
|
+
if (!this.has(key)) {
|
|
1398
|
+
return void 0;
|
|
1399
|
+
}
|
|
1400
|
+
const value = super.get(key);
|
|
1401
|
+
this.set(key, value);
|
|
1402
|
+
return value;
|
|
1403
|
+
}
|
|
1404
|
+
set(key, value) {
|
|
1405
|
+
this.delete(key);
|
|
1406
|
+
super.set(key, value);
|
|
1407
|
+
if (this.size > this.capacity) {
|
|
1408
|
+
this.deleteOldestEntry();
|
|
1409
|
+
}
|
|
1410
|
+
return this;
|
|
1411
|
+
}
|
|
1412
|
+
deleteOldestEntry() {
|
|
1413
|
+
for (const entry of this) {
|
|
1414
|
+
this.delete(entry[0]);
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1420
|
+
// src/parser/template.ts
|
|
1421
|
+
var lruCache = new LruCache(5);
|
|
1422
|
+
function parseTemplate(code) {
|
|
1423
|
+
const cache = lruCache.get(code);
|
|
1424
|
+
if (cache) {
|
|
1425
|
+
return cache;
|
|
1426
|
+
}
|
|
1427
|
+
const ctx = new Context(code);
|
|
1428
|
+
const normalized = ctx.locs.getNormalizedLineFeed();
|
|
1429
|
+
const ctxForAstro = normalized.needRemap ? new Context(normalized.code) : ctx;
|
|
1430
|
+
try {
|
|
1431
|
+
const result = parse2((normalized == null ? void 0 : normalized.code) ?? code, ctxForAstro);
|
|
1432
|
+
if (normalized.needRemap) {
|
|
1433
|
+
remap(result, normalized, code, ctxForAstro);
|
|
1434
|
+
ctx.originalAST = ctxForAstro.originalAST;
|
|
1435
|
+
}
|
|
1436
|
+
const templateResult = {
|
|
1437
|
+
result,
|
|
1438
|
+
context: ctx
|
|
1439
|
+
};
|
|
1440
|
+
lruCache.set(code, templateResult);
|
|
1441
|
+
return templateResult;
|
|
1442
|
+
} catch (e) {
|
|
1443
|
+
if (typeof e.pos === "number") {
|
|
1444
|
+
const err = new ParseError(e.message, normalized == null ? void 0 : normalized.remapIndex(e.pos), ctx);
|
|
1445
|
+
err.astroCompilerError = e;
|
|
1446
|
+
throw err;
|
|
1447
|
+
}
|
|
1448
|
+
throw e;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
function remap(result, normalized, originalCode, ctxForAstro) {
|
|
1452
|
+
const remapDataMap = /* @__PURE__ */ new Map();
|
|
1453
|
+
walk(
|
|
1454
|
+
result.ast,
|
|
1455
|
+
normalized.code,
|
|
1456
|
+
(node) => {
|
|
1457
|
+
const start = normalized.remapIndex(node.position.start.offset);
|
|
1458
|
+
let end, value;
|
|
1459
|
+
if (node.position.end) {
|
|
1460
|
+
end = normalized.remapIndex(node.position.end.offset);
|
|
1461
|
+
if (node.position.start.offset === start && node.position.end.offset === end) {
|
|
1462
|
+
return;
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
if (node.type === "text") {
|
|
1466
|
+
value = originalCode.slice(
|
|
1467
|
+
start,
|
|
1468
|
+
normalized.remapIndex(getEndOffset(node, ctxForAstro))
|
|
1469
|
+
);
|
|
1470
|
+
} else if (node.type === "comment") {
|
|
1471
|
+
value = originalCode.slice(
|
|
1472
|
+
start + 4,
|
|
1473
|
+
normalized.remapIndex(getEndOffset(node, ctxForAstro)) - 3
|
|
1474
|
+
);
|
|
1475
|
+
} else if (node.type === "attribute") {
|
|
1476
|
+
if (node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
|
|
1477
|
+
let valueStart = normalized.remapIndex(
|
|
1478
|
+
calcAttributeValueStartOffset(node, ctxForAstro)
|
|
1479
|
+
);
|
|
1480
|
+
let valueEnd = normalized.remapIndex(
|
|
1481
|
+
calcAttributeEndOffset(node, ctxForAstro)
|
|
1482
|
+
);
|
|
1483
|
+
if (node.kind !== "quoted" || originalCode[valueStart] === '"' || originalCode[valueStart] === "'") {
|
|
1484
|
+
valueStart++;
|
|
1485
|
+
valueEnd--;
|
|
1486
|
+
}
|
|
1487
|
+
value = originalCode.slice(valueStart, valueEnd);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
remapDataMap.set(node, {
|
|
1491
|
+
start,
|
|
1492
|
+
end,
|
|
1493
|
+
value
|
|
1494
|
+
});
|
|
1495
|
+
},
|
|
1496
|
+
(_node) => {
|
|
1497
|
+
}
|
|
1498
|
+
);
|
|
1499
|
+
for (const [node, remapData] of remapDataMap) {
|
|
1500
|
+
node.position.start.offset = remapData.start;
|
|
1501
|
+
if (node.position.end) {
|
|
1502
|
+
node.position.end.offset = remapData.end;
|
|
1503
|
+
}
|
|
1504
|
+
if (node.type === "text" || node.type === "comment" || node.type === "attribute" && node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
|
|
1505
|
+
node.value = remapData.value;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
// src/context/parser-options.ts
|
|
1511
|
+
import path3 from "path";
|
|
1512
|
+
import fs2 from "fs";
|
|
1513
|
+
|
|
1514
|
+
// src/context/resolve-parser/espree.ts
|
|
1515
|
+
import { createRequire as createRequire2 } from "module";
|
|
1516
|
+
import path2 from "path";
|
|
1517
|
+
var espreeCache = null;
|
|
1518
|
+
function isLinterPath(p) {
|
|
1519
|
+
return p.includes(`eslint${path2.sep}lib${path2.sep}linter${path2.sep}linter.js`) || p.includes(`eslint${path2.sep}lib${path2.sep}linter.js`);
|
|
1520
|
+
}
|
|
1521
|
+
function getEspree() {
|
|
1522
|
+
if (!espreeCache) {
|
|
1523
|
+
const linterPath = Object.keys(__require.cache || {}).find(isLinterPath);
|
|
1524
|
+
if (linterPath) {
|
|
1525
|
+
try {
|
|
1526
|
+
espreeCache = createRequire2(linterPath)("espree");
|
|
1527
|
+
} catch {
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
if (!espreeCache) {
|
|
1531
|
+
espreeCache = __require("espree");
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return espreeCache;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
// src/context/resolve-parser/index.ts
|
|
1538
|
+
function getParserForLang(attrs, parser) {
|
|
1539
|
+
if (parser) {
|
|
1540
|
+
if (typeof parser === "string" || isParserObject(parser)) {
|
|
1541
|
+
return parser;
|
|
1542
|
+
}
|
|
1543
|
+
if (typeof parser === "object") {
|
|
1544
|
+
const value = parser[attrs.lang || "js"];
|
|
1545
|
+
if (typeof value === "string" || isParserObject(value)) {
|
|
1546
|
+
return value;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
return "espree";
|
|
1551
|
+
}
|
|
1552
|
+
function getParser(attrs, parser) {
|
|
1553
|
+
const parserValue = getParserForLang(attrs, parser);
|
|
1554
|
+
if (isParserObject(parserValue)) {
|
|
1555
|
+
return parserValue;
|
|
1556
|
+
}
|
|
1557
|
+
if (parserValue !== "espree") {
|
|
1558
|
+
return __require(parserValue);
|
|
1559
|
+
}
|
|
1560
|
+
return getEspree();
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// src/context/parser-options.ts
|
|
1564
|
+
var ParserOptionsContext = class {
|
|
1565
|
+
constructor(options) {
|
|
1566
|
+
this.state = {};
|
|
1567
|
+
const parserOptions = {
|
|
1568
|
+
ecmaVersion: 2020,
|
|
1569
|
+
sourceType: "module",
|
|
1570
|
+
loc: true,
|
|
1571
|
+
range: true,
|
|
1572
|
+
raw: true,
|
|
1573
|
+
tokens: true,
|
|
1574
|
+
comment: true,
|
|
1575
|
+
eslintVisitorKeys: true,
|
|
1576
|
+
eslintScopeManager: true,
|
|
1577
|
+
...options || {}
|
|
1578
|
+
};
|
|
1579
|
+
parserOptions.ecmaFeatures = {
|
|
1580
|
+
...parserOptions.ecmaFeatures || {},
|
|
1581
|
+
jsx: true
|
|
1582
|
+
};
|
|
1583
|
+
parserOptions.sourceType = "module";
|
|
1584
|
+
if (parserOptions.ecmaVersion <= 5 || parserOptions.ecmaVersion == null) {
|
|
1585
|
+
parserOptions.ecmaVersion = 2015;
|
|
1586
|
+
}
|
|
1587
|
+
this.parserOptions = parserOptions;
|
|
1588
|
+
}
|
|
1589
|
+
getParser() {
|
|
1590
|
+
return getParser({}, this.parserOptions.parser);
|
|
1591
|
+
}
|
|
1592
|
+
isTypeScript() {
|
|
1593
|
+
var _a, _b;
|
|
1594
|
+
if (this.state.isTypeScript != null) {
|
|
1595
|
+
return this.state.isTypeScript;
|
|
1596
|
+
}
|
|
1597
|
+
const parserValue = getParserForLang({}, (_a = this.parserOptions) == null ? void 0 : _a.parser);
|
|
1598
|
+
if (maybeTSESLintParserObject(parserValue) || parserValue === "@typescript-eslint/parser") {
|
|
1599
|
+
return this.state.isTypeScript = true;
|
|
1600
|
+
}
|
|
1601
|
+
if (typeof parserValue !== "string") {
|
|
1602
|
+
return this.state.isTypeScript = false;
|
|
1603
|
+
}
|
|
1604
|
+
const parserName = parserValue;
|
|
1605
|
+
if (parserName.includes("@typescript-eslint/parser")) {
|
|
1606
|
+
let targetPath = parserName;
|
|
1607
|
+
while (targetPath) {
|
|
1608
|
+
const pkgPath = path3.join(targetPath, "package.json");
|
|
1609
|
+
if (fs2.existsSync(pkgPath)) {
|
|
1610
|
+
try {
|
|
1611
|
+
return this.state.isTypeScript = ((_b = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"))) == null ? void 0 : _b.name) === "@typescript-eslint/parser";
|
|
1612
|
+
} catch {
|
|
1613
|
+
return this.state.isTypeScript = false;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
const parent = path3.dirname(targetPath);
|
|
1617
|
+
if (targetPath === parent) {
|
|
1618
|
+
break;
|
|
1619
|
+
}
|
|
1620
|
+
targetPath = parent;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
return this.state.isTypeScript = false;
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
// src/parser/index.ts
|
|
1628
|
+
function parseForESLint(code, options) {
|
|
1629
|
+
const { result: resultTemplate, context: ctx } = parseTemplate(code);
|
|
1630
|
+
const scriptContext = processTemplate(ctx, resultTemplate);
|
|
1631
|
+
const parserOptions = new ParserOptionsContext(options);
|
|
1632
|
+
const resultScript = parseScript(scriptContext.script, ctx, parserOptions);
|
|
1633
|
+
scriptContext.restore(resultScript);
|
|
1634
|
+
sort(resultScript.ast.comments);
|
|
1635
|
+
sort(resultScript.ast.tokens);
|
|
1636
|
+
extractTokens(resultScript, ctx);
|
|
1637
|
+
resultScript.services = Object.assign(resultScript.services || {}, {
|
|
1638
|
+
isAstro: true,
|
|
1639
|
+
getAstroAst() {
|
|
1640
|
+
return resultTemplate.ast;
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
resultScript.visitorKeys = Object.assign({}, KEYS, resultScript.visitorKeys);
|
|
1644
|
+
return resultScript;
|
|
1645
|
+
}
|
|
1646
|
+
function extractTokens(ast, ctx) {
|
|
1647
|
+
if (!ast.ast.tokens) {
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
const useRanges = sort([...ast.ast.tokens, ...ast.ast.comments || []]).map(
|
|
1651
|
+
(t) => t.range
|
|
1652
|
+
);
|
|
1653
|
+
let range = useRanges.shift();
|
|
1654
|
+
for (let index = 0; index < ctx.code.length; index++) {
|
|
1655
|
+
while (range && range[1] <= index) {
|
|
1656
|
+
range = useRanges.shift();
|
|
1657
|
+
}
|
|
1658
|
+
if (range && range[0] <= index) {
|
|
1659
|
+
index = range[1] - 1;
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1662
|
+
const c = ctx.code[index];
|
|
1663
|
+
if (!c.trim()) {
|
|
1664
|
+
continue;
|
|
1665
|
+
}
|
|
1666
|
+
if (isPunctuator(c)) {
|
|
1667
|
+
ast.ast.tokens.push(
|
|
1668
|
+
ctx.buildToken(AST_TOKEN_TYPES2.Punctuator, [index, index + 1])
|
|
1669
|
+
);
|
|
1670
|
+
} else {
|
|
1671
|
+
ast.ast.tokens.push(
|
|
1672
|
+
ctx.buildToken(AST_TOKEN_TYPES2.Identifier, [index, index + 1])
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
sort(ast.ast.tokens);
|
|
1677
|
+
function isPunctuator(c) {
|
|
1678
|
+
return /^[^\w$]$/iu.test(c);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
// src/astro-tools/index.ts
|
|
1683
|
+
function parseTemplate2(code) {
|
|
1684
|
+
const parsed = parseTemplate(code);
|
|
1685
|
+
return {
|
|
1686
|
+
result: parsed.result,
|
|
1687
|
+
getEndOffset: (node) => getEndOffset(node, parsed.context),
|
|
1688
|
+
calcAttributeValueStartOffset: (node) => calcAttributeValueStartOffset(node, parsed.context),
|
|
1689
|
+
calcAttributeEndOffset: (node) => calcAttributeEndOffset(node, parsed.context),
|
|
1690
|
+
walk(parent, enter, leave) {
|
|
1691
|
+
walk(
|
|
1692
|
+
parent,
|
|
1693
|
+
code,
|
|
1694
|
+
enter,
|
|
1695
|
+
leave || (() => {
|
|
1696
|
+
})
|
|
1697
|
+
);
|
|
1698
|
+
},
|
|
1699
|
+
getLocFromIndex: (index) => parsed.context.getLocFromIndex(index),
|
|
1700
|
+
getIndexFromLoc: (loc) => parsed.context.locs.getIndexFromLoc(loc)
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
// src/ast/index.ts
|
|
1705
|
+
var ast_exports = {};
|
|
1706
|
+
|
|
1707
|
+
// src/index.ts
|
|
1708
|
+
function parseForESLint2(code, options) {
|
|
1709
|
+
return parseForESLint(code, options);
|
|
1710
|
+
}
|
|
1711
|
+
var VisitorKeys = KEYS;
|
|
1712
|
+
export {
|
|
1713
|
+
ast_exports as AST,
|
|
1714
|
+
ParseError,
|
|
1715
|
+
VisitorKeys,
|
|
1716
|
+
parseForESLint2 as parseForESLint,
|
|
1717
|
+
parseTemplate2 as parseTemplate,
|
|
1718
|
+
traverseNodes
|
|
1719
|
+
};
|