astro-eslint-parser 0.0.18 → 0.2.1

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.
Files changed (41) hide show
  1. package/README.md +22 -11
  2. package/lib/ast/astro.d.ts +1 -1
  3. package/lib/ast/index.d.ts +6 -0
  4. package/lib/ast/jsx.d.ts +18 -18
  5. package/lib/astro/index.js +2 -4
  6. package/lib/astro-tools/index.d.ts +21 -0
  7. package/lib/astro-tools/index.js +26 -0
  8. package/lib/context/index.d.ts +13 -8
  9. package/lib/context/index.js +51 -100
  10. package/lib/context/parser-options.d.ts +8 -0
  11. package/lib/context/parser-options.js +71 -0
  12. package/lib/{parser → context/resolve-parser}/espree.d.ts +1 -1
  13. package/lib/{parser → context/resolve-parser}/espree.js +3 -18
  14. package/lib/context/resolve-parser/index.d.ts +5 -0
  15. package/lib/{parser/resolve-parser.js → context/resolve-parser/index.js} +0 -0
  16. package/lib/context/script.d.ts +1 -1
  17. package/lib/context/script.js +2 -3
  18. package/lib/index.d.ts +2 -1
  19. package/lib/index.js +3 -1
  20. package/lib/parser/astro-parser/astrojs-compiler-service.d.ts +2 -4
  21. package/lib/parser/astro-parser/astrojs-compiler-service.js +3 -12
  22. package/lib/parser/astro-parser/astrojs-compiler-worker.d.ts +1 -0
  23. package/lib/parser/astro-parser/astrojs-compiler-worker.js +11 -0
  24. package/lib/parser/astro-parser/parse.js +7 -51
  25. package/lib/parser/index.d.ts +0 -17
  26. package/lib/parser/index.js +6 -31
  27. package/lib/parser/lru-cache.d.ts +7 -0
  28. package/lib/parser/lru-cache.js +32 -0
  29. package/lib/parser/process-template.js +24 -5
  30. package/lib/parser/script.d.ts +3 -2
  31. package/lib/parser/script.js +18 -19
  32. package/lib/parser/template.d.ts +10 -0
  33. package/lib/parser/template.js +102 -0
  34. package/lib/parser/ts-patch.d.ts +8 -0
  35. package/lib/parser/ts-patch.js +58 -0
  36. package/lib/types.d.ts +21 -0
  37. package/lib/types.js +2 -0
  38. package/package.json +8 -5
  39. package/lib/parser/astro-parser/wasm_exec.d.ts +0 -35
  40. package/lib/parser/astro-parser/wasm_exec.js +0 -470
  41. package/lib/parser/resolve-parser.d.ts +0 -16
package/README.md CHANGED
@@ -19,18 +19,19 @@ This parser is in the ***experimental stages*** of development.
19
19
 
20
20
  At least it works fine with a [fork of the `astro.build` repository](https://github.com/ota-meshi/astro.build/tree/eslint).
21
21
 
22
- ⚠ Currently this parser relies heavily on the internal API of [@astrojs/compiler]. It may stop working in a future update of [@astrojs/compiler]. ⚠
23
-
24
22
  [@astrojs/compiler]: https://github.com/withastro/compiler
25
23
 
26
- <!--
24
+ ## :checkered_flag: Motivation
25
+
26
+ This parser allows us to lint the script of `.astro` files.
27
+
28
+ > Note that this parser alone will not lint the scripts inside the `<script>` tag. Use [eslint-plugin-astro] to lint the script inside the `<script>` tag as well.
29
+
27
30
  ### ESLint Plugins Using astro-eslint-parser
28
31
 
29
- #### [@ota-meshi/eslint-plugin-astro](https://ota-meshi.github.io/eslint-plugin-astro/)
32
+ #### [eslint-plugin-astro]
30
33
 
31
- ESLint plugin for Astro.
32
- It provides many unique check rules by using the template AST.
33
- -->
34
+ ESLint plugin for Astro component.
34
35
 
35
36
  ## 💿 Installation
36
37
 
@@ -62,7 +63,7 @@ npm install --save-dev eslint astro-eslint-parser
62
63
  $ eslint src --ext .js,.astro
63
64
  ```
64
65
 
65
- The commit diff [here](https://github.com/ota-meshi/astro.build/commit/7f291ac15e6d97cc20a64b8f97dcbd85379759b5) is an example of introducing this parser to the `astro.build` repository.
66
+ The commit diff [here](https://github.com/withastro/astro.build/compare/main...ota-meshi:eslint) is an example of introducing this parser to the `astro.build` repository.
66
67
 
67
68
  ## 🔧 Options
68
69
 
@@ -154,13 +155,21 @@ For example, the [react/jsx-no-target-blank] rule works fine.
154
155
  [eslint-plugin-react]: https://github.com/jsx-eslint/eslint-plugin-react/
155
156
  [react/jsx-no-target-blank]: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
156
157
 
158
+ ## :ghost: Limitations
159
+
160
+ If this parser is used with `@typescript-eslint/parser` and `parserOptions.project` is set, it will temporarily create a `.tsx` file to parse the `.astro` file.
161
+ This parser works by converting the `.astro` file to JSX and letting the JavaScript parser parse it.
162
+ Since `@typescript-eslint/parser` can only parse files with the extension `.tsx` as JSX, it is necessary to temporarily create a `.tsx` file. Temporarily created files will try to be deleted after parses, but if the parsing takes a long time, the files may be visible to you.
163
+
164
+ See also [`@typescript-eslint/parser` readme](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/parser#parseroptionsecmafeaturesjsx).
165
+
157
166
  ## :hammer_and_wrench: Usage for Custom Rules / Plugins
158
167
 
168
+ <!-- - [AST.md](./docs/AST.md) is AST specification. You can check it on the [Online DEMO](https://ota-meshi.github.io/astro-eslint-parser/). -->
169
+
159
170
  - TBA
160
171
  - You can check the AST in the [Online DEMO](https://ota-meshi.github.io/astro-eslint-parser/). However, AST is subject to major changes in the future.
161
-
162
- <!-- - [AST.md](./docs/AST.md) is AST specification. You can check it on the [Online DEMO](https://ota-meshi.github.io/astro-eslint-parser/). -->
163
- <!-- - I have already [implemented some rules] in the [`@ota-meshi/eslint-plugin-astro`]. The source code for these rules will be helpful to you. -->
172
+ - I have already [implemented some rules] in the [eslint-plugin-astro]. The source code for these rules will be helpful to you.
164
173
 
165
174
  ## :beers: Contributing
166
175
 
@@ -180,3 +189,5 @@ See the [LICENSE](LICENSE) file for license rights and limitations (MIT).
180
189
 
181
190
  [Astro]: https://astro.build/
182
191
  [ESLint]: https://eslint.org/
192
+ [eslint-plugin-astro]: https://ota-meshi.github.io/eslint-plugin-astro/
193
+ [implemented some rules]: https://ota-meshi.github.io/eslint-plugin-astro/rules/
@@ -2,7 +2,7 @@ import type { JSXAttribute, JSXElement, JSXExpression, JSXExpressionContainer, J
2
2
  import type { TSESTree as ES } from "@typescript-eslint/types";
3
3
  import type { BaseNode } from "./base";
4
4
  export declare type AstroNode = AstroProgram | AstroFragment | AstroHTMLComment | AstroDoctype | AstroShorthandAttribute | AstroTemplateLiteralAttribute | AstroRawText;
5
- export declare type AstroChild = JSXElement | JSXFragment | JSXExpression | JSXText | AstroHTMLComment;
5
+ export declare type AstroChild = JSXElement | JSXFragment | JSXExpression | JSXText | AstroHTMLComment | AstroRawText;
6
6
  export declare type AstroParentNode = JSXElement | JSXFragment | AstroFragment;
7
7
  /** Node of Astro program root */
8
8
  export interface AstroProgram extends Omit<ES.Program, "type" | "body"> {
@@ -1,2 +1,8 @@
1
1
  export * from "./astro";
2
2
  export * from "./jsx";
3
+ import type { TSESTree } from "@typescript-eslint/types";
4
+ export declare type Comment = TSESTree.Comment;
5
+ export declare type Token = TSESTree.Token;
6
+ export declare type SourceLocation = TSESTree.SourceLocation;
7
+ export declare type Range = TSESTree.Range;
8
+ export declare type Position = TSESTree.Position;
package/lib/ast/jsx.d.ts CHANGED
@@ -1,25 +1,25 @@
1
- import type { TSESTree as ES, AST_NODE_TYPES } from "@typescript-eslint/types";
2
- import type { AstroFragment, AstroHTMLComment, AstroShorthandAttribute, AstroTemplateLiteralAttribute } from "./astro";
1
+ import type { TSESTree as ES } from "@typescript-eslint/types";
2
+ import type { AstroFragment, AstroHTMLComment, AstroRawText, AstroShorthandAttribute, AstroTemplateLiteralAttribute } from "./astro";
3
3
  import type { BaseNode } from "./base";
4
4
  export declare type JSXNode = JSXAttribute | JSXClosingElement | JSXClosingFragment | JSXElement | JSXEmptyExpression | JSXExpressionContainer | JSXFragment | JSXIdentifier | JSXMemberExpression | JSXNamespacedName | JSXOpeningElement | JSXOpeningFragment | JSXSpreadAttribute | JSXSpreadChild | JSXText;
5
- export declare type JSXChild = JSXElement | JSXFragment | JSXExpression | JSXText | AstroHTMLComment;
5
+ export declare type JSXChild = JSXElement | JSXFragment | JSXExpression | JSXText | AstroHTMLComment | AstroRawText;
6
6
  export declare type JSXParentNode = JSXElement | JSXFragment | AstroFragment;
7
7
  export interface JSXElement extends BaseNode {
8
- type: AST_NODE_TYPES.JSXElement;
8
+ type: "JSXElement";
9
9
  openingElement: JSXOpeningElement;
10
10
  closingElement: JSXClosingElement | null;
11
11
  children: JSXChild[];
12
12
  parent?: JSXParentNode;
13
13
  }
14
14
  export interface JSXFragment extends BaseNode {
15
- type: AST_NODE_TYPES.JSXFragment;
15
+ type: "JSXFragment";
16
16
  openingFragment: JSXOpeningFragment;
17
17
  closingFragment: JSXClosingFragment;
18
18
  children: JSXChild[];
19
19
  parent?: JSXParentNode;
20
20
  }
21
21
  export interface JSXOpeningElement extends BaseNode {
22
- type: AST_NODE_TYPES.JSXOpeningElement;
22
+ type: "JSXOpeningElement";
23
23
  typeParameters?: ES.TSTypeParameterInstantiation;
24
24
  selfClosing: boolean;
25
25
  name: JSXTagNameExpression;
@@ -27,64 +27,64 @@ export interface JSXOpeningElement extends BaseNode {
27
27
  parent?: JSXElement;
28
28
  }
29
29
  export interface JSXClosingElement extends BaseNode {
30
- type: AST_NODE_TYPES.JSXClosingElement;
30
+ type: "JSXClosingElement";
31
31
  name: JSXTagNameExpression;
32
32
  parent?: JSXElement;
33
33
  }
34
34
  export interface JSXClosingFragment extends BaseNode {
35
- type: AST_NODE_TYPES.JSXClosingFragment;
35
+ type: "JSXClosingFragment";
36
36
  parent?: JSXFragment;
37
37
  }
38
38
  export interface JSXOpeningFragment extends BaseNode {
39
- type: AST_NODE_TYPES.JSXOpeningFragment;
39
+ type: "JSXOpeningFragment";
40
40
  parent?: JSXFragment;
41
41
  }
42
42
  export interface JSXAttribute extends BaseNode {
43
- type: AST_NODE_TYPES.JSXAttribute;
43
+ type: "JSXAttribute";
44
44
  name: JSXIdentifier | JSXNamespacedName;
45
45
  value: JSXExpression | ES.Literal | null;
46
46
  parent?: JSXOpeningElement;
47
47
  }
48
48
  export interface JSXSpreadAttribute extends BaseNode {
49
- type: AST_NODE_TYPES.JSXSpreadAttribute;
49
+ type: "JSXSpreadAttribute";
50
50
  argument: ES.Expression;
51
51
  parent?: JSXOpeningElement;
52
52
  }
53
53
  export declare type JSXTagNameExpression = JSXIdentifier | JSXMemberExpression | JSXNamespacedName;
54
54
  export interface JSXIdentifier extends BaseNode {
55
- type: AST_NODE_TYPES.JSXIdentifier;
55
+ type: "JSXIdentifier";
56
56
  name: string;
57
57
  parent?: JSXAttribute | AstroShorthandAttribute | AstroTemplateLiteralAttribute | JSXMemberExpression | JSXNamespacedName | JSXOpeningElement | JSXClosingElement;
58
58
  }
59
59
  export interface JSXMemberExpression extends BaseNode {
60
- type: AST_NODE_TYPES.JSXMemberExpression;
60
+ type: "JSXMemberExpression";
61
61
  object: JSXTagNameExpression;
62
62
  property: JSXIdentifier;
63
63
  parent?: JSXMemberExpression | JSXOpeningElement | JSXClosingElement;
64
64
  }
65
65
  export interface JSXNamespacedName extends BaseNode {
66
- type: AST_NODE_TYPES.JSXNamespacedName;
66
+ type: "JSXNamespacedName";
67
67
  namespace: JSXIdentifier;
68
68
  name: JSXIdentifier;
69
69
  parent?: JSXAttribute | AstroShorthandAttribute | AstroTemplateLiteralAttribute | JSXMemberExpression | JSXOpeningElement | JSXClosingElement;
70
70
  }
71
71
  export declare type JSXExpression = JSXExpressionContainer | JSXSpreadChild;
72
72
  export interface JSXExpressionContainer extends BaseNode {
73
- type: AST_NODE_TYPES.JSXExpressionContainer;
73
+ type: "JSXExpressionContainer";
74
74
  expression: ES.Expression | JSXEmptyExpression;
75
75
  parent?: JSXAttribute | AstroShorthandAttribute | AstroTemplateLiteralAttribute | JSXParentNode;
76
76
  }
77
77
  export interface JSXSpreadChild extends BaseNode {
78
- type: AST_NODE_TYPES.JSXSpreadChild;
78
+ type: "JSXSpreadChild";
79
79
  expression: ES.Expression;
80
80
  parent?: JSXAttribute | JSXParentNode;
81
81
  }
82
82
  export interface JSXEmptyExpression extends BaseNode {
83
- type: AST_NODE_TYPES.JSXEmptyExpression;
83
+ type: "JSXEmptyExpression";
84
84
  parent?: JSXExpressionContainer;
85
85
  }
86
86
  export interface JSXText extends BaseNode {
87
- type: AST_NODE_TYPES.JSXText;
87
+ type: "JSXText";
88
88
  value: string;
89
89
  raw: string;
90
90
  parent?: JSXParentNode;
@@ -116,8 +116,7 @@ exports.calcAttributeValueStartOffset = calcAttributeValueStartOffset;
116
116
  * Get end offset of tag
117
117
  */
118
118
  function getEndOffset(node, ctx) {
119
- var _a;
120
- if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
119
+ if (node.position.end?.offset != null) {
121
120
  return node.position.end.offset;
122
121
  }
123
122
  if (isTag(node))
@@ -323,8 +322,7 @@ exports.skipSpaces = skipSpaces;
323
322
  * Get children
324
323
  */
325
324
  function getSortedChildren(parent, code) {
326
- var _a;
327
- if (parent.type === "root" && ((_a = parent.children[0]) === null || _a === void 0 ? void 0 : _a.type) === "frontmatter") {
325
+ if (parent.type === "root" && parent.children[0]?.type === "frontmatter") {
328
326
  // The order of comments and frontmatter may be changed.
329
327
  const children = [...parent.children];
330
328
  if (children.every((n) => n.position)) {
@@ -0,0 +1,21 @@
1
+ import type { ParseResult } from "@astrojs/compiler";
2
+ import type { AttributeNode, Node, ParentNode } from "@astrojs/compiler/types";
3
+ export interface ParseTemplateResult {
4
+ result: ParseResult;
5
+ getEndOffset: (node: Node) => number;
6
+ calcAttributeValueStartOffset: (node: AttributeNode) => number;
7
+ calcAttributeEndOffset: (node: AttributeNode) => number;
8
+ walk: (parent: ParentNode, enter: (n: Node | AttributeNode, parents: ParentNode[]) => void, leave?: (n: Node | AttributeNode, parents: ParentNode[]) => void) => void;
9
+ getLocFromIndex: (index: number) => {
10
+ line: number;
11
+ column: number;
12
+ };
13
+ getIndexFromLoc: (loc: {
14
+ line: number;
15
+ column: number;
16
+ }) => number;
17
+ }
18
+ /**
19
+ * Parse the astro component template.
20
+ */
21
+ export declare function parseTemplate(code: string): ParseTemplateResult;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTemplate = void 0;
4
+ const template_1 = require("../parser/template");
5
+ const astro_1 = require("../astro");
6
+ /**
7
+ * Parse the astro component template.
8
+ */
9
+ function parseTemplate(code) {
10
+ const parsed = (0, template_1.parseTemplate)(code);
11
+ return {
12
+ result: parsed.result,
13
+ getEndOffset: (node) => (0, astro_1.getEndOffset)(node, parsed.context),
14
+ calcAttributeValueStartOffset: (node) => (0, astro_1.calcAttributeValueStartOffset)(node, parsed.context),
15
+ calcAttributeEndOffset: (node) => (0, astro_1.calcAttributeEndOffset)(node, parsed.context),
16
+ walk(parent, enter, leave) {
17
+ (0, astro_1.walk)(parent, code, enter, leave ||
18
+ (() => {
19
+ /* noop */
20
+ }));
21
+ },
22
+ getLocFromIndex: (index) => parsed.context.getLocFromIndex(index),
23
+ getIndexFromLoc: (loc) => parsed.context.locs.getIndexFromLoc(loc),
24
+ };
25
+ }
26
+ exports.parseTemplate = parseTemplate;
@@ -1,16 +1,14 @@
1
1
  import type { TSESTree } from "@typescript-eslint/types";
2
- import type { ESLintExtendedProgram } from "../parser";
3
2
  declare type RangeAndLoc = {
4
3
  range: TSESTree.Range;
5
4
  loc: TSESTree.SourceLocation;
6
5
  };
7
6
  export declare class Context {
8
7
  readonly code: string;
9
- readonly parserOptions: any;
10
8
  readonly locs: LinesAndColumns;
11
9
  private readonly locsMap;
12
10
  private readonly state;
13
- constructor(code: string, parserOptions: any);
11
+ constructor(code: string);
14
12
  getLocFromIndex(index: number): {
15
13
  line: number;
16
14
  column: number;
@@ -27,15 +25,12 @@ export declare class Context {
27
25
  * get text
28
26
  */
29
27
  getText(range: TSESTree.Range): string;
30
- isTypeScript(): boolean;
31
- remapCR({ ast, visitorKeys }: ESLintExtendedProgram): void;
32
28
  get originalAST(): any;
33
29
  set originalAST(originalAST: any);
34
30
  }
35
31
  export declare class LinesAndColumns {
36
- readonly code: string;
37
- private readonly crs;
38
32
  private readonly lineStartIndices;
33
+ private readonly normalizedLineFeed;
39
34
  constructor(origCode: string);
40
35
  getLocFromIndex(index: number): {
41
36
  line: number;
@@ -45,6 +40,16 @@ export declare class LinesAndColumns {
45
40
  line: number;
46
41
  column: number;
47
42
  }): number;
48
- getCRs(): number[];
43
+ getNormalizedLineFeed(): NormalizedLineFeed;
44
+ }
45
+ export declare class NormalizedLineFeed {
46
+ readonly code: string;
47
+ private readonly offsets;
48
+ get needRemap(): boolean;
49
+ /**
50
+ * Remap index
51
+ */
52
+ readonly remapIndex: (index: number) => number;
53
+ constructor(code: string, offsets: number[]);
49
54
  }
50
55
  export {};
@@ -1,20 +1,12 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.LinesAndColumns = exports.Context = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const fs_1 = __importDefault(require("fs"));
9
- const resolve_parser_1 = require("../parser/resolve-parser");
10
- const traverse_1 = require("../traverse");
3
+ exports.NormalizedLineFeed = exports.LinesAndColumns = exports.Context = void 0;
11
4
  class Context {
12
- constructor(code, parserOptions) {
5
+ constructor(code) {
13
6
  this.locsMap = new Map();
14
7
  this.state = {};
15
8
  this.locs = new LinesAndColumns(code);
16
- this.code = this.locs.code;
17
- this.parserOptions = parserOptions;
9
+ this.code = code;
18
10
  }
19
11
  getLocFromIndex(index) {
20
12
  let loc = this.locsMap.get(index);
@@ -43,7 +35,11 @@ class Context {
43
35
  * Build token
44
36
  */
45
37
  buildToken(type, range) {
46
- return Object.assign({ type, value: this.getText(range) }, this.getLocations(...range));
38
+ return {
39
+ type,
40
+ value: this.getText(range),
41
+ ...this.getLocations(...range),
42
+ };
47
43
  }
48
44
  /**
49
45
  * get text
@@ -51,84 +47,6 @@ class Context {
51
47
  getText(range) {
52
48
  return this.code.slice(range[0], range[1]);
53
49
  }
54
- isTypeScript() {
55
- var _a, _b;
56
- if (this.state.isTypeScript != null) {
57
- return this.state.isTypeScript;
58
- }
59
- const parserName = (0, resolve_parser_1.getParserName)({}, (_a = this.parserOptions) === null || _a === void 0 ? void 0 : _a.parser);
60
- if (parserName === "@typescript-eslint/parser") {
61
- return (this.state.isTypeScript = true);
62
- }
63
- if (parserName.includes("@typescript-eslint/parser")) {
64
- let targetPath = parserName;
65
- while (targetPath) {
66
- const pkgPath = path_1.default.join(targetPath, "package.json");
67
- if (fs_1.default.existsSync(pkgPath)) {
68
- try {
69
- return (this.state.isTypeScript =
70
- ((_b = JSON.parse(fs_1.default.readFileSync(pkgPath, "utf-8"))) === null || _b === void 0 ? void 0 : _b.name) === "@typescript-eslint/parser");
71
- }
72
- catch (_c) {
73
- return (this.state.isTypeScript = false);
74
- }
75
- }
76
- const parent = path_1.default.dirname(targetPath);
77
- if (targetPath === parent) {
78
- break;
79
- }
80
- targetPath = parent;
81
- }
82
- }
83
- return (this.state.isTypeScript = false);
84
- }
85
- remapCR({ ast, visitorKeys }) {
86
- const crs = this.locs.getCRs();
87
- if (!crs.length) {
88
- return;
89
- }
90
- const cache = {};
91
- /**
92
- * Remap index
93
- */
94
- function remapIndex(index) {
95
- let result = cache[index];
96
- if (result != null) {
97
- return result;
98
- }
99
- result = index;
100
- for (const cr of crs) {
101
- if (cr < result) {
102
- result++;
103
- }
104
- else {
105
- break;
106
- }
107
- }
108
- return (cache[index] = result);
109
- }
110
- /**
111
- * Remap range
112
- */
113
- function remapRange(range) {
114
- return [remapIndex(range[0]), remapIndex(range[1])];
115
- }
116
- (0, traverse_1.traverseNodes)(ast, {
117
- visitorKeys,
118
- enterNode(node) {
119
- node.range = remapRange(node.range);
120
- },
121
- leaveNode() {
122
- // ignore
123
- },
124
- });
125
- for (const token of ast.tokens || []) {
126
- token.range = remapRange(token.range);
127
- }
128
- for (const comment of ast.comments || []) {
129
- comment.range = remapRange(comment.range);
130
- }
131
- }
132
50
  get originalAST() {
133
51
  return this.state.originalAST;
134
52
  }
@@ -142,30 +60,31 @@ class LinesAndColumns {
142
60
  const len = origCode.length;
143
61
  const lineStartIndices = [0];
144
62
  const crs = [];
145
- let code = "";
63
+ let normalizedCode = "";
146
64
  for (let index = 0; index < len;) {
147
65
  const c = origCode[index++];
148
66
  if (c === "\r") {
149
67
  const next = origCode[index++] || "";
150
68
  if (next === "\n") {
151
- code += next;
69
+ normalizedCode += next;
152
70
  crs.push(index - 2);
71
+ lineStartIndices.push(index);
153
72
  }
154
73
  else {
155
- code += `\n${next}`;
74
+ normalizedCode += `\n${next}`;
75
+ lineStartIndices.push(index - 1);
156
76
  }
157
- lineStartIndices.push(code.length);
158
77
  }
159
78
  else {
160
- code += c;
79
+ normalizedCode += c;
161
80
  if (c === "\n") {
162
- lineStartIndices.push(code.length);
81
+ lineStartIndices.push(index);
163
82
  }
164
83
  }
165
84
  }
166
85
  this.lineStartIndices = lineStartIndices;
167
- this.code = code;
168
- this.crs = crs;
86
+ //
87
+ this.normalizedLineFeed = new NormalizedLineFeed(normalizedCode, crs);
169
88
  }
170
89
  getLocFromIndex(index) {
171
90
  const lineNumber = sortedLastIndex(this.lineStartIndices, index);
@@ -179,11 +98,43 @@ class LinesAndColumns {
179
98
  const positionIndex = lineStartIndex + loc.column;
180
99
  return positionIndex;
181
100
  }
182
- getCRs() {
183
- return this.crs;
101
+ getNormalizedLineFeed() {
102
+ return this.normalizedLineFeed;
184
103
  }
185
104
  }
186
105
  exports.LinesAndColumns = LinesAndColumns;
106
+ class NormalizedLineFeed {
107
+ constructor(code, offsets) {
108
+ this.code = code;
109
+ this.offsets = offsets;
110
+ if (offsets.length) {
111
+ const cache = {};
112
+ this.remapIndex = (index) => {
113
+ let result = cache[index];
114
+ if (result != null) {
115
+ return result;
116
+ }
117
+ result = index;
118
+ for (const offset of offsets) {
119
+ if (offset < result) {
120
+ result++;
121
+ }
122
+ else {
123
+ break;
124
+ }
125
+ }
126
+ return (cache[index] = result);
127
+ };
128
+ }
129
+ else {
130
+ this.remapIndex = (i) => i;
131
+ }
132
+ }
133
+ get needRemap() {
134
+ return this.offsets.length > 0;
135
+ }
136
+ }
137
+ exports.NormalizedLineFeed = NormalizedLineFeed;
187
138
  /**
188
139
  * Uses a binary search to determine the highest index at which value should be inserted into array in order to maintain its sort order.
189
140
  */
@@ -0,0 +1,8 @@
1
+ import type { ESLintCustomParser } from "../types";
2
+ export declare class ParserOptionsContext {
3
+ readonly parserOptions: any;
4
+ private readonly state;
5
+ constructor(options: any);
6
+ getParser(): ESLintCustomParser;
7
+ isTypeScript(): boolean;
8
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ParserOptionsContext = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const resolve_parser_1 = require("./resolve-parser");
10
+ class ParserOptionsContext {
11
+ constructor(options) {
12
+ this.state = {};
13
+ const parserOptions = {
14
+ ecmaVersion: 2020,
15
+ sourceType: "module",
16
+ loc: true,
17
+ range: true,
18
+ raw: true,
19
+ tokens: true,
20
+ comment: true,
21
+ eslintVisitorKeys: true,
22
+ eslintScopeManager: true,
23
+ ...(options || {}),
24
+ };
25
+ parserOptions.ecmaFeatures = {
26
+ ...(parserOptions.ecmaFeatures || {}),
27
+ jsx: true,
28
+ };
29
+ parserOptions.sourceType = "module";
30
+ if (parserOptions.ecmaVersion <= 5 ||
31
+ parserOptions.ecmaVersion == null) {
32
+ parserOptions.ecmaVersion = 2015;
33
+ }
34
+ this.parserOptions = parserOptions;
35
+ }
36
+ getParser() {
37
+ return (0, resolve_parser_1.getParser)({}, this.parserOptions.parser);
38
+ }
39
+ isTypeScript() {
40
+ if (this.state.isTypeScript != null) {
41
+ return this.state.isTypeScript;
42
+ }
43
+ const parserName = (0, resolve_parser_1.getParserName)({}, this.parserOptions?.parser);
44
+ if (parserName === "@typescript-eslint/parser") {
45
+ return (this.state.isTypeScript = true);
46
+ }
47
+ if (parserName.includes("@typescript-eslint/parser")) {
48
+ let targetPath = parserName;
49
+ while (targetPath) {
50
+ const pkgPath = path_1.default.join(targetPath, "package.json");
51
+ if (fs_1.default.existsSync(pkgPath)) {
52
+ try {
53
+ return (this.state.isTypeScript =
54
+ JSON.parse(fs_1.default.readFileSync(pkgPath, "utf-8"))
55
+ ?.name === "@typescript-eslint/parser");
56
+ }
57
+ catch {
58
+ return (this.state.isTypeScript = false);
59
+ }
60
+ }
61
+ const parent = path_1.default.dirname(targetPath);
62
+ if (targetPath === parent) {
63
+ break;
64
+ }
65
+ targetPath = parent;
66
+ }
67
+ }
68
+ return (this.state.isTypeScript = false);
69
+ }
70
+ }
71
+ exports.ParserOptionsContext = ParserOptionsContext;
@@ -1,4 +1,4 @@
1
- import type { ESLintCustomParser } from "./resolve-parser";
1
+ import type { ESLintCustomParser } from "../../types";
2
2
  /**
3
3
  * Load `espree` from the loaded ESLint.
4
4
  * If the loaded ESLint was not found, just returns `require("espree")`.
@@ -4,23 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getEspree = void 0;
7
- const module_1 = __importDefault(require("module"));
7
+ const module_1 = require("module");
8
8
  const path_1 = __importDefault(require("path"));
9
- const createRequire =
10
- // Added in v12.2.0
11
- module_1.default.createRequire ||
12
- // Added in v10.12.0, but deprecated in v12.2.0.
13
- // @ts-expect-error -- old type
14
- module_1.default.createRequireFromPath ||
15
- // Polyfill - This is not executed on the tests on node@>=10.
16
- /* istanbul ignore next */
17
- ((modName) => {
18
- const mod = new module_1.default(modName);
19
- mod.filename = modName;
20
- mod.paths = module_1.default._nodeModulePaths(path_1.default.dirname(modName));
21
- mod._compile("module.exports = require;", modName);
22
- return mod.exports;
23
- });
24
9
  let espreeCache = null;
25
10
  /** Checks if given path is linter path */
26
11
  function isLinterPath(p) {
@@ -40,9 +25,9 @@ function getEspree() {
40
25
  const linterPath = Object.keys(require.cache || {}).find(isLinterPath);
41
26
  if (linterPath) {
42
27
  try {
43
- espreeCache = createRequire(linterPath)("espree");
28
+ espreeCache = (0, module_1.createRequire)(linterPath)("espree");
44
29
  }
45
- catch (_a) {
30
+ catch {
46
31
  // ignore
47
32
  }
48
33
  }
@@ -0,0 +1,5 @@
1
+ import type { ESLintCustomParser } from "../../types";
2
+ /** Get parser name */
3
+ export declare function getParserName(attrs: Record<string, string | undefined>, parser: any): string;
4
+ /** Get parser */
5
+ export declare function getParser(attrs: Record<string, string | undefined>, parser: any): ESLintCustomParser;
@@ -1,6 +1,6 @@
1
1
  import type { Context } from ".";
2
- import type { ESLintExtendedProgram } from "../parser";
3
2
  import type { TSESTree } from "@typescript-eslint/types";
3
+ import type { ESLintExtendedProgram } from "../types";
4
4
  declare class RestoreNodeProcessContext {
5
5
  readonly result: ESLintExtendedProgram;
6
6
  readonly removeTokens: Set<(token: TSESTree.Token) => boolean>;