astro-eslint-parser 1.3.2 → 2.0.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.js DELETED
@@ -1,2960 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name2 in all)
10
- __defProp(target, name2, { get: all[name2], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- AST: () => ast_exports,
34
- ParseError: () => ParseError,
35
- VisitorKeys: () => VisitorKeys,
36
- meta: () => meta_exports,
37
- name: () => name,
38
- parseForESLint: () => parseForESLint2,
39
- parseTemplate: () => parseTemplate2,
40
- traverseNodes: () => traverseNodes
41
- });
42
- module.exports = __toCommonJS(index_exports);
43
-
44
- // src/visitor-keys.ts
45
- var import_eslint_visitor_keys = require("eslint-visitor-keys");
46
- var astroKeys = {
47
- Program: ["body"],
48
- AstroFragment: ["children"],
49
- AstroHTMLComment: [],
50
- AstroDoctype: [],
51
- AstroShorthandAttribute: ["name", "value"],
52
- AstroTemplateLiteralAttribute: ["name", "value"],
53
- AstroRawText: []
54
- };
55
- var KEYS = (0, import_eslint_visitor_keys.unionWith)(
56
- astroKeys
57
- );
58
-
59
- // src/parser/index.ts
60
- var import_types3 = require("@typescript-eslint/types");
61
-
62
- // src/debug.ts
63
- var import_debug = __toESM(require("debug"));
64
- var debug = (0, import_debug.default)("astro-eslint-parser");
65
-
66
- // src/parser/ts-patch.ts
67
- var import_module2 = require("module");
68
- var import_path2 = __toESM(require("path"));
69
- var import_fs = __toESM(require("fs"));
70
- var import_semver = require("semver");
71
-
72
- // src/parser/ts-for-v5/get-project-config-files.ts
73
- var fs = __toESM(require("fs"));
74
- var path = __toESM(require("path"));
75
- function getProjectConfigFiles(parseSettings, project) {
76
- if (project !== true) {
77
- return project === void 0 || Array.isArray(project) ? project : [project];
78
- }
79
- let directory = path.dirname(parseSettings.filePath);
80
- const checkedDirectories = [directory];
81
- do {
82
- const tsconfigPath = path.join(directory, "tsconfig.json");
83
- const cached = fs.existsSync(tsconfigPath) && tsconfigPath;
84
- if (cached) {
85
- return [cached];
86
- }
87
- directory = path.dirname(directory);
88
- checkedDirectories.push(directory);
89
- } while (directory.length > 1 && directory.length >= parseSettings.tsconfigRootDir.length);
90
- throw new Error(
91
- `project was set to \`true\` but couldn't find any tsconfig.json relative to '${parseSettings.filePath}' within '${parseSettings.tsconfigRootDir}'.`
92
- );
93
- }
94
-
95
- // src/parser/ts-for-v5/programs.ts
96
- var import_path = __toESM(require("path"));
97
- var tsServices = /* @__PURE__ */ new Map();
98
- function getTSProgram(code, options, ts) {
99
- const tsconfigPath = options.project;
100
- let service2 = tsServices.get(tsconfigPath);
101
- if (!service2) {
102
- service2 = new TSService(tsconfigPath, ts);
103
- tsServices.set(tsconfigPath, service2);
104
- }
105
- return service2.getProgram(code, options.filePath);
106
- }
107
- var TSService = class {
108
- constructor(tsconfigPath, ts) {
109
- this.patchedHostSet = /* @__PURE__ */ new WeakSet();
110
- this.currTarget = {
111
- code: "",
112
- filePath: ""
113
- };
114
- this.fileWatchCallbacks = /* @__PURE__ */ new Map();
115
- this.ts = ts;
116
- this.watch = this.createWatch(tsconfigPath);
117
- }
118
- getProgram(code, filePath) {
119
- const normalized = normalizeFileName(this.ts, filePath);
120
- const lastTarget = this.currTarget;
121
- this.currTarget = {
122
- code,
123
- filePath: normalized
124
- };
125
- for (const { filePath: targetPath } of [this.currTarget, lastTarget]) {
126
- if (!targetPath) continue;
127
- this.fileWatchCallbacks.get(targetPath)?.update();
128
- }
129
- const program = this.watch.getProgram().getProgram();
130
- program.getTypeChecker();
131
- return program;
132
- }
133
- createWatch(tsconfigPath) {
134
- const { ts } = this;
135
- const createAbstractBuilder = (...buildArgs) => {
136
- const [
137
- rootNames,
138
- options,
139
- argHost,
140
- oldProgram,
141
- configFileParsingDiagnostics,
142
- projectReferences
143
- ] = buildArgs;
144
- const host = argHost;
145
- if (!this.patchedHostSet.has(host)) {
146
- this.patchedHostSet.add(host);
147
- const getTargetSourceFile = (fileName, languageVersionOrOptions) => {
148
- var _a;
149
- if (this.currTarget.filePath === normalizeFileName(ts, fileName)) {
150
- return (_a = this.currTarget).sourceFile ?? (_a.sourceFile = ts.createSourceFile(
151
- this.currTarget.filePath,
152
- this.currTarget.code,
153
- languageVersionOrOptions,
154
- true,
155
- ts.ScriptKind.TSX
156
- ));
157
- }
158
- return null;
159
- };
160
- const original2 = {
161
- getSourceFile: host.getSourceFile,
162
- getSourceFileByPath: host.getSourceFileByPath
163
- };
164
- host.getSourceFile = (fileName, languageVersionOrOptions, ...args) => {
165
- const originalSourceFile = original2.getSourceFile.call(
166
- host,
167
- fileName,
168
- languageVersionOrOptions,
169
- ...args
170
- );
171
- return getTargetSourceFile(fileName, languageVersionOrOptions) ?? originalSourceFile;
172
- };
173
- host.getSourceFileByPath = (fileName, filePath, languageVersionOrOptions, ...args) => {
174
- const originalSourceFile = original2.getSourceFileByPath.call(
175
- host,
176
- fileName,
177
- filePath,
178
- languageVersionOrOptions,
179
- ...args
180
- );
181
- return getTargetSourceFile(fileName, languageVersionOrOptions) ?? originalSourceFile;
182
- };
183
- }
184
- return ts.createAbstractBuilder(
185
- rootNames,
186
- options,
187
- host,
188
- oldProgram,
189
- configFileParsingDiagnostics,
190
- projectReferences
191
- );
192
- };
193
- const watchCompilerHost = ts.createWatchCompilerHost(
194
- tsconfigPath,
195
- {
196
- noEmit: true,
197
- jsx: ts.JsxEmit.Preserve,
198
- // This option is required if `includes` only includes `*.astro` files.
199
- // However, the option is not in the documentation.
200
- // https://github.com/microsoft/TypeScript/issues/28447
201
- allowNonTsExtensions: true
202
- },
203
- ts.sys,
204
- createAbstractBuilder,
205
- (diagnostic) => {
206
- throw new Error(formatDiagnostics(ts, [diagnostic]));
207
- },
208
- () => {
209
- },
210
- void 0,
211
- [
212
- {
213
- extension: ".astro",
214
- isMixedContent: true,
215
- scriptKind: ts.ScriptKind.Deferred
216
- }
217
- ]
218
- );
219
- const original = {
220
- readFile: watchCompilerHost.readFile
221
- };
222
- watchCompilerHost.readFile = (fileName, ...args) => {
223
- const normalized = normalizeFileName(ts, fileName);
224
- if (this.currTarget.filePath === normalized) {
225
- return this.currTarget.code;
226
- }
227
- return original.readFile.call(watchCompilerHost, fileName, ...args);
228
- };
229
- watchCompilerHost.watchFile = (fileName, callback) => {
230
- const normalized = normalizeFileName(ts, fileName);
231
- this.fileWatchCallbacks.set(normalized, {
232
- update: () => callback(fileName, ts.FileWatcherEventKind.Changed)
233
- });
234
- return {
235
- close: () => {
236
- this.fileWatchCallbacks.delete(normalized);
237
- }
238
- };
239
- };
240
- watchCompilerHost.watchDirectory = () => {
241
- return {
242
- close: () => {
243
- }
244
- };
245
- };
246
- watchCompilerHost.afterProgramCreate = (program) => {
247
- const originalDiagnostics = program.getConfigFileParsingDiagnostics();
248
- const configFileDiagnostics = originalDiagnostics.filter(
249
- (diag) => diag.category === ts.DiagnosticCategory.Error && diag.code !== 18003
250
- );
251
- if (configFileDiagnostics.length > 0) {
252
- throw new Error(formatDiagnostics(ts, configFileDiagnostics));
253
- }
254
- };
255
- const watch = ts.createWatchProgram(watchCompilerHost);
256
- return watch;
257
- }
258
- };
259
- function formatDiagnostics(ts, diagnostics) {
260
- return ts.formatDiagnostics(diagnostics, {
261
- getCanonicalFileName: (f) => f,
262
- getCurrentDirectory: () => process.cwd(),
263
- getNewLine: () => "\n"
264
- });
265
- }
266
- function normalizeFileName(ts, fileName) {
267
- let normalized = import_path.default.normalize(fileName);
268
- if (normalized.endsWith(import_path.default.sep)) {
269
- normalized = normalized.slice(0, -1);
270
- }
271
- if (ts.sys.useCaseSensitiveFileNames) {
272
- return toAbsolutePath(normalized, null);
273
- }
274
- return toAbsolutePath(normalized.toLowerCase(), null);
275
- }
276
- function toAbsolutePath(filePath, baseDir) {
277
- return import_path.default.isAbsolute(filePath) ? filePath : import_path.default.join(baseDir || process.cwd(), filePath);
278
- }
279
-
280
- // src/parser/ts-for-v5/resolve-project-list.ts
281
- var import_fast_glob = require("fast-glob");
282
- var import_is_glob = __toESM(require("is-glob"));
283
- var path3 = __toESM(require("path"));
284
- var import_module = require("module");
285
- function resolveProjectList(options) {
286
- const sanitizedProjects = [];
287
- if (typeof options.project === "string") {
288
- sanitizedProjects.push(options.project);
289
- } else if (Array.isArray(options.project)) {
290
- for (const project of options.project) {
291
- if (typeof project === "string") {
292
- sanitizedProjects.push(project);
293
- }
294
- }
295
- }
296
- if (sanitizedProjects.length === 0) {
297
- return [];
298
- }
299
- const projectFolderIgnoreList = (options.projectFolderIgnoreList ?? ["**/node_modules/**"]).reduce((acc, folder) => {
300
- if (typeof folder === "string") {
301
- acc.push(folder);
302
- }
303
- return acc;
304
- }, []).map((folder) => folder.startsWith("!") ? folder : `!${folder}`);
305
- const nonGlobProjects = sanitizedProjects.filter(
306
- (project) => !(0, import_is_glob.default)(project)
307
- );
308
- const globProjects = sanitizedProjects.filter((project) => (0, import_is_glob.default)(project));
309
- const uniqueCanonicalProjectPaths = new Set(
310
- nonGlobProjects.concat(
311
- globProjects.length === 0 ? [] : (0, import_fast_glob.sync)([...globProjects, ...projectFolderIgnoreList], {
312
- cwd: options.tsconfigRootDir
313
- })
314
- ).map(
315
- (project) => getCanonicalFileName(
316
- ensureAbsolutePath(project, options.tsconfigRootDir)
317
- )
318
- )
319
- );
320
- const returnValue = Array.from(uniqueCanonicalProjectPaths);
321
- return returnValue;
322
- }
323
- var _correctPathCasing;
324
- function correctPathCasing(filePath) {
325
- if (_correctPathCasing === void 0) {
326
- const ts = (0, import_module.createRequire)(
327
- path3.join(process.cwd(), "__placeholder__.js")
328
- )("typescript");
329
- const useCaseSensitiveFileNames = ts.sys !== void 0 ? ts.sys.useCaseSensitiveFileNames : true;
330
- _correctPathCasing = useCaseSensitiveFileNames ? (f) => f : (f) => f.toLowerCase();
331
- }
332
- return _correctPathCasing(filePath);
333
- }
334
- function getCanonicalFileName(filePath) {
335
- let normalized = path3.normalize(filePath);
336
- if (normalized.endsWith(path3.sep)) {
337
- normalized = normalized.slice(0, -1);
338
- }
339
- return correctPathCasing(normalized);
340
- }
341
- function ensureAbsolutePath(p, tsconfigRootDir) {
342
- return path3.isAbsolute(p) ? p : path3.join(tsconfigRootDir || process.cwd(), p);
343
- }
344
-
345
- // src/parser/ts-for-v5/parse-tsx-for-typescript.ts
346
- var DEFAULT_EXTRA_FILE_EXTENSIONS = [".vue", ".svelte", ".astro"];
347
- function parseTsxForTypeScript(code, options, tsEslintParser, ts) {
348
- const programs = [];
349
- for (const option of iterateOptions(options)) {
350
- programs.push(getTSProgram(code, option, ts));
351
- }
352
- const parserOptions = {
353
- ...options,
354
- programs
355
- };
356
- return tsEslintParser.parseForESLint(code, parserOptions);
357
- }
358
- function* iterateOptions(options) {
359
- if (!options) {
360
- throw new Error("`parserOptions` is required.");
361
- }
362
- if (!options.filePath) {
363
- throw new Error("`filePath` is required.");
364
- }
365
- if (!options.project) {
366
- throw new Error(
367
- "Specify `parserOptions.project`. Otherwise there is no point in using this parser."
368
- );
369
- }
370
- const tsconfigRootDir = typeof options.tsconfigRootDir === "string" ? options.tsconfigRootDir : process.cwd();
371
- const projects = resolveProjectList({
372
- project: getProjectConfigFiles(
373
- { tsconfigRootDir, filePath: options.filePath },
374
- options.project
375
- ),
376
- projectFolderIgnoreList: options.projectFolderIgnoreList,
377
- tsconfigRootDir
378
- });
379
- for (const project of projects) {
380
- yield {
381
- project,
382
- filePath: options.filePath,
383
- extraFileExtensions: options.extraFileExtensions || DEFAULT_EXTRA_FILE_EXTENSIONS
384
- };
385
- }
386
- }
387
-
388
- // src/parser/ts-patch.ts
389
- function tsPatch(scriptParserOptions, tsParserName) {
390
- if (tsParserName === "typescript-eslint-parser-for-extra-files") {
391
- return {
392
- terminate() {
393
- }
394
- };
395
- }
396
- let targetExt = ".astro";
397
- if (scriptParserOptions.filePath) {
398
- const ext = import_path2.default.extname(scriptParserOptions.filePath);
399
- if (ext) {
400
- targetExt = ext;
401
- }
402
- }
403
- try {
404
- const cwd = process.cwd();
405
- const relativeTo = import_path2.default.join(cwd, "__placeholder__.js");
406
- const ts = (0, import_module2.createRequire)(relativeTo)("typescript");
407
- if ((0, import_semver.satisfies)(ts.version, ">=5")) {
408
- const result = tsPatchForV5(ts, scriptParserOptions);
409
- if (result) {
410
- return result;
411
- }
412
- } else {
413
- const result = tsPatchForV4(ts, targetExt);
414
- if (result) {
415
- return result;
416
- }
417
- }
418
- } catch {
419
- }
420
- const tsxFilePath = `${scriptParserOptions.filePath}.tsx`;
421
- scriptParserOptions.filePath = tsxFilePath;
422
- if (!import_fs.default.existsSync(tsxFilePath)) {
423
- import_fs.default.writeFileSync(tsxFilePath, "/* temp for astro-eslint-parser */");
424
- return {
425
- terminate() {
426
- import_fs.default.unlinkSync(tsxFilePath);
427
- }
428
- };
429
- }
430
- return null;
431
- }
432
- function tsPatchForV5(ts, scriptParserOptions) {
433
- return {
434
- terminate() {
435
- },
436
- parse(code, parser) {
437
- return parseTsxForTypeScript(
438
- code,
439
- scriptParserOptions,
440
- parser,
441
- ts
442
- );
443
- }
444
- };
445
- }
446
- function tsPatchForV4(ts, targetExt) {
447
- const { ensureScriptKind, getScriptKindFromFileName } = ts;
448
- if (typeof ensureScriptKind !== "function" || typeof getScriptKindFromFileName !== "function") {
449
- return null;
450
- }
451
- ts.ensureScriptKind = function(fileName, ...args) {
452
- if (fileName.endsWith(targetExt)) {
453
- return ts.ScriptKind.TSX;
454
- }
455
- return ensureScriptKind.call(this, fileName, ...args);
456
- };
457
- ts.getScriptKindFromFileName = function(fileName, ...args) {
458
- if (fileName.endsWith(targetExt)) {
459
- return ts.ScriptKind.TSX;
460
- }
461
- return getScriptKindFromFileName.call(this, fileName, ...args);
462
- };
463
- if (ts.ensureScriptKind === ensureScriptKind || ts.getScriptKindFromFileName === getScriptKindFromFileName) {
464
- return null;
465
- }
466
- return {
467
- terminate() {
468
- ts.ensureScriptKind = ensureScriptKind;
469
- ts.getScriptKindFromFileName = getScriptKindFromFileName;
470
- }
471
- };
472
- }
473
-
474
- // src/context/resolve-parser/parser-object.ts
475
- function isParserObject(value) {
476
- return isEnhancedParserObject(value) || isBasicParserObject(value);
477
- }
478
- function isEnhancedParserObject(value) {
479
- return Boolean(value && typeof value.parseForESLint === "function");
480
- }
481
- function isBasicParserObject(value) {
482
- return Boolean(value && typeof value.parse === "function");
483
- }
484
- function maybeTSESLintParserObject(value) {
485
- return isEnhancedParserObject(value) && isBasicParserObject(value) && typeof value.createProgram === "function" && typeof value.clearCaches === "function" && typeof value.version === "string";
486
- }
487
- function getTSParserNameFromObject(value) {
488
- if (!isEnhancedParserObject(value)) {
489
- return null;
490
- }
491
- if (value.name === "typescript-eslint-parser-for-extra-files")
492
- return "typescript-eslint-parser-for-extra-files";
493
- if (value.meta?.name === "typescript-eslint/parser")
494
- return "@typescript-eslint/parser";
495
- return null;
496
- }
497
- function isTSESLintParserObject(value) {
498
- if (!isEnhancedParserObject(value)) return false;
499
- if (value.name === "typescript-eslint-parser-for-extra-files")
500
- return true;
501
- if (value.meta?.name === "typescript-eslint/parser") return true;
502
- try {
503
- const result = value.parseForESLint("", {});
504
- const services = result.services;
505
- return Boolean(
506
- services && services.esTreeNodeToTSNodeMap && services.tsNodeToESTreeNodeMap && services.program
507
- );
508
- } catch {
509
- return false;
510
- }
511
- }
512
-
513
- // src/parser/script.ts
514
- var import_types = require("@typescript-eslint/types");
515
- var import_scope_manager2 = require("@typescript-eslint/scope-manager");
516
-
517
- // src/traverse.ts
518
- function fallbackKeysFilter(key) {
519
- let value = null;
520
- 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));
521
- }
522
- function getFallbackKeys(node) {
523
- return Object.keys(node).filter(fallbackKeysFilter, node);
524
- }
525
- function getKeys(node, visitorKeys) {
526
- const keys = (visitorKeys || KEYS)[node.type] || getFallbackKeys(node);
527
- return keys.filter((key) => !getNodes(node, key).next().done);
528
- }
529
- function* getNodes(node, key) {
530
- const child = node[key];
531
- if (Array.isArray(child)) {
532
- for (const c of child) {
533
- if (isNode(c)) {
534
- yield c;
535
- }
536
- }
537
- } else if (isNode(child)) {
538
- yield child;
539
- }
540
- }
541
- function isNode(x) {
542
- return x !== null && typeof x === "object" && typeof x.type === "string";
543
- }
544
- function traverse(node, parent, visitor) {
545
- visitor.enterNode(node, parent);
546
- const keys = getKeys(node, visitor.visitorKeys);
547
- for (const key of keys) {
548
- for (const child of getNodes(node, key)) {
549
- traverse(child, node, visitor);
550
- }
551
- }
552
- visitor.leaveNode(node, parent);
553
- }
554
- function traverseNodes(node, visitor) {
555
- traverse(node, null, visitor);
556
- }
557
-
558
- // src/parser/scope/index.ts
559
- var import_scope_manager = require("@typescript-eslint/scope-manager");
560
-
561
- // src/util/index.ts
562
- function sortedLastIndex(array, compare) {
563
- let lower = 0;
564
- let upper = array.length;
565
- while (lower < upper) {
566
- const mid = Math.floor(lower + (upper - lower) / 2);
567
- const target = compare(array[mid]);
568
- if (target < 0) {
569
- lower = mid + 1;
570
- } else if (target > 0) {
571
- upper = mid;
572
- } else {
573
- return mid + 1;
574
- }
575
- }
576
- return upper;
577
- }
578
- function addElementToSortedArray(array, element, compare) {
579
- const index = sortedLastIndex(array, (target) => compare(target, element));
580
- array.splice(index, 0, element);
581
- }
582
- function addElementsToSortedArray(array, elements, compare) {
583
- if (!elements.length) {
584
- return;
585
- }
586
- let last = elements[0];
587
- let index = sortedLastIndex(array, (target) => compare(target, last));
588
- for (const element of elements) {
589
- if (compare(last, element) > 0) {
590
- index = sortedLastIndex(array, (target) => compare(target, element));
591
- }
592
- let e = array[index];
593
- while (e && compare(e, element) <= 0) {
594
- e = array[++index];
595
- }
596
- array.splice(index, 0, element);
597
- last = element;
598
- }
599
- }
600
-
601
- // src/parser/scope/index.ts
602
- var READ_FLAG = 1;
603
- var WRITE_FLAG = 2;
604
- var READ_WRITE_FLAG = 3;
605
- var REFERENCE_TYPE_VALUE_FLAG = 1;
606
- var REFERENCE_TYPE_TYPE_FLAG = 2;
607
- function getProgramScope(scopeManager) {
608
- const globalScope = scopeManager.globalScope;
609
- return globalScope.childScopes.find((s) => s.type === "module") || globalScope;
610
- }
611
- function removeAllScopeAndVariableAndReference(target, info) {
612
- const removeTargetScopes = /* @__PURE__ */ new Set();
613
- traverseNodes(target, {
614
- visitorKeys: info.visitorKeys,
615
- enterNode(node) {
616
- const scope = info.scopeManager.acquire(node);
617
- if (scope) {
618
- removeTargetScopes.add(scope);
619
- return;
620
- }
621
- if (node.type === "Identifier" || node.type === "JSXIdentifier") {
622
- let targetScope = getInnermostScopeFromNode(info.scopeManager, node);
623
- while (targetScope && targetScope.block.type !== "Program" && target.range[0] <= targetScope.block.range[0] && targetScope.block.range[1] <= target.range[1]) {
624
- targetScope = targetScope.upper;
625
- }
626
- if (removeTargetScopes.has(targetScope)) {
627
- return;
628
- }
629
- removeIdentifierVariable(node, targetScope);
630
- removeIdentifierReference(node, targetScope);
631
- }
632
- },
633
- leaveNode() {
634
- }
635
- });
636
- for (const scope of removeTargetScopes) {
637
- removeScope(info.scopeManager, scope);
638
- }
639
- }
640
- function addVirtualReference(node, variable, scope, status) {
641
- const reference = new import_scope_manager.Reference(
642
- node,
643
- scope,
644
- status.write && status.read ? READ_WRITE_FLAG : status.write ? WRITE_FLAG : READ_FLAG,
645
- void 0,
646
- // writeExpr
647
- void 0,
648
- // maybeImplicitGlobal
649
- void 0,
650
- // init
651
- status.typeRef ? REFERENCE_TYPE_TYPE_FLAG : REFERENCE_TYPE_VALUE_FLAG
652
- );
653
- reference.astroVirtualReference = true;
654
- addReference(variable.references, reference);
655
- reference.resolved = variable;
656
- if (status.forceUsed) {
657
- variable.eslintUsed = true;
658
- }
659
- return reference;
660
- }
661
- function addGlobalVariable(reference, scopeManager) {
662
- const globalScope = scopeManager.globalScope;
663
- const name2 = reference.identifier.name;
664
- let variable = globalScope.set.get(name2);
665
- if (!variable) {
666
- variable = new import_scope_manager.Variable(name2, globalScope);
667
- globalScope.variables.push(variable);
668
- globalScope.set.set(name2, variable);
669
- }
670
- reference.resolved = variable;
671
- variable.references.push(reference);
672
- return variable;
673
- }
674
- function removeReferenceFromThrough(reference, baseScope) {
675
- const variable = reference.resolved;
676
- const name2 = reference.identifier.name;
677
- let scope = baseScope;
678
- while (scope) {
679
- for (const ref of [...scope.through]) {
680
- if (reference === ref) {
681
- scope.through.splice(scope.through.indexOf(ref), 1);
682
- } else if (ref.identifier.name === name2) {
683
- ref.resolved = variable;
684
- if (!variable.references.includes(ref)) {
685
- addReference(variable.references, ref);
686
- }
687
- scope.through.splice(scope.through.indexOf(ref), 1);
688
- }
689
- }
690
- scope = scope.upper;
691
- }
692
- }
693
- function removeScope(scopeManager, scope) {
694
- for (const childScope of scope.childScopes) {
695
- removeScope(scopeManager, childScope);
696
- }
697
- while (scope.references[0]) {
698
- removeReference(scope.references[0], scope);
699
- }
700
- const upper = scope.upper;
701
- if (upper) {
702
- const index2 = upper.childScopes.indexOf(scope);
703
- if (index2 >= 0) {
704
- upper.childScopes.splice(index2, 1);
705
- }
706
- }
707
- const index = scopeManager.scopes.indexOf(scope);
708
- if (index >= 0) {
709
- scopeManager.scopes.splice(index, 1);
710
- }
711
- }
712
- function removeReference(reference, baseScope) {
713
- if (reference.resolved) {
714
- if (reference.resolved.defs.some((d) => d.name === reference.identifier)) {
715
- const varIndex = baseScope.variables.indexOf(reference.resolved);
716
- if (varIndex >= 0) {
717
- baseScope.variables.splice(varIndex, 1);
718
- }
719
- const name2 = reference.identifier.name;
720
- if (reference.resolved === baseScope.set.get(name2)) {
721
- baseScope.set.delete(name2);
722
- }
723
- } else {
724
- const refIndex = reference.resolved.references.indexOf(reference);
725
- if (refIndex >= 0) {
726
- reference.resolved.references.splice(refIndex, 1);
727
- }
728
- }
729
- }
730
- let scope = baseScope;
731
- while (scope) {
732
- const refIndex = scope.references.indexOf(reference);
733
- if (refIndex >= 0) {
734
- scope.references.splice(refIndex, 1);
735
- }
736
- const throughIndex = scope.through.indexOf(reference);
737
- if (throughIndex >= 0) {
738
- scope.through.splice(throughIndex, 1);
739
- }
740
- scope = scope.upper;
741
- }
742
- }
743
- function removeIdentifierVariable(node, scope) {
744
- for (let varIndex = 0; varIndex < scope.variables.length; varIndex++) {
745
- const variable = scope.variables[varIndex];
746
- const defIndex = variable.defs.findIndex((def) => def.name === node);
747
- if (defIndex < 0) {
748
- continue;
749
- }
750
- variable.defs.splice(defIndex, 1);
751
- if (variable.defs.length === 0) {
752
- referencesToThrough(variable.references, scope);
753
- variable.references.forEach((r) => {
754
- if (r.init) r.init = false;
755
- r.resolved = null;
756
- });
757
- scope.variables.splice(varIndex, 1);
758
- const name2 = node.name;
759
- if (variable === scope.set.get(name2)) {
760
- scope.set.delete(name2);
761
- }
762
- } else {
763
- const idIndex = variable.identifiers.indexOf(node);
764
- if (idIndex >= 0) {
765
- variable.identifiers.splice(idIndex, 1);
766
- }
767
- }
768
- return;
769
- }
770
- }
771
- function removeIdentifierReference(node, scope) {
772
- const reference = scope.references.find((ref) => ref.identifier === node);
773
- if (reference) {
774
- removeReference(reference, scope);
775
- return true;
776
- }
777
- const location = node.range[0];
778
- const pendingScopes = [];
779
- for (const childScope of scope.childScopes) {
780
- const range = childScope.block.range;
781
- if (range[0] <= location && location < range[1]) {
782
- if (removeIdentifierReference(node, childScope)) {
783
- return true;
784
- }
785
- } else {
786
- pendingScopes.push(childScope);
787
- }
788
- }
789
- for (const childScope of pendingScopes) {
790
- if (removeIdentifierReference(node, childScope)) {
791
- return true;
792
- }
793
- }
794
- return false;
795
- }
796
- function getInnermostScopeFromNode(scopeManager, currentNode) {
797
- return getInnermostScope(
798
- getScopeFromNode(scopeManager, currentNode),
799
- currentNode
800
- );
801
- }
802
- function getScopeFromNode(scopeManager, currentNode) {
803
- let node = currentNode;
804
- for (; node; node = node.parent || null) {
805
- const scope = scopeManager.acquire(node, false);
806
- if (scope) {
807
- if (scope.type === "function-expression-name") {
808
- return scope.childScopes[0];
809
- }
810
- if (scope.type === "global" && node.type === "Program" && node.sourceType === "module") {
811
- return scope.childScopes.find((s) => s.type === "module") || scope;
812
- }
813
- return scope;
814
- }
815
- }
816
- const global = scopeManager.globalScope;
817
- return global;
818
- }
819
- function getInnermostScope(initialScope, node) {
820
- for (const childScope of initialScope.childScopes) {
821
- const range = childScope.block.range;
822
- if (range[0] <= node.range[0] && node.range[1] <= range[1]) {
823
- return getInnermostScope(childScope, node);
824
- }
825
- }
826
- return initialScope;
827
- }
828
- function referencesToThrough(references, baseScope) {
829
- let scope = baseScope;
830
- while (scope) {
831
- addAllReferences(scope.through, references);
832
- scope = scope.upper;
833
- }
834
- }
835
- function addAllReferences(list, elements) {
836
- addElementsToSortedArray(
837
- list,
838
- elements,
839
- (a, b) => a.identifier.range[0] - b.identifier.range[0]
840
- );
841
- }
842
- function addReference(list, reference) {
843
- addElementToSortedArray(
844
- list,
845
- reference,
846
- (a, b) => a.identifier.range[0] - b.identifier.range[0]
847
- );
848
- }
849
-
850
- // src/parser/eslint-scope.ts
851
- var eslintScope = __toESM(require("eslint-scope"));
852
- var import_semver2 = __toESM(require("semver"));
853
- var import_path3 = __toESM(require("path"));
854
- var import_module3 = require("module");
855
- var eslintScopeCache = null;
856
- function getEslintScope() {
857
- return eslintScopeCache ?? (eslintScopeCache = getNewest());
858
- }
859
- function getNewest() {
860
- let newest = eslintScope;
861
- const userEslintScope = getEslintScopeFromUser();
862
- if (userEslintScope && userEslintScope.version != null && import_semver2.default.lte(newest.version, userEslintScope.version)) {
863
- newest = userEslintScope;
864
- }
865
- const eslintEslintScope = getEslintScopeFromEslint();
866
- if (eslintEslintScope && eslintEslintScope.version != null && import_semver2.default.lte(newest.version, eslintEslintScope.version)) {
867
- newest = eslintEslintScope;
868
- }
869
- return newest;
870
- }
871
- function getEslintScopeFromUser() {
872
- try {
873
- const cwd = process.cwd();
874
- const relativeTo = import_path3.default.join(cwd, "__placeholder__.js");
875
- return (0, import_module3.createRequire)(relativeTo)("eslint-scope");
876
- } catch {
877
- return null;
878
- }
879
- }
880
- function getEslintScopeFromEslint() {
881
- try {
882
- const cwd = process.cwd();
883
- const requireFromUser = (0, import_module3.createRequire)(import_path3.default.join(cwd, "__placeholder__.js"));
884
- const eslintPackagePath = requireFromUser.resolve("eslint/package.json");
885
- const requireFromEslint = (0, import_module3.createRequire)(
886
- eslintPackagePath.replace(/package\.json$/, "__placeholder__.js")
887
- );
888
- return requireFromEslint("eslint-scope");
889
- } catch {
890
- return null;
891
- }
892
- }
893
-
894
- // src/parser/script.ts
895
- var eslintScope2 = getEslintScope();
896
- function parseScript(code, ctx, parserOptionsCtx) {
897
- const result = parseScriptInternal(code, ctx, parserOptionsCtx);
898
- const parserOptions = parserOptionsCtx.parserOptions;
899
- if (!result.scopeManager && parserOptions.eslintScopeManager) {
900
- result.scopeManager = analyzeScope(result, parserOptions);
901
- }
902
- return result;
903
- }
904
- function analyzeScope(result, parserOptions) {
905
- try {
906
- return (0, import_scope_manager2.analyze)(result.ast, {
907
- globalReturn: parserOptions.ecmaFeatures?.globalReturn,
908
- jsxPragma: parserOptions.jsxPragma,
909
- jsxFragmentName: parserOptions.jsxFragmentName,
910
- lib: parserOptions.lib,
911
- sourceType: parserOptions.sourceType
912
- });
913
- } catch {
914
- }
915
- const ecmaFeatures = parserOptions.ecmaFeatures || {};
916
- return analyzeForEcmaScript(result.ast, {
917
- ignoreEval: true,
918
- nodejsScope: ecmaFeatures.globalReturn,
919
- impliedStrict: ecmaFeatures.impliedStrict,
920
- ecmaVersion: 1e8,
921
- sourceType: parserOptions.sourceType === "commonjs" ? "script" : parserOptions.sourceType || "script",
922
- // @ts-expect-error -- Type bug?
923
- childVisitorKeys: result.visitorKeys || KEYS,
924
- fallback: getKeys
925
- });
926
- }
927
- function parseScriptInternal(code, _ctx, parserOptionsCtx) {
928
- const parser = parserOptionsCtx.getParser();
929
- let patchResult;
930
- try {
931
- const parserOptions = parserOptionsCtx.parserOptions;
932
- if (parserOptionsCtx.isTypeScript() && parserOptions.filePath && parserOptions.project) {
933
- patchResult = tsPatch(parserOptions, parserOptionsCtx.getTSParserName());
934
- } else if (parserOptionsCtx.isTypeScript() && parserOptions.filePath && parserOptions.projectService) {
935
- console.warn(
936
- "`astro-eslint-parser` does not support the `projectService` option, it will parse it as `project: true` instead."
937
- );
938
- patchResult = tsPatch(
939
- { ...parserOptions, project: true, projectService: void 0 },
940
- parserOptionsCtx.getTSParserName()
941
- );
942
- }
943
- const result = isEnhancedParserObject(parser) ? patchResult?.parse ? patchResult.parse(code, parser) : parser.parseForESLint(code, parserOptions) : parser.parse(code, parserOptions);
944
- if ("ast" in result && result.ast != null) {
945
- return result;
946
- }
947
- return { ast: result };
948
- } catch (e) {
949
- debug(
950
- "[script] parsing error:",
951
- e.message,
952
- `@ ${JSON.stringify(code)}
953
-
954
- ${code}`
955
- );
956
- throw e;
957
- } finally {
958
- patchResult?.terminate();
959
- }
960
- }
961
- var Referencer = class extends eslintScope2.Referencer {
962
- JSXAttribute(node) {
963
- this.visit(node.value);
964
- }
965
- JSXClosingElement() {
966
- }
967
- JSXFragment(node) {
968
- this.visitChildren(node);
969
- }
970
- JSXIdentifier(node) {
971
- const scope = this.currentScope();
972
- const ref = new import_scope_manager2.Reference(
973
- node,
974
- scope,
975
- READ_FLAG,
976
- void 0,
977
- void 0,
978
- false,
979
- REFERENCE_TYPE_VALUE_FLAG
980
- );
981
- scope.references.push(ref);
982
- scope.__left.push(ref);
983
- }
984
- JSXMemberExpression(node) {
985
- if (node.object.type !== import_types.AST_NODE_TYPES.JSXIdentifier) {
986
- this.visit(node.object);
987
- } else {
988
- if (node.object.name !== "this") {
989
- this.visit(node.object);
990
- }
991
- }
992
- }
993
- JSXOpeningElement(node) {
994
- if (node.name.type === import_types.AST_NODE_TYPES.JSXIdentifier) {
995
- if (node.name.name[0].toUpperCase() === node.name.name[0] || node.name.name === "this") {
996
- this.visit(node.name);
997
- }
998
- } else {
999
- this.visit(node.name);
1000
- }
1001
- for (const attr of node.attributes) {
1002
- this.visit(attr);
1003
- }
1004
- }
1005
- };
1006
- function analyzeForEcmaScript(tree, providedOptions) {
1007
- const options = Object.assign(
1008
- {
1009
- optimistic: false,
1010
- nodejsScope: false,
1011
- impliedStrict: false,
1012
- sourceType: "script",
1013
- // one of ['script', 'module', 'commonjs']
1014
- ecmaVersion: 5,
1015
- childVisitorKeys: null,
1016
- fallback: "iteration"
1017
- },
1018
- providedOptions
1019
- );
1020
- const scopeManager = new eslintScope2.ScopeManager(
1021
- // @ts-expect-error -- No typings
1022
- options
1023
- );
1024
- const referencer = new Referencer(options, scopeManager);
1025
- referencer.visit(tree);
1026
- return scopeManager;
1027
- }
1028
-
1029
- // src/parser/sort.ts
1030
- function sort(tokens) {
1031
- return tokens.sort((a, b) => {
1032
- if (a.range[0] !== b.range[0]) {
1033
- return a.range[0] - b.range[0];
1034
- }
1035
- return a.range[1] - b.range[1];
1036
- });
1037
- }
1038
-
1039
- // src/parser/process-template.ts
1040
- var import_types2 = require("@typescript-eslint/types");
1041
-
1042
- // src/astro/index.ts
1043
- var import_decode = require("entities/decode");
1044
-
1045
- // src/errors.ts
1046
- var ParseError = class extends SyntaxError {
1047
- /**
1048
- * Initialize this ParseError instance.
1049
- */
1050
- constructor(message, offset, ctx) {
1051
- super(message);
1052
- if (typeof offset === "number") {
1053
- this.index = offset;
1054
- const loc = ctx.getLocFromIndex(offset);
1055
- this.lineNumber = loc.line;
1056
- this.column = loc.column;
1057
- } else {
1058
- this.index = ctx.getIndexFromLoc(offset);
1059
- this.lineNumber = offset.line;
1060
- this.column = offset.column;
1061
- }
1062
- this.originalAST = ctx.originalAST;
1063
- }
1064
- };
1065
-
1066
- // src/astro/index.ts
1067
- function isTag(node) {
1068
- return node.type === "element" || node.type === "custom-element" || node.type === "component" || node.type === "fragment";
1069
- }
1070
- function isParent(node) {
1071
- return Array.isArray(node.children);
1072
- }
1073
- function walkElements(parent, code, enter, leave, parents = []) {
1074
- const children = getSortedChildren(parent, code);
1075
- const currParents = [parent, ...parents];
1076
- for (const node of children) {
1077
- enter(node, currParents);
1078
- if (isParent(node)) {
1079
- walkElements(node, code, enter, leave, currParents);
1080
- }
1081
- leave(node, currParents);
1082
- }
1083
- }
1084
- function walk(parent, code, enter, leave) {
1085
- walkElements(
1086
- parent,
1087
- code,
1088
- (node, parents) => {
1089
- enter(node, parents);
1090
- if (isTag(node)) {
1091
- const attrParents = [node, ...parents];
1092
- for (const attr of node.attributes) {
1093
- enter(attr, attrParents);
1094
- leave(attr, attrParents);
1095
- }
1096
- }
1097
- },
1098
- leave
1099
- );
1100
- }
1101
- function calcStartTagEndOffset(node, ctx) {
1102
- const lastAttr = node.attributes[node.attributes.length - 1];
1103
- let beforeCloseIndex;
1104
- if (lastAttr) {
1105
- beforeCloseIndex = calcAttributeEndOffset(lastAttr, ctx);
1106
- } else {
1107
- const info2 = getTokenInfo(
1108
- ctx,
1109
- [`<${node.name}`],
1110
- node.position.start.offset
1111
- );
1112
- beforeCloseIndex = info2.index + info2.match.length;
1113
- }
1114
- const info = getTokenInfo(ctx, [[">", "/>"]], beforeCloseIndex);
1115
- return info.index + info.match.length;
1116
- }
1117
- function calcAttributeEndOffset(node, ctx) {
1118
- let info;
1119
- if (node.kind === "empty") {
1120
- info = getTokenInfo(ctx, [node.name], node.position.start.offset);
1121
- } else if (node.kind === "quoted") {
1122
- info = getTokenInfo(
1123
- ctx,
1124
- [
1125
- [
1126
- {
1127
- token: `"${node.value}"`,
1128
- htmlEntityDecode: true
1129
- },
1130
- {
1131
- token: `'${node.value}'`,
1132
- htmlEntityDecode: true
1133
- },
1134
- {
1135
- token: node.value,
1136
- htmlEntityDecode: true
1137
- }
1138
- ]
1139
- ],
1140
- calcAttributeValueStartOffset(node, ctx)
1141
- );
1142
- } else if (node.kind === "expression") {
1143
- info = getTokenInfo(
1144
- ctx,
1145
- ["{", node.value, "}"],
1146
- calcAttributeValueStartOffset(node, ctx)
1147
- );
1148
- } else if (node.kind === "shorthand") {
1149
- info = getTokenInfo(
1150
- ctx,
1151
- ["{", node.name, "}"],
1152
- node.position.start.offset
1153
- );
1154
- } else if (node.kind === "spread") {
1155
- info = getTokenInfo(
1156
- ctx,
1157
- ["{", "...", node.name, "}"],
1158
- node.position.start.offset
1159
- );
1160
- } else if (node.kind === "template-literal") {
1161
- info = getTokenInfo(
1162
- ctx,
1163
- [`\`${node.value}\``],
1164
- calcAttributeValueStartOffset(node, ctx)
1165
- );
1166
- } else {
1167
- throw new ParseError(
1168
- `Unknown attr kind: ${node.kind}`,
1169
- node.position.start.offset,
1170
- ctx
1171
- );
1172
- }
1173
- return info.index + info.match.length;
1174
- }
1175
- function calcAttributeValueStartOffset(node, ctx) {
1176
- let info;
1177
- if (node.kind === "quoted") {
1178
- info = getTokenInfo(
1179
- ctx,
1180
- [
1181
- node.name,
1182
- "=",
1183
- [`"`, `'`, { token: node.value, htmlEntityDecode: true }]
1184
- ],
1185
- node.position.start.offset
1186
- );
1187
- } else if (node.kind === "expression") {
1188
- info = getTokenInfo(
1189
- ctx,
1190
- [node.name, "=", "{"],
1191
- node.position.start.offset
1192
- );
1193
- } else if (node.kind === "template-literal") {
1194
- info = getTokenInfo(
1195
- ctx,
1196
- [node.name, "=", "`"],
1197
- node.position.start.offset
1198
- );
1199
- } else {
1200
- throw new ParseError(
1201
- `Unknown attr kind: ${node.kind}`,
1202
- node.position.start.offset,
1203
- ctx
1204
- );
1205
- }
1206
- return info.index;
1207
- }
1208
- function getEndOffset(node, ctx) {
1209
- if (node.position.end?.offset != null) {
1210
- return node.position.end.offset;
1211
- }
1212
- if (isTag(node)) return calcTagEndOffset(node, ctx);
1213
- if (node.type === "expression") return calcExpressionEndOffset(node, ctx);
1214
- if (node.type === "comment") return calcCommentEndOffset(node, ctx);
1215
- if (node.type === "frontmatter") {
1216
- const start = node.position.start.offset;
1217
- return ctx.code.indexOf("---", start + 3) + 3;
1218
- }
1219
- if (node.type === "doctype") {
1220
- const start = node.position.start.offset;
1221
- return ctx.code.indexOf(">", start) + 1;
1222
- }
1223
- if (node.type === "text") {
1224
- const start = node.position.start.offset;
1225
- return start + node.value.length;
1226
- }
1227
- if (node.type === "root") {
1228
- return ctx.code.length;
1229
- }
1230
- throw new Error(`unknown type: ${node.type}`);
1231
- }
1232
- function calcContentEndOffset(parent, ctx) {
1233
- const code = ctx.code;
1234
- if (isTag(parent)) {
1235
- const end = getEndOffset(parent, ctx);
1236
- if (code[end - 1] !== ">") {
1237
- return end;
1238
- }
1239
- const index = code.lastIndexOf("</", end - 1);
1240
- if (index >= 0 && code.slice(index + 2, end - 1).trim() === parent.name) {
1241
- return index;
1242
- }
1243
- return end;
1244
- } else if (parent.type === "expression") {
1245
- const end = getEndOffset(parent, ctx);
1246
- return code.lastIndexOf("}", end);
1247
- } else if (parent.type === "root") {
1248
- return code.length;
1249
- }
1250
- throw new Error(`unknown type: ${parent.type}`);
1251
- }
1252
- function getSelfClosingTag(node, ctx) {
1253
- if (node.children.length > 0) {
1254
- return null;
1255
- }
1256
- const code = ctx.code;
1257
- const startTagEndOffset = calcStartTagEndOffset(node, ctx);
1258
- if (code.startsWith("/>", startTagEndOffset - 2)) {
1259
- return {
1260
- offset: startTagEndOffset,
1261
- end: "/>"
1262
- };
1263
- }
1264
- if (code.startsWith(`</${node.name}`, startTagEndOffset)) {
1265
- return null;
1266
- }
1267
- return {
1268
- offset: startTagEndOffset,
1269
- end: ">"
1270
- };
1271
- }
1272
- function getEndTag(node, ctx) {
1273
- let beforeIndex;
1274
- if (node.children.length) {
1275
- const lastChild = node.children[node.children.length - 1];
1276
- beforeIndex = getEndOffset(lastChild, ctx);
1277
- } else {
1278
- beforeIndex = calcStartTagEndOffset(node, ctx);
1279
- }
1280
- beforeIndex = skipSpaces(ctx.code, beforeIndex);
1281
- if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
1282
- const offset = beforeIndex;
1283
- beforeIndex = beforeIndex + 2 + node.name.length;
1284
- const info = getTokenInfo(ctx, [">"], beforeIndex);
1285
- const end = info.index + info.match.length;
1286
- return {
1287
- offset,
1288
- tag: ctx.code.slice(offset, end)
1289
- };
1290
- }
1291
- return null;
1292
- }
1293
- function calcCommentEndOffset(node, ctx) {
1294
- const info = getTokenInfo(
1295
- ctx,
1296
- ["<!--", node.value, "-->"],
1297
- node.position.start.offset
1298
- );
1299
- return info.index + info.match.length;
1300
- }
1301
- function calcTagEndOffset(node, ctx) {
1302
- let beforeIndex;
1303
- if (node.children.length) {
1304
- const lastChild = node.children[node.children.length - 1];
1305
- beforeIndex = getEndOffset(lastChild, ctx);
1306
- } else {
1307
- beforeIndex = calcStartTagEndOffset(node, ctx);
1308
- }
1309
- beforeIndex = skipSpaces(ctx.code, beforeIndex);
1310
- if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
1311
- beforeIndex = beforeIndex + 2 + node.name.length;
1312
- const info = getTokenInfo(ctx, [">"], beforeIndex);
1313
- return info.index + info.match.length;
1314
- }
1315
- return beforeIndex;
1316
- }
1317
- function calcExpressionEndOffset(node, ctx) {
1318
- if (node.children.length) {
1319
- const lastChild = node.children[node.children.length - 1];
1320
- const beforeIndex = getEndOffset(lastChild, ctx);
1321
- const info2 = getTokenInfo(ctx, ["}"], beforeIndex);
1322
- return info2.index + info2.match.length;
1323
- }
1324
- const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
1325
- return info.index + info.match.length;
1326
- }
1327
- function getTokenInfo(ctx, tokens, position) {
1328
- let lastMatch;
1329
- for (const t of tokens) {
1330
- const index = lastMatch ? lastMatch.index + lastMatch.match.length : position;
1331
- const m = Array.isArray(t) ? matchOfForMulti(t, index) : match(t, index);
1332
- if (m == null) {
1333
- throw new ParseError(
1334
- `Unknown token at ${index}, expected: ${JSON.stringify(
1335
- t
1336
- )}, actual: ${JSON.stringify(ctx.code.slice(index, index + 10))}`,
1337
- index,
1338
- ctx
1339
- );
1340
- }
1341
- lastMatch = m;
1342
- }
1343
- return lastMatch;
1344
- function match(token, position2) {
1345
- const search = typeof token === "string" ? token : token.token;
1346
- const index = search.trim() === search ? skipSpaces(ctx.code, position2) : position2;
1347
- if (ctx.code.startsWith(search, index)) {
1348
- return {
1349
- match: search,
1350
- index
1351
- };
1352
- }
1353
- if (typeof token !== "string") {
1354
- return matchWithHTMLEntity(token, index);
1355
- }
1356
- return null;
1357
- }
1358
- function matchOfForMulti(search, position2) {
1359
- for (const s of search) {
1360
- const m = match(s, position2);
1361
- if (m) {
1362
- return m;
1363
- }
1364
- }
1365
- return null;
1366
- }
1367
- function matchWithHTMLEntity(token, position2) {
1368
- const search = token.token;
1369
- let codeOffset = position2;
1370
- let searchOffset = 0;
1371
- while (searchOffset < search.length) {
1372
- const searchChar = search[searchOffset];
1373
- if (ctx.code[codeOffset] === searchChar) {
1374
- if (searchChar === "&") {
1375
- const entityCandidate = ctx.code.slice(codeOffset, codeOffset + 5);
1376
- if (entityCandidate === "&amp;" || entityCandidate === "&AMP;") {
1377
- codeOffset += 5;
1378
- searchOffset++;
1379
- continue;
1380
- }
1381
- }
1382
- codeOffset++;
1383
- searchOffset++;
1384
- continue;
1385
- }
1386
- const entity = getHTMLEntity(codeOffset);
1387
- if (entity?.entity === searchChar) {
1388
- codeOffset += entity.length;
1389
- searchOffset++;
1390
- continue;
1391
- }
1392
- return null;
1393
- }
1394
- return {
1395
- match: ctx.code.slice(position2, codeOffset),
1396
- index: position2
1397
- };
1398
- function getHTMLEntity(position3) {
1399
- let codeOffset2 = position3;
1400
- if (ctx.code[codeOffset2++] !== "&") return null;
1401
- let entity = "";
1402
- const entityDecoder = new import_decode.EntityDecoder(
1403
- import_decode.htmlDecodeTree,
1404
- (cp) => entity += String.fromCodePoint(cp)
1405
- );
1406
- entityDecoder.startEntity(import_decode.DecodingMode.Attribute);
1407
- const length = entityDecoder.write(ctx.code, codeOffset2);
1408
- if (length < 0) {
1409
- return null;
1410
- }
1411
- if (length === 0) {
1412
- return null;
1413
- }
1414
- return {
1415
- entity,
1416
- length
1417
- };
1418
- }
1419
- }
1420
- }
1421
- function skipSpaces(string, position) {
1422
- const re = /\s*/g;
1423
- re.lastIndex = position;
1424
- const match = re.exec(string);
1425
- if (match) {
1426
- return match.index + match[0].length;
1427
- }
1428
- return position;
1429
- }
1430
- function getSortedChildren(parent, code) {
1431
- if (parent.type === "root" && parent.children[0]?.type === "frontmatter") {
1432
- const children = [...parent.children];
1433
- if (children.every((n) => n.position)) {
1434
- return children.sort(
1435
- (a, b) => a.position.start.offset - b.position.start.offset
1436
- );
1437
- }
1438
- let start = skipSpaces(code, 0);
1439
- if (code.startsWith("<!", start)) {
1440
- const frontmatter = children.shift();
1441
- const before = [];
1442
- let first;
1443
- while (first = children.shift()) {
1444
- start = skipSpaces(code, start);
1445
- if (first.type === "comment" && code.startsWith("<!--", start)) {
1446
- start = code.indexOf("-->", start + 4) + 3;
1447
- before.push(first);
1448
- } else if (first.type === "doctype" && code.startsWith("<!", start)) {
1449
- start = code.indexOf(">", start + 2) + 1;
1450
- before.push(first);
1451
- } else {
1452
- children.unshift(first);
1453
- break;
1454
- }
1455
- }
1456
- return [...before, frontmatter, ...children];
1457
- }
1458
- }
1459
- return parent.children;
1460
- }
1461
-
1462
- // src/context/restore.ts
1463
- var RestoreNodeProcessContext = class {
1464
- constructor(result, nodeMap) {
1465
- this.removeTokens = /* @__PURE__ */ new Set();
1466
- this.result = result;
1467
- this.nodeMap = nodeMap;
1468
- }
1469
- addRemoveToken(test) {
1470
- this.removeTokens.add(test);
1471
- }
1472
- getParent(node) {
1473
- return this.nodeMap.get(node) || null;
1474
- }
1475
- findToken(startIndex) {
1476
- const tokens = this.result.ast.tokens || [];
1477
- return tokens.find((t) => t.range[0] === startIndex) || null;
1478
- }
1479
- };
1480
- var RestoreContext = class {
1481
- constructor(ctx) {
1482
- this.offsets = [];
1483
- this.virtualFragments = [];
1484
- this.restoreNodeProcesses = [];
1485
- this.tokens = [];
1486
- this.ctx = ctx;
1487
- }
1488
- addRestoreNodeProcess(process2) {
1489
- this.restoreNodeProcesses.push(process2);
1490
- }
1491
- addOffset(offset) {
1492
- this.offsets.push(offset);
1493
- }
1494
- addVirtualFragmentRange(start, end) {
1495
- const peek = this.virtualFragments[this.virtualFragments.length - 1];
1496
- if (peek && peek.end === start) {
1497
- peek.end = end;
1498
- return;
1499
- }
1500
- this.virtualFragments.push({ start, end });
1501
- }
1502
- addToken(type, range) {
1503
- if (range[0] >= range[1]) {
1504
- return;
1505
- }
1506
- this.tokens.push(this.ctx.buildToken(type, range));
1507
- }
1508
- /**
1509
- * Restore AST nodes
1510
- */
1511
- restore(result) {
1512
- const nodeMap = remapLocationsAndGetNodeMap(result, this.tokens, {
1513
- remapLocation: (n) => this.remapLocation(n),
1514
- removeToken: (token) => this.virtualFragments.some(
1515
- (f) => f.start <= token.range[0] && token.range[1] <= f.end
1516
- )
1517
- });
1518
- restoreNodes(result, nodeMap, this.restoreNodeProcesses);
1519
- const firstOffset = Math.min(
1520
- ...[result.ast.body[0], result.ast.tokens?.[0], result.ast.comments?.[0]].filter((t) => Boolean(t)).map((t) => t.range[0])
1521
- );
1522
- if (firstOffset < result.ast.range[0]) {
1523
- result.ast.range[0] = firstOffset;
1524
- result.ast.loc.start = this.ctx.getLocFromIndex(firstOffset);
1525
- }
1526
- }
1527
- remapLocation(node) {
1528
- let [start, end] = node.range;
1529
- const startFragment = this.virtualFragments.find(
1530
- (f) => f.start <= start && start < f.end
1531
- );
1532
- if (startFragment) {
1533
- start = startFragment.end;
1534
- }
1535
- const endFragment = this.virtualFragments.find(
1536
- (f) => f.start < end && end <= f.end
1537
- );
1538
- if (endFragment) {
1539
- end = endFragment.start;
1540
- if (startFragment === endFragment) {
1541
- start = startFragment.start;
1542
- }
1543
- }
1544
- if (end < start) {
1545
- const w = start;
1546
- start = end;
1547
- end = w;
1548
- }
1549
- const locs = this.ctx.getLocations(...this.getRemapRange(start, end));
1550
- node.loc = locs.loc;
1551
- node.range = locs.range;
1552
- if (node.start != null) {
1553
- delete node.start;
1554
- }
1555
- if (node.end != null) {
1556
- delete node.end;
1557
- }
1558
- }
1559
- getRemapRange(start, end) {
1560
- if (!this.offsets.length) {
1561
- return [start, end];
1562
- }
1563
- let lastStart = this.offsets[0];
1564
- let lastEnd = this.offsets[0];
1565
- for (const offset of this.offsets) {
1566
- if (offset.dist <= start) {
1567
- lastStart = offset;
1568
- }
1569
- if (offset.dist < end) {
1570
- lastEnd = offset;
1571
- } else {
1572
- if (offset.dist === end && start === end) {
1573
- lastEnd = offset;
1574
- }
1575
- break;
1576
- }
1577
- }
1578
- const remapStart = lastStart.original + (start - lastStart.dist);
1579
- const remapEnd = lastEnd.original + (end - lastEnd.dist);
1580
- if (remapEnd < remapStart) {
1581
- return [remapEnd, remapStart];
1582
- }
1583
- return [remapStart, remapEnd];
1584
- }
1585
- };
1586
- function remapLocationsAndGetNodeMap(result, restoreTokens, {
1587
- remapLocation,
1588
- removeToken
1589
- }) {
1590
- const traversed = /* @__PURE__ */ new Map();
1591
- traverseNodes(result.ast, {
1592
- visitorKeys: result.visitorKeys,
1593
- enterNode: (node, p) => {
1594
- if (!traversed.has(node)) {
1595
- traversed.set(node, p);
1596
- remapLocation(node);
1597
- }
1598
- },
1599
- leaveNode: (_node) => {
1600
- }
1601
- });
1602
- const tokens = [...restoreTokens];
1603
- for (const token of result.ast.tokens || []) {
1604
- if (removeToken(token)) {
1605
- continue;
1606
- }
1607
- remapLocation(token);
1608
- tokens.push(token);
1609
- }
1610
- result.ast.tokens = tokens;
1611
- for (const token of result.ast.comments || []) {
1612
- remapLocation(token);
1613
- }
1614
- return traversed;
1615
- }
1616
- function restoreNodes(result, nodeMap, restoreNodeProcesses) {
1617
- const context = new RestoreNodeProcessContext(result, nodeMap);
1618
- const restoreNodeProcessesSet = new Set(restoreNodeProcesses);
1619
- for (const [node] of nodeMap) {
1620
- if (!restoreNodeProcessesSet.size) {
1621
- break;
1622
- }
1623
- for (const proc of [...restoreNodeProcessesSet]) {
1624
- if (proc(node, context)) {
1625
- restoreNodeProcessesSet.delete(proc);
1626
- }
1627
- }
1628
- }
1629
- if (context.removeTokens.size) {
1630
- const tokens = result.ast.tokens || [];
1631
- for (let index = tokens.length - 1; index >= 0; index--) {
1632
- const token = tokens[index];
1633
- for (const rt of context.removeTokens) {
1634
- if (rt(token)) {
1635
- tokens.splice(index, 1);
1636
- context.removeTokens.delete(rt);
1637
- if (!context.removeTokens.size) {
1638
- break;
1639
- }
1640
- }
1641
- }
1642
- }
1643
- }
1644
- }
1645
-
1646
- // src/context/script.ts
1647
- var VirtualScriptContext = class {
1648
- constructor(ctx) {
1649
- this.script = "";
1650
- this.consumedIndex = 0;
1651
- this.originalCode = ctx.code;
1652
- this.restoreContext = new RestoreContext(ctx);
1653
- }
1654
- skipOriginalOffset(offset) {
1655
- this.consumedIndex += offset;
1656
- }
1657
- skipUntilOriginalOffset(offset) {
1658
- this.consumedIndex = Math.max(offset, this.consumedIndex);
1659
- }
1660
- appendOriginal(index) {
1661
- if (this.consumedIndex >= index) {
1662
- return;
1663
- }
1664
- this.restoreContext.addOffset({
1665
- original: this.consumedIndex,
1666
- dist: this.script.length
1667
- });
1668
- this.script += this.originalCode.slice(this.consumedIndex, index);
1669
- this.consumedIndex = index;
1670
- }
1671
- appendVirtualScript(virtualFragment) {
1672
- const start = this.script.length;
1673
- this.script += virtualFragment;
1674
- this.restoreContext.addVirtualFragmentRange(start, this.script.length);
1675
- }
1676
- };
1677
-
1678
- // src/parser/process-template.ts
1679
- function processTemplate(ctx, resultTemplate) {
1680
- let uniqueIdSeq = 0;
1681
- const usedUniqueIds = /* @__PURE__ */ new Set();
1682
- const script = new VirtualScriptContext(ctx);
1683
- let fragmentOpened = false;
1684
- function openRootFragment(startOffset) {
1685
- script.appendVirtualScript("<>");
1686
- fragmentOpened = true;
1687
- script.restoreContext.addRestoreNodeProcess((scriptNode, { result }) => {
1688
- if (scriptNode.type === import_types2.AST_NODE_TYPES.ExpressionStatement && scriptNode.expression.type === import_types2.AST_NODE_TYPES.JSXFragment && scriptNode.range[0] === startOffset && result.ast.body.includes(scriptNode)) {
1689
- const index = result.ast.body.indexOf(scriptNode);
1690
- const rootFragment = result.ast.body[index] = scriptNode.expression;
1691
- delete rootFragment.closingFragment;
1692
- delete rootFragment.openingFragment;
1693
- rootFragment.type = "AstroFragment";
1694
- return true;
1695
- }
1696
- return false;
1697
- });
1698
- }
1699
- walkElements(
1700
- resultTemplate.ast,
1701
- ctx.code,
1702
- // eslint-disable-next-line complexity -- X(
1703
- (node, [parent]) => {
1704
- if (node.type === "frontmatter") {
1705
- const start = node.position.start.offset;
1706
- if (fragmentOpened) {
1707
- script.appendVirtualScript("</>;");
1708
- fragmentOpened = false;
1709
- }
1710
- script.appendOriginal(start);
1711
- script.skipOriginalOffset(3);
1712
- const end = getEndOffset(node, ctx);
1713
- const scriptStart = start + 3;
1714
- let scriptEnd = end - 3;
1715
- let endChar;
1716
- while (scriptStart < scriptEnd - 1 && (endChar = ctx.code[scriptEnd - 1]) && !endChar.trim()) {
1717
- scriptEnd--;
1718
- }
1719
- script.appendOriginal(scriptEnd);
1720
- script.appendVirtualScript("\n;");
1721
- script.skipOriginalOffset(end - scriptEnd);
1722
- script.restoreContext.addRestoreNodeProcess(
1723
- (_scriptNode, { result }) => {
1724
- for (let index = 0; index < result.ast.body.length; index++) {
1725
- const st = result.ast.body[index];
1726
- if (st.type === import_types2.AST_NODE_TYPES.EmptyStatement) {
1727
- if (st.range[0] === scriptEnd && st.range[1] === scriptEnd) {
1728
- result.ast.body.splice(index, 1);
1729
- break;
1730
- }
1731
- }
1732
- }
1733
- return true;
1734
- }
1735
- );
1736
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.Punctuator, [
1737
- node.position.start.offset,
1738
- node.position.start.offset + 3
1739
- ]);
1740
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.Punctuator, [
1741
- end - 3,
1742
- end
1743
- ]);
1744
- } else if (isTag(node)) {
1745
- if (parent.type === "expression") {
1746
- const siblings = parent.children.filter(
1747
- (n) => n.type !== "text" || n.value.trim()
1748
- );
1749
- const index = siblings.indexOf(node);
1750
- const before = siblings[index - 1];
1751
- if (!before || !isTag(before)) {
1752
- const after = siblings[index + 1];
1753
- if (after && (isTag(after) || after.type === "comment")) {
1754
- const start2 = node.position.start.offset;
1755
- script.appendOriginal(start2);
1756
- script.appendVirtualScript("<>");
1757
- script.restoreContext.addRestoreNodeProcess((scriptNode) => {
1758
- if (scriptNode.range[0] === start2 && scriptNode.type === import_types2.AST_NODE_TYPES.JSXFragment) {
1759
- delete scriptNode.openingFragment;
1760
- delete scriptNode.closingFragment;
1761
- const fragmentNode = scriptNode;
1762
- fragmentNode.type = "AstroFragment";
1763
- const last = fragmentNode.children[fragmentNode.children.length - 1];
1764
- if (fragmentNode.range[1] < last.range[1]) {
1765
- fragmentNode.range[1] = last.range[1];
1766
- fragmentNode.loc.end = ctx.getLocFromIndex(
1767
- fragmentNode.range[1]
1768
- );
1769
- }
1770
- return true;
1771
- }
1772
- return false;
1773
- });
1774
- }
1775
- }
1776
- }
1777
- const start = node.position.start.offset;
1778
- script.appendOriginal(start);
1779
- if (!fragmentOpened) {
1780
- openRootFragment(start);
1781
- }
1782
- for (const attr of node.attributes) {
1783
- if (attr.kind === "quoted" || attr.kind === "empty" || attr.kind === "expression" || attr.kind === "template-literal") {
1784
- const needPunctuatorsProcess = node.type === "component" || node.type === "fragment" ? /[.:@]/u.test(attr.name) : /[.@]/u.test(attr.name) || attr.name.startsWith(":");
1785
- if (needPunctuatorsProcess) {
1786
- processAttributePunctuators(attr);
1787
- }
1788
- }
1789
- if (attr.kind === "quoted") {
1790
- if (attr.raw && !attr.raw.startsWith('"') && !attr.raw.startsWith("'")) {
1791
- const attrStart = attr.position.start.offset;
1792
- const start2 = calcAttributeValueStartOffset(attr, ctx);
1793
- const end = calcAttributeEndOffset(attr, ctx);
1794
- script.appendOriginal(start2);
1795
- script.appendVirtualScript('"');
1796
- script.appendOriginal(end);
1797
- script.appendVirtualScript('"');
1798
- script.restoreContext.addRestoreNodeProcess(
1799
- (scriptNode, context) => {
1800
- if (scriptNode.type === import_types2.AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === attrStart) {
1801
- const attrNode = scriptNode;
1802
- if (attrNode.value?.type === "Literal" && typeof attrNode.value.value === "string") {
1803
- const raw = ctx.code.slice(start2, end);
1804
- attrNode.value.raw = raw;
1805
- context.findToken(start2).value = raw;
1806
- return true;
1807
- }
1808
- }
1809
- return false;
1810
- }
1811
- );
1812
- }
1813
- } else if (attr.kind === "shorthand") {
1814
- const start2 = attr.position.start.offset;
1815
- script.appendOriginal(start2);
1816
- const jsxName = /[\s"'[\]{}]/u.test(attr.name) ? generateUniqueId(attr.name) : attr.name;
1817
- script.appendVirtualScript(`${jsxName}=`);
1818
- script.restoreContext.addRestoreNodeProcess((scriptNode) => {
1819
- if (scriptNode.type === import_types2.AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === start2) {
1820
- const attrNode = scriptNode;
1821
- attrNode.type = "AstroShorthandAttribute";
1822
- const locs = ctx.getLocations(
1823
- ...attrNode.value.expression.range
1824
- );
1825
- if (jsxName !== attr.name) {
1826
- attrNode.name.name = attr.name;
1827
- }
1828
- attrNode.name.range = locs.range;
1829
- attrNode.name.loc = locs.loc;
1830
- return true;
1831
- }
1832
- return false;
1833
- });
1834
- } else if (attr.kind === "template-literal") {
1835
- const attrStart = attr.position.start.offset;
1836
- const start2 = calcAttributeValueStartOffset(attr, ctx);
1837
- const end = calcAttributeEndOffset(attr, ctx);
1838
- script.appendOriginal(start2);
1839
- script.appendVirtualScript("{");
1840
- script.appendOriginal(end);
1841
- script.appendVirtualScript("}");
1842
- script.restoreContext.addRestoreNodeProcess((scriptNode) => {
1843
- if (scriptNode.type === import_types2.AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === attrStart) {
1844
- const attrNode = scriptNode;
1845
- attrNode.type = "AstroTemplateLiteralAttribute";
1846
- return true;
1847
- }
1848
- return false;
1849
- });
1850
- }
1851
- }
1852
- const closing = getSelfClosingTag(node, ctx);
1853
- if (closing && closing.end === ">") {
1854
- script.appendOriginal(closing.offset - 1);
1855
- script.appendVirtualScript("/");
1856
- }
1857
- if (node.name === "script" || node.name === "style" || node.attributes.some((attr) => attr.name === "is:raw")) {
1858
- const text = node.children[0];
1859
- if (text && text.type === "text") {
1860
- const styleNodeStart = node.position.start.offset;
1861
- const start2 = text.position.start.offset;
1862
- script.appendOriginal(start2);
1863
- script.skipOriginalOffset(text.value.length);
1864
- script.restoreContext.addRestoreNodeProcess((scriptNode) => {
1865
- if (scriptNode.type === import_types2.AST_NODE_TYPES.JSXElement && scriptNode.range[0] === styleNodeStart) {
1866
- const textNode = {
1867
- type: "AstroRawText",
1868
- value: text.value,
1869
- raw: text.value,
1870
- parent: scriptNode,
1871
- ...ctx.getLocations(start2, start2 + text.value.length)
1872
- };
1873
- scriptNode.children = [textNode];
1874
- return true;
1875
- }
1876
- return false;
1877
- });
1878
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.JSXText, [
1879
- start2,
1880
- start2 + text.value.length
1881
- ]);
1882
- }
1883
- }
1884
- } else if (node.type === "comment") {
1885
- const start = node.position.start.offset;
1886
- const end = getEndOffset(node, ctx);
1887
- const length = end - start;
1888
- script.appendOriginal(start);
1889
- if (!fragmentOpened) {
1890
- openRootFragment(start);
1891
- }
1892
- script.appendOriginal(start + 1);
1893
- script.appendVirtualScript(`></`);
1894
- script.skipOriginalOffset(length - 2);
1895
- script.appendOriginal(end);
1896
- script.restoreContext.addRestoreNodeProcess((scriptNode, context) => {
1897
- if (scriptNode.range[0] === start && scriptNode.type === import_types2.AST_NODE_TYPES.JSXFragment) {
1898
- delete scriptNode.children;
1899
- delete scriptNode.openingFragment;
1900
- delete scriptNode.closingFragment;
1901
- delete scriptNode.expression;
1902
- const commentNode = scriptNode;
1903
- commentNode.type = "AstroHTMLComment";
1904
- commentNode.value = node.value;
1905
- context.addRemoveToken(
1906
- (token) => token.value === "<" && token.range[0] === scriptNode.range[0]
1907
- );
1908
- context.addRemoveToken(
1909
- (token) => token.value === ">" && token.range[1] === scriptNode.range[1]
1910
- );
1911
- return true;
1912
- }
1913
- return false;
1914
- });
1915
- script.restoreContext.addToken("HTMLComment", [
1916
- start,
1917
- start + length
1918
- ]);
1919
- } else if (node.type === "doctype") {
1920
- const start = node.position.start.offset;
1921
- const end = getEndOffset(node, ctx);
1922
- const length = end - start;
1923
- script.appendOriginal(start);
1924
- if (!fragmentOpened) {
1925
- openRootFragment(start);
1926
- }
1927
- script.appendOriginal(start + 1);
1928
- script.appendVirtualScript(`></`);
1929
- script.skipOriginalOffset(length - 2);
1930
- script.appendOriginal(end);
1931
- script.restoreContext.addRestoreNodeProcess((scriptNode, context) => {
1932
- if (scriptNode.range[0] === start && scriptNode.type === import_types2.AST_NODE_TYPES.JSXFragment) {
1933
- delete scriptNode.children;
1934
- delete scriptNode.openingFragment;
1935
- delete scriptNode.closingFragment;
1936
- delete scriptNode.expression;
1937
- const doctypeNode = scriptNode;
1938
- doctypeNode.type = "AstroDoctype";
1939
- context.addRemoveToken(
1940
- (token) => token.value === "<" && token.range[0] === scriptNode.range[0]
1941
- );
1942
- context.addRemoveToken(
1943
- (token) => token.value === ">" && token.range[1] === scriptNode.range[1]
1944
- );
1945
- return true;
1946
- }
1947
- return false;
1948
- });
1949
- script.restoreContext.addToken("HTMLDocType", [
1950
- start,
1951
- end
1952
- ]);
1953
- } else {
1954
- const start = node.position.start.offset;
1955
- script.appendOriginal(start);
1956
- if (!fragmentOpened) {
1957
- openRootFragment(start);
1958
- }
1959
- }
1960
- },
1961
- (node, [parent]) => {
1962
- if (isTag(node)) {
1963
- const closing = getSelfClosingTag(node, ctx);
1964
- if (!closing) {
1965
- const end = getEndTag(node, ctx);
1966
- if (!end) {
1967
- const offset = calcContentEndOffset(node, ctx);
1968
- script.appendOriginal(offset);
1969
- script.appendVirtualScript(`</${node.name}>`);
1970
- script.restoreContext.addRestoreNodeProcess(
1971
- (scriptNode, context) => {
1972
- const parent2 = context.getParent(scriptNode);
1973
- if (scriptNode.range[0] === offset && scriptNode.type === import_types2.AST_NODE_TYPES.JSXClosingElement && parent2.type === import_types2.AST_NODE_TYPES.JSXElement) {
1974
- removeAllScopeAndVariableAndReference(scriptNode, {
1975
- visitorKeys: context.result.visitorKeys,
1976
- scopeManager: context.result.scopeManager
1977
- });
1978
- parent2.closingElement = null;
1979
- return true;
1980
- }
1981
- return false;
1982
- }
1983
- );
1984
- }
1985
- }
1986
- }
1987
- if ((isTag(node) || node.type === "comment") && parent.type === "expression") {
1988
- const siblings = parent.children.filter(
1989
- (n) => n.type !== "text" || n.value.trim()
1990
- );
1991
- const index = siblings.indexOf(node);
1992
- const after = siblings[index + 1];
1993
- if (!after || !isTag(after) && after.type !== "comment") {
1994
- const before = siblings[index - 1];
1995
- if (before && (isTag(before) || before.type === "comment")) {
1996
- const end = getEndOffset(node, ctx);
1997
- script.appendOriginal(end);
1998
- script.appendVirtualScript("</>");
1999
- }
2000
- }
2001
- }
2002
- }
2003
- );
2004
- if (fragmentOpened) {
2005
- const last = resultTemplate.ast.children[resultTemplate.ast.children.length - 1];
2006
- const end = getEndOffset(last, ctx);
2007
- script.appendOriginal(end);
2008
- script.appendVirtualScript("</>;");
2009
- }
2010
- script.appendOriginal(ctx.code.length);
2011
- return script;
2012
- function processAttributePunctuators(attr) {
2013
- const start = attr.position.start.offset;
2014
- let targetIndex = start;
2015
- let colonOffset;
2016
- for (let index = 0; index < attr.name.length; index++) {
2017
- const char = attr.name[index];
2018
- if (char !== ":" && char !== "." && char !== "@") {
2019
- continue;
2020
- }
2021
- if (index === 0) {
2022
- targetIndex++;
2023
- }
2024
- const punctuatorIndex = start + index;
2025
- script.appendOriginal(punctuatorIndex);
2026
- script.skipOriginalOffset(1);
2027
- script.appendVirtualScript(`_`);
2028
- if (char === ":" && index !== 0 && colonOffset == null) {
2029
- colonOffset = index;
2030
- }
2031
- }
2032
- if (colonOffset != null) {
2033
- const punctuatorIndex = start + colonOffset;
2034
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.JSXIdentifier, [
2035
- start,
2036
- punctuatorIndex
2037
- ]);
2038
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.Punctuator, [
2039
- punctuatorIndex,
2040
- punctuatorIndex + 1
2041
- ]);
2042
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.JSXIdentifier, [
2043
- punctuatorIndex + 1,
2044
- start + attr.name.length
2045
- ]);
2046
- } else {
2047
- script.restoreContext.addToken(import_types2.AST_TOKEN_TYPES.JSXIdentifier, [
2048
- start,
2049
- start + attr.name.length
2050
- ]);
2051
- }
2052
- script.restoreContext.addRestoreNodeProcess((scriptNode, context) => {
2053
- if (scriptNode.type === import_types2.AST_NODE_TYPES.JSXAttribute && scriptNode.range[0] === targetIndex) {
2054
- const baseNameNode = scriptNode.name;
2055
- if (colonOffset != null) {
2056
- const nameNode = baseNameNode;
2057
- nameNode.type = import_types2.AST_NODE_TYPES.JSXNamespacedName;
2058
- nameNode.namespace = {
2059
- type: import_types2.AST_NODE_TYPES.JSXIdentifier,
2060
- name: attr.name.slice(0, colonOffset),
2061
- ...ctx.getLocations(
2062
- baseNameNode.range[0],
2063
- baseNameNode.range[0] + colonOffset
2064
- )
2065
- };
2066
- nameNode.name = {
2067
- type: import_types2.AST_NODE_TYPES.JSXIdentifier,
2068
- name: attr.name.slice(colonOffset + 1),
2069
- ...ctx.getLocations(
2070
- baseNameNode.range[0] + colonOffset + 1,
2071
- baseNameNode.range[1]
2072
- )
2073
- };
2074
- scriptNode.name = nameNode;
2075
- nameNode.namespace.parent = nameNode;
2076
- nameNode.name.parent = nameNode;
2077
- } else {
2078
- if (baseNameNode.type === import_types2.AST_NODE_TYPES.JSXIdentifier) {
2079
- const nameNode = baseNameNode;
2080
- nameNode.name = attr.name;
2081
- scriptNode.name = nameNode;
2082
- } else {
2083
- const nameNode = baseNameNode;
2084
- nameNode.namespace.name = attr.name.slice(
2085
- baseNameNode.namespace.range[0] - start,
2086
- baseNameNode.namespace.range[1] - start
2087
- );
2088
- nameNode.name.name = attr.name.slice(
2089
- baseNameNode.name.range[0] - start,
2090
- baseNameNode.name.range[1] - start
2091
- );
2092
- scriptNode.name = nameNode;
2093
- nameNode.namespace.parent = nameNode;
2094
- nameNode.name.parent = nameNode;
2095
- }
2096
- }
2097
- context.addRemoveToken(
2098
- (token) => token.range[0] === baseNameNode.range[0] && token.range[1] === baseNameNode.range[1]
2099
- );
2100
- return true;
2101
- }
2102
- return false;
2103
- });
2104
- }
2105
- function generateUniqueId(base) {
2106
- let candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
2107
- while (usedUniqueIds.has(candidate) || ctx.code.includes(candidate)) {
2108
- candidate = `$_${base.replace(/\W/g, "_")}${uniqueIdSeq++}`;
2109
- }
2110
- usedUniqueIds.add(candidate);
2111
- return candidate;
2112
- }
2113
- }
2114
-
2115
- // src/context/index.ts
2116
- var Context = class {
2117
- constructor(code, filePath) {
2118
- this.locsMap = /* @__PURE__ */ new Map();
2119
- this.state = {};
2120
- this.locs = new LinesAndColumns(code);
2121
- this.code = code;
2122
- this.filePath = filePath;
2123
- }
2124
- getLocFromIndex(index) {
2125
- let loc = this.locsMap.get(index);
2126
- if (!loc) {
2127
- loc = this.locs.getLocFromIndex(index);
2128
- this.locsMap.set(index, loc);
2129
- }
2130
- return {
2131
- line: loc.line,
2132
- column: loc.column
2133
- };
2134
- }
2135
- getIndexFromLoc(loc) {
2136
- return this.locs.getIndexFromLoc(loc);
2137
- }
2138
- /**
2139
- * Get the location information of the given indexes.
2140
- */
2141
- getLocations(start, end) {
2142
- return {
2143
- range: [start, end],
2144
- loc: {
2145
- start: this.getLocFromIndex(start),
2146
- end: this.getLocFromIndex(end)
2147
- }
2148
- };
2149
- }
2150
- /**
2151
- * Build token
2152
- */
2153
- buildToken(type, range) {
2154
- return {
2155
- type,
2156
- value: this.getText(range),
2157
- ...this.getLocations(...range)
2158
- };
2159
- }
2160
- /**
2161
- * get text
2162
- */
2163
- getText(range) {
2164
- return this.code.slice(range[0], range[1]);
2165
- }
2166
- get originalAST() {
2167
- return this.state.originalAST;
2168
- }
2169
- set originalAST(originalAST) {
2170
- this.state.originalAST = originalAST;
2171
- }
2172
- };
2173
- var LinesAndColumns = class {
2174
- constructor(origCode) {
2175
- const len = origCode.length;
2176
- const lineStartIndices = [0];
2177
- const crs = [];
2178
- let normalizedCode = "";
2179
- for (let index = 0; index < len; ) {
2180
- const c = origCode[index++];
2181
- if (c === "\r") {
2182
- const next = origCode[index++] || "";
2183
- if (next === "\n") {
2184
- normalizedCode += next;
2185
- crs.push(index - 2);
2186
- lineStartIndices.push(index);
2187
- } else {
2188
- normalizedCode += `
2189
- ${next}`;
2190
- lineStartIndices.push(index - 1);
2191
- }
2192
- } else {
2193
- normalizedCode += c;
2194
- if (c === "\n") {
2195
- lineStartIndices.push(index);
2196
- }
2197
- }
2198
- }
2199
- this.lineStartIndices = lineStartIndices;
2200
- this.code = origCode;
2201
- this.normalizedLineFeed = new NormalizedLineFeed(normalizedCode, crs);
2202
- }
2203
- getLocFromIndex(index) {
2204
- const lineNumber = sortedLastIndex(
2205
- this.lineStartIndices,
2206
- (target) => target - index
2207
- );
2208
- return {
2209
- line: lineNumber,
2210
- column: index - this.lineStartIndices[lineNumber - 1]
2211
- };
2212
- }
2213
- getIndexFromLoc(loc) {
2214
- const lineIndex = loc.line - 1;
2215
- if (this.lineStartIndices.length > lineIndex) {
2216
- const lineStartIndex = this.lineStartIndices[lineIndex];
2217
- const positionIndex = lineStartIndex + loc.column;
2218
- return positionIndex;
2219
- } else if (this.lineStartIndices.length === lineIndex) {
2220
- return this.code.length + loc.column;
2221
- }
2222
- return this.code.length + loc.column;
2223
- }
2224
- getNormalizedLineFeed() {
2225
- return this.normalizedLineFeed;
2226
- }
2227
- };
2228
- var NormalizedLineFeed = class {
2229
- get needRemap() {
2230
- return this.offsets.length > 0;
2231
- }
2232
- constructor(code, offsets) {
2233
- this.code = code;
2234
- this.offsets = offsets;
2235
- if (offsets.length) {
2236
- const cache = {};
2237
- this.remapIndex = (index) => {
2238
- let result = cache[index];
2239
- if (result != null) {
2240
- return result;
2241
- }
2242
- result = index;
2243
- for (const offset of offsets) {
2244
- if (offset < result) {
2245
- result++;
2246
- } else {
2247
- break;
2248
- }
2249
- }
2250
- return cache[index] = result;
2251
- };
2252
- } else {
2253
- this.remapIndex = (i) => i;
2254
- }
2255
- }
2256
- };
2257
-
2258
- // src/parser/astro-parser/parse.ts
2259
- var service = __toESM(require("astrojs-compiler-sync"));
2260
- function parse2(code, ctx) {
2261
- const result = service.parse(code, { position: true });
2262
- for (const { code: code2, text, location, severity } of result.diagnostics || []) {
2263
- if (severity === 1) {
2264
- ctx.originalAST = result.ast;
2265
- throw new ParseError(`${text} [${code2}]`, location, ctx);
2266
- }
2267
- }
2268
- if (!result.ast.children) {
2269
- result.ast.children = [];
2270
- }
2271
- const htmlElement = result.ast.children.find(
2272
- (n) => n.type === "element" && n.name === "html"
2273
- );
2274
- if (!result._adjusted) {
2275
- if (htmlElement) {
2276
- adjustHTML(result.ast, htmlElement, ctx);
2277
- }
2278
- fixLocations(result.ast, ctx);
2279
- result._adjusted = true;
2280
- }
2281
- return result;
2282
- }
2283
- function adjustHTML(ast, htmlElement, ctx) {
2284
- const htmlEnd = ctx.code.indexOf("</html");
2285
- if (htmlEnd < 0) {
2286
- return;
2287
- }
2288
- const isOffsetAfter = buildComparableOffsetComparator(ctx.code);
2289
- const hasTokenAfter = Boolean(ctx.code.slice(htmlEnd + 7).trim());
2290
- const children = [...htmlElement.children];
2291
- for (const child of children) {
2292
- const offset = child.position?.start.offset;
2293
- if (hasTokenAfter && offset != null) {
2294
- if (isOffsetAfter(offset, htmlEnd)) {
2295
- htmlElement.children.splice(htmlElement.children.indexOf(child), 1);
2296
- ast.children.push(child);
2297
- }
2298
- }
2299
- if (child.type === "element" && child.name === "body") {
2300
- adjustHTMLBody(
2301
- ast,
2302
- htmlElement,
2303
- htmlEnd,
2304
- hasTokenAfter,
2305
- child,
2306
- ctx,
2307
- isOffsetAfter
2308
- );
2309
- }
2310
- }
2311
- function buildComparableOffsetComparator(code) {
2312
- let remapOffset;
2313
- const comparableOffsetCache = /* @__PURE__ */ new Map();
2314
- return (offset, threshold) => {
2315
- if (threshold > offset) {
2316
- return false;
2317
- }
2318
- let comparableOffset = comparableOffsetCache.get(offset);
2319
- if (comparableOffset == null) {
2320
- remapOffset || (remapOffset = buildComparableOffsetRemapper(code));
2321
- comparableOffset = remapOffset(offset);
2322
- comparableOffsetCache.set(offset, comparableOffset);
2323
- }
2324
- return threshold <= comparableOffset;
2325
- };
2326
- }
2327
- function buildComparableOffsetRemapper(code) {
2328
- let byteOffsets, codeUnitOffsets;
2329
- for (let index = 0, byteOffset = 0; index < code.length; ) {
2330
- const codePoint = code.codePointAt(index);
2331
- const codeUnitLength = codePoint > 65535 ? 2 : 1;
2332
- const nextIndex = index + codeUnitLength;
2333
- const nextByteOffset = byteOffset + getUTF8ByteLength(codePoint);
2334
- if (byteOffsets) {
2335
- byteOffsets.push(nextByteOffset);
2336
- codeUnitOffsets.push(nextIndex);
2337
- } else if (codePoint > 127) {
2338
- byteOffsets = [0];
2339
- codeUnitOffsets = [0];
2340
- for (let asciiOffset = 1; asciiOffset <= index; asciiOffset++) {
2341
- byteOffsets.push(asciiOffset);
2342
- codeUnitOffsets.push(asciiOffset);
2343
- }
2344
- byteOffsets.push(nextByteOffset);
2345
- codeUnitOffsets.push(nextIndex);
2346
- }
2347
- index = nextIndex;
2348
- byteOffset = nextByteOffset;
2349
- }
2350
- if (!byteOffsets || !codeUnitOffsets) {
2351
- return (offset) => offset;
2352
- }
2353
- return (offset) => {
2354
- const index = sortedLastIndex(byteOffsets, (target) => target - offset) - 1;
2355
- return codeUnitOffsets[Math.max(index, 0)];
2356
- };
2357
- }
2358
- function getUTF8ByteLength(codePoint) {
2359
- if (codePoint <= 127) {
2360
- return 1;
2361
- }
2362
- if (codePoint <= 2047) {
2363
- return 2;
2364
- }
2365
- if (codePoint <= 65535) {
2366
- return 3;
2367
- }
2368
- return 4;
2369
- }
2370
- }
2371
- function adjustHTMLBody(ast, htmlElement, htmlEnd, hasTokenAfterHtmlEnd, bodyElement, ctx, isOffsetAfter) {
2372
- const bodyEnd = ctx.code.indexOf("</body");
2373
- if (bodyEnd == null) {
2374
- return;
2375
- }
2376
- const hasTokenAfter = Boolean(ctx.code.slice(bodyEnd + 7, htmlEnd).trim());
2377
- if (!hasTokenAfter && !hasTokenAfterHtmlEnd) {
2378
- return;
2379
- }
2380
- const children = [...bodyElement.children];
2381
- for (const child of children) {
2382
- const offset = child.position?.start.offset;
2383
- if (offset != null && isOffsetAfter(offset, bodyEnd)) {
2384
- if (hasTokenAfterHtmlEnd && isOffsetAfter(offset, htmlEnd)) {
2385
- bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
2386
- ast.children.push(child);
2387
- } else if (hasTokenAfter) {
2388
- bodyElement.children.splice(bodyElement.children.indexOf(child), 1);
2389
- htmlElement.children.push(child);
2390
- }
2391
- }
2392
- }
2393
- }
2394
- function fixLocations(node, ctx) {
2395
- let start = 0;
2396
- walk(
2397
- node,
2398
- ctx.code,
2399
- // eslint-disable-next-line complexity -- X(
2400
- (node2, [parent]) => {
2401
- if (node2.type === "frontmatter") {
2402
- start = node2.position.start.offset = tokenIndex(ctx, "---", start);
2403
- if (!node2.position.end) {
2404
- node2.position.end = {};
2405
- }
2406
- start = node2.position.end.offset = tokenIndex(ctx, "---", start + 3 + node2.value.length) + 3;
2407
- } else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
2408
- if (!node2.position) {
2409
- node2.position = { start: {}, end: {} };
2410
- }
2411
- start = node2.position.start.offset = tokenIndex(ctx, "<", start);
2412
- start += 1;
2413
- start += node2.name.length;
2414
- if (!node2.attributes.length) {
2415
- start = calcStartTagEndOffset(node2, ctx);
2416
- }
2417
- } else if (node2.type === "attribute") {
2418
- fixLocationForAttr(node2, ctx, start);
2419
- start = calcAttributeEndOffset(node2, ctx);
2420
- if (node2.position.end) {
2421
- node2.position.end.offset = start;
2422
- }
2423
- } else if (node2.type === "comment") {
2424
- node2.position.start.offset = tokenIndex(ctx, "<!--", start);
2425
- start = calcCommentEndOffset(node2, ctx);
2426
- if (node2.position.end) {
2427
- node2.position.end.offset = start;
2428
- }
2429
- } else if (node2.type === "text") {
2430
- if (parent.type === "element" && (parent.name === "script" || parent.name === "style")) {
2431
- node2.position.start.offset = start;
2432
- start = ctx.code.indexOf(`</${parent.name}`, start);
2433
- if (start < 0) {
2434
- start = ctx.code.length;
2435
- }
2436
- } else {
2437
- const index = tokenIndexSafe(ctx.code, node2.value, start);
2438
- if (index != null) {
2439
- start = node2.position.start.offset = index;
2440
- start += node2.value.length;
2441
- } else {
2442
- node2.position.start.offset = start;
2443
- const value = node2.value.replace(/\s+/gu, "");
2444
- for (const char of value) {
2445
- const index2 = tokenIndex(ctx, char, start);
2446
- start = index2 + 1;
2447
- }
2448
- start = skipSpaces(ctx.code, start);
2449
- node2.value = ctx.code.slice(node2.position.start.offset, start);
2450
- }
2451
- }
2452
- if (node2.position.end) {
2453
- node2.position.end.offset = start;
2454
- }
2455
- } else if (node2.type === "expression") {
2456
- start = node2.position.start.offset = tokenIndex(ctx, "{", start);
2457
- start += 1;
2458
- } else if (node2.type === "doctype") {
2459
- if (!node2.position) {
2460
- node2.position = { start: {}, end: {} };
2461
- }
2462
- if (!node2.position.end) {
2463
- node2.position.end = {};
2464
- }
2465
- start = node2.position.start.offset = tokenIndex(ctx, "<!", start);
2466
- start += 2;
2467
- start = node2.position.end.offset = ctx.code.indexOf(">", start) + 1;
2468
- } else if (node2.type === "root") {
2469
- }
2470
- },
2471
- (node2, [parent]) => {
2472
- if (node2.type === "attribute") {
2473
- const attributes = parent.attributes;
2474
- if (attributes[attributes.length - 1] === node2) {
2475
- start = calcStartTagEndOffset(parent, ctx);
2476
- }
2477
- } else if (node2.type === "expression") {
2478
- start = tokenIndex(ctx, "}", start) + 1;
2479
- } else if (node2.type === "fragment" || node2.type === "element" || node2.type === "component" || node2.type === "custom-element") {
2480
- if (!getSelfClosingTag(node2, ctx)) {
2481
- const closeTagStart = tokenIndexSafe(
2482
- ctx.code,
2483
- `</${node2.name}`,
2484
- start
2485
- );
2486
- if (closeTagStart != null) {
2487
- start = closeTagStart + 2 + node2.name.length;
2488
- start = tokenIndex(ctx, ">", start) + 1;
2489
- }
2490
- }
2491
- } else {
2492
- return;
2493
- }
2494
- if (node2.position.end) {
2495
- node2.position.end.offset = start;
2496
- }
2497
- }
2498
- );
2499
- }
2500
- function fixLocationForAttr(node, ctx, start) {
2501
- if (node.kind === "empty") {
2502
- node.position.start.offset = tokenIndex(ctx, node.name, start);
2503
- } else if (node.kind === "quoted") {
2504
- node.position.start.offset = tokenIndex(ctx, node.name, start);
2505
- } else if (node.kind === "expression") {
2506
- node.position.start.offset = tokenIndex(ctx, node.name, start);
2507
- } else if (node.kind === "shorthand") {
2508
- node.position.start.offset = tokenIndex(ctx, "{", start);
2509
- } else if (node.kind === "spread") {
2510
- node.position.start.offset = tokenIndex(ctx, "{", start);
2511
- } else if (node.kind === "template-literal") {
2512
- node.position.start.offset = tokenIndex(ctx, node.name, start);
2513
- } else {
2514
- throw new ParseError(
2515
- `Unknown attr kind: ${node.kind}`,
2516
- node.position.start.offset,
2517
- ctx
2518
- );
2519
- }
2520
- }
2521
- function tokenIndex(ctx, token, position) {
2522
- const index = tokenIndexSafe(ctx.code, token, position);
2523
- if (index == null) {
2524
- const start = token.trim() === token ? skipSpaces(ctx.code, position) : position;
2525
- throw new ParseError(
2526
- `Unknown token at ${start}, expected: ${JSON.stringify(
2527
- token
2528
- )}, actual: ${JSON.stringify(ctx.code.slice(start, start + 10))}`,
2529
- start,
2530
- ctx
2531
- );
2532
- }
2533
- return index;
2534
- }
2535
- function tokenIndexSafe(string, token, position) {
2536
- const index = token.trim() === token ? skipSpaces(string, position) : position;
2537
- if (string.startsWith(token, index)) {
2538
- return index;
2539
- }
2540
- return null;
2541
- }
2542
-
2543
- // src/parser/lru-cache.ts
2544
- var LruCache = class extends Map {
2545
- constructor(capacity) {
2546
- super();
2547
- this.capacity = capacity;
2548
- }
2549
- get(key) {
2550
- if (!this.has(key)) {
2551
- return void 0;
2552
- }
2553
- const value = super.get(key);
2554
- this.set(key, value);
2555
- return value;
2556
- }
2557
- set(key, value) {
2558
- this.delete(key);
2559
- super.set(key, value);
2560
- if (this.size > this.capacity) {
2561
- this.deleteOldestEntry();
2562
- }
2563
- return this;
2564
- }
2565
- deleteOldestEntry() {
2566
- for (const entry of this) {
2567
- this.delete(entry[0]);
2568
- return;
2569
- }
2570
- }
2571
- };
2572
-
2573
- // src/parser/template.ts
2574
- var lruCache = new LruCache(5);
2575
- function parseTemplate(code, filePath) {
2576
- const cache = lruCache.get(code);
2577
- if (cache) {
2578
- return cache;
2579
- }
2580
- const ctx = new Context(code, filePath);
2581
- const normalized = ctx.locs.getNormalizedLineFeed();
2582
- const ctxForAstro = normalized.needRemap ? new Context(normalized.code, filePath) : ctx;
2583
- try {
2584
- const result = parse2(normalized?.code ?? code, ctxForAstro);
2585
- if (normalized.needRemap) {
2586
- remap(result, normalized, code, ctxForAstro);
2587
- ctx.originalAST = ctxForAstro.originalAST;
2588
- }
2589
- const templateResult = {
2590
- result,
2591
- context: ctx
2592
- };
2593
- lruCache.set(code, templateResult);
2594
- return templateResult;
2595
- } catch (e) {
2596
- if (typeof e.pos === "number") {
2597
- const err = new ParseError(e.message, normalized?.remapIndex(e.pos), ctx);
2598
- err.astroCompilerError = e;
2599
- throw err;
2600
- }
2601
- throw e;
2602
- }
2603
- }
2604
- function remap(result, normalized, originalCode, ctxForAstro) {
2605
- const remapDataMap = /* @__PURE__ */ new Map();
2606
- walk(
2607
- result.ast,
2608
- normalized.code,
2609
- (node) => {
2610
- const start = normalized.remapIndex(node.position.start.offset);
2611
- let end, value;
2612
- if (node.position.end) {
2613
- end = normalized.remapIndex(node.position.end.offset);
2614
- if (node.position.start.offset === start && node.position.end.offset === end) {
2615
- return;
2616
- }
2617
- }
2618
- if (node.type === "text") {
2619
- value = originalCode.slice(
2620
- start,
2621
- normalized.remapIndex(getEndOffset(node, ctxForAstro))
2622
- );
2623
- } else if (node.type === "comment") {
2624
- value = originalCode.slice(
2625
- start + 4,
2626
- normalized.remapIndex(getEndOffset(node, ctxForAstro)) - 3
2627
- );
2628
- } else if (node.type === "attribute") {
2629
- if (node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
2630
- let valueStart = normalized.remapIndex(
2631
- calcAttributeValueStartOffset(node, ctxForAstro)
2632
- );
2633
- let valueEnd = normalized.remapIndex(
2634
- calcAttributeEndOffset(node, ctxForAstro)
2635
- );
2636
- if (node.kind !== "quoted" || originalCode[valueStart] === '"' || originalCode[valueStart] === "'") {
2637
- valueStart++;
2638
- valueEnd--;
2639
- }
2640
- value = originalCode.slice(valueStart, valueEnd);
2641
- }
2642
- }
2643
- remapDataMap.set(node, {
2644
- start,
2645
- end,
2646
- value
2647
- });
2648
- },
2649
- (_node) => {
2650
- }
2651
- );
2652
- for (const [node, remapData] of remapDataMap) {
2653
- node.position.start.offset = remapData.start;
2654
- if (node.position.end) {
2655
- node.position.end.offset = remapData.end;
2656
- }
2657
- if (node.type === "text" || node.type === "comment" || node.type === "attribute" && node.kind !== "empty" && node.kind !== "shorthand" && node.kind !== "spread") {
2658
- node.value = remapData.value;
2659
- }
2660
- }
2661
- }
2662
-
2663
- // src/context/parser-options.ts
2664
- var import_path5 = __toESM(require("path"));
2665
- var import_fs2 = __toESM(require("fs"));
2666
-
2667
- // src/context/resolve-parser/espree.ts
2668
- var import_module4 = require("module");
2669
- var import_path4 = __toESM(require("path"));
2670
- var espreeCache = null;
2671
- function isLinterPath(p) {
2672
- return (
2673
- // ESLint 6 and above
2674
- p.includes(`eslint${import_path4.default.sep}lib${import_path4.default.sep}linter${import_path4.default.sep}linter.js`) || // ESLint 5
2675
- p.includes(`eslint${import_path4.default.sep}lib${import_path4.default.sep}linter.js`)
2676
- );
2677
- }
2678
- function getEspree() {
2679
- if (!espreeCache) {
2680
- const linterPath = Object.keys(require.cache || {}).find(isLinterPath);
2681
- if (linterPath) {
2682
- try {
2683
- espreeCache = (0, import_module4.createRequire)(linterPath)("espree");
2684
- } catch {
2685
- }
2686
- }
2687
- if (!espreeCache) {
2688
- espreeCache = require("espree");
2689
- }
2690
- }
2691
- return espreeCache;
2692
- }
2693
-
2694
- // src/context/resolve-parser/index.ts
2695
- function getParserForLang(attrs, parser) {
2696
- if (parser) {
2697
- if (typeof parser === "string" || isParserObject(parser)) {
2698
- return parser;
2699
- }
2700
- if (typeof parser === "object") {
2701
- const value = parser[attrs.lang || "js"];
2702
- if (typeof value === "string" || isParserObject(value)) {
2703
- return value;
2704
- }
2705
- }
2706
- }
2707
- return "espree";
2708
- }
2709
- function getParser(attrs, parser) {
2710
- const parserValue = getParserForLang(attrs, parser);
2711
- if (isParserObject(parserValue)) {
2712
- return parserValue;
2713
- }
2714
- if (parserValue !== "espree") {
2715
- return require(parserValue);
2716
- }
2717
- return getEspree();
2718
- }
2719
-
2720
- // src/context/parser-options.ts
2721
- var TS_PARSER_NAMES = [
2722
- "@typescript-eslint/parser",
2723
- "typescript-eslint-parser-for-extra-files"
2724
- ];
2725
- var ParserOptionsContext = class {
2726
- constructor(options) {
2727
- this.state = {};
2728
- const parserOptions = {
2729
- ecmaVersion: 2020,
2730
- sourceType: "module",
2731
- loc: true,
2732
- range: true,
2733
- raw: true,
2734
- tokens: true,
2735
- comment: true,
2736
- eslintVisitorKeys: true,
2737
- // eslintScopeManager: true,
2738
- ...options || {}
2739
- };
2740
- parserOptions.ecmaFeatures = {
2741
- ...parserOptions.ecmaFeatures || {},
2742
- jsx: true
2743
- };
2744
- parserOptions.sourceType = "module";
2745
- if (parserOptions.ecmaVersion <= 5 || parserOptions.ecmaVersion == null) {
2746
- parserOptions.ecmaVersion = 2015;
2747
- }
2748
- this.parserOptions = parserOptions;
2749
- }
2750
- getParser() {
2751
- return getParser({}, this.parserOptions.parser);
2752
- }
2753
- getTSParserName() {
2754
- if (this.state.ts != null) {
2755
- return this.state.ts === false ? null : this.state.ts.parserName;
2756
- }
2757
- const parserValue = getParserForLang({}, this.parserOptions?.parser);
2758
- if (typeof parserValue !== "string") {
2759
- const name2 = getTSParserNameFromObject(parserValue);
2760
- if (name2) {
2761
- this.state.ts = { parserName: name2 };
2762
- return this.state.ts.parserName;
2763
- }
2764
- if (maybeTSESLintParserObject(parserValue) || isTSESLintParserObject(parserValue)) {
2765
- this.state.ts = { parserName: "$unknown$" };
2766
- return this.state.ts.parserName;
2767
- }
2768
- this.state.ts = false;
2769
- return null;
2770
- }
2771
- const parserName = parserValue;
2772
- if (TS_PARSER_NAMES.includes(parserName)) {
2773
- this.state.ts = { parserName };
2774
- return this.state.ts.parserName;
2775
- }
2776
- if (TS_PARSER_NAMES.some((nm) => parserName.includes(nm))) {
2777
- let targetPath = parserName;
2778
- while (targetPath) {
2779
- const pkgPath = import_path5.default.join(targetPath, "package.json");
2780
- if (import_fs2.default.existsSync(pkgPath)) {
2781
- try {
2782
- const pkgName = JSON.parse(import_fs2.default.readFileSync(pkgPath, "utf-8"))?.name;
2783
- if (TS_PARSER_NAMES.includes(pkgName)) {
2784
- this.state.ts = { parserName: pkgName };
2785
- return this.state.ts.parserName;
2786
- }
2787
- this.state.ts = false;
2788
- return null;
2789
- } catch {
2790
- this.state.ts = false;
2791
- return null;
2792
- }
2793
- }
2794
- const parent = import_path5.default.dirname(targetPath);
2795
- if (targetPath === parent) {
2796
- break;
2797
- }
2798
- targetPath = parent;
2799
- }
2800
- }
2801
- this.state.ts = false;
2802
- return null;
2803
- }
2804
- isTypeScript() {
2805
- return Boolean(this.getTSParserName());
2806
- }
2807
- };
2808
-
2809
- // src/parser/index.ts
2810
- function parseForESLint(code, options) {
2811
- const { result: resultTemplate, context: ctx } = parseTemplate(
2812
- code,
2813
- options?.filePath ?? "<input>"
2814
- );
2815
- const scriptContext = processTemplate(ctx, resultTemplate);
2816
- const parserOptions = new ParserOptionsContext(options);
2817
- if (parserOptions.isTypeScript() && /\bAstro\b/u.test(code)) {
2818
- scriptContext.appendVirtualScript(
2819
- `declare const Astro: Readonly<import('astro').AstroGlobal<Props>>;`
2820
- );
2821
- scriptContext.restoreContext.addRestoreNodeProcess(
2822
- (_scriptNode, { result }) => {
2823
- const declareNode = result.ast.body.pop();
2824
- const scopeManager = result.scopeManager;
2825
- if (scopeManager) {
2826
- removeAllScopeAndVariableAndReference(declareNode, {
2827
- visitorKeys: result.visitorKeys,
2828
- scopeManager
2829
- });
2830
- const scope = getProgramScope(scopeManager);
2831
- const propsVariable = scope.set.get("Props");
2832
- if (propsVariable) {
2833
- addVirtualReference(
2834
- propsVariable.identifiers[0],
2835
- propsVariable,
2836
- scope,
2837
- {
2838
- read: true,
2839
- typeRef: true,
2840
- forceUsed: true
2841
- }
2842
- );
2843
- }
2844
- const astroGlobalReferences = scope.through.filter(
2845
- (ref) => ref.identifier.name === "Astro" || ref.identifier.name === "Fragment"
2846
- );
2847
- for (const astroGlobalReference of astroGlobalReferences) {
2848
- addGlobalVariable(astroGlobalReference, scopeManager);
2849
- removeReferenceFromThrough(astroGlobalReference, scope);
2850
- }
2851
- }
2852
- return true;
2853
- }
2854
- );
2855
- }
2856
- const resultScript = parseScript(scriptContext.script, ctx, parserOptions);
2857
- scriptContext.restoreContext.restore(resultScript);
2858
- sort(resultScript.ast.comments);
2859
- sort(resultScript.ast.tokens);
2860
- extractTokens(resultScript, ctx);
2861
- resultScript.services = Object.assign(resultScript.services || {}, {
2862
- isAstro: true,
2863
- getAstroAst() {
2864
- return resultTemplate.ast;
2865
- },
2866
- getAstroResult() {
2867
- return resultTemplate;
2868
- }
2869
- });
2870
- resultScript.visitorKeys = Object.assign({}, KEYS, resultScript.visitorKeys);
2871
- return resultScript;
2872
- }
2873
- function extractTokens(ast, ctx) {
2874
- if (!ast.ast.tokens) {
2875
- return;
2876
- }
2877
- const useRanges = sort([...ast.ast.tokens, ...ast.ast.comments || []]).map(
2878
- (t) => t.range
2879
- );
2880
- let range = useRanges.shift();
2881
- for (let index = 0; index < ctx.code.length; index++) {
2882
- while (range && range[1] <= index) {
2883
- range = useRanges.shift();
2884
- }
2885
- if (range && range[0] <= index) {
2886
- index = range[1] - 1;
2887
- continue;
2888
- }
2889
- const c = ctx.code[index];
2890
- if (!c.trim()) {
2891
- continue;
2892
- }
2893
- if (isPunctuator(c)) {
2894
- ast.ast.tokens.push(
2895
- ctx.buildToken(import_types3.AST_TOKEN_TYPES.Punctuator, [index, index + 1])
2896
- );
2897
- } else {
2898
- ast.ast.tokens.push(
2899
- ctx.buildToken(import_types3.AST_TOKEN_TYPES.Identifier, [index, index + 1])
2900
- );
2901
- }
2902
- }
2903
- sort(ast.ast.tokens);
2904
- function isPunctuator(c) {
2905
- return /^[^\w$]$/iu.test(c);
2906
- }
2907
- }
2908
-
2909
- // src/astro-tools/index.ts
2910
- function parseTemplate2(code) {
2911
- const parsed = parseTemplate(code);
2912
- return {
2913
- result: parsed.result,
2914
- getEndOffset: (node) => getEndOffset(node, parsed.context),
2915
- calcAttributeValueStartOffset: (node) => calcAttributeValueStartOffset(node, parsed.context),
2916
- calcAttributeEndOffset: (node) => calcAttributeEndOffset(node, parsed.context),
2917
- walk(parent, enter, leave) {
2918
- walk(
2919
- parent,
2920
- code,
2921
- enter,
2922
- leave || (() => {
2923
- })
2924
- );
2925
- },
2926
- getLocFromIndex: (index) => parsed.context.getLocFromIndex(index),
2927
- getIndexFromLoc: (loc) => parsed.context.locs.getIndexFromLoc(loc)
2928
- };
2929
- }
2930
-
2931
- // src/ast/index.ts
2932
- var ast_exports = {};
2933
-
2934
- // src/meta.ts
2935
- var meta_exports = {};
2936
- __export(meta_exports, {
2937
- name: () => name,
2938
- version: () => version
2939
- });
2940
-
2941
- // package.json
2942
- var name = "astro-eslint-parser";
2943
- var version = "1.3.2";
2944
-
2945
- // src/index.ts
2946
- function parseForESLint2(code, options) {
2947
- return parseForESLint(code, options);
2948
- }
2949
- var VisitorKeys = KEYS;
2950
- // Annotate the CommonJS export names for ESM import in node:
2951
- 0 && (module.exports = {
2952
- AST,
2953
- ParseError,
2954
- VisitorKeys,
2955
- meta,
2956
- name,
2957
- parseForESLint,
2958
- parseTemplate,
2959
- traverseNodes
2960
- });