astro-eslint-parser 0.0.15 → 0.0.16

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/README.md CHANGED
@@ -15,6 +15,8 @@ You can check it on [Online DEMO](https://ota-meshi.github.io/astro-eslint-parse
15
15
 
16
16
  This parser is in the ***experimental stages*** of development.
17
17
 
18
+ At least it works fine with a [fork of the `astro.build` repository](https://github.com/ota-meshi/astro.build/tree/eslint).
19
+
18
20
  ⚠ Currently this parser relies heavily on the internal API of [@astrojs/compiler]. It may stop working in a future update of [@astrojs/compiler]. ⚠
19
21
 
20
22
  [@astrojs/compiler]: https://github.com/withastro/compiler
@@ -37,25 +39,28 @@ npm install --save-dev eslint astro-eslint-parser
37
39
  ## 📖 Usage
38
40
 
39
41
  1. Write `overrides.parser` option into your `.eslintrc.*` file.
40
- 2. Use glob patterns or `--ext .astro` CLI option.
41
42
 
42
- ```json
43
- {
44
- "extends": "eslint:recommended",
45
- "overrides": [
46
- {
47
- "files": ["*.astro"],
48
- "parser": "astro-eslint-parser"
49
- }
50
- ]
51
- }
52
- ```
43
+ ```json
44
+ {
45
+ "extends": "eslint:recommended",
46
+ "overrides": [
47
+ {
48
+ "files": ["*.astro"],
49
+ "parser": "astro-eslint-parser"
50
+ }
51
+ ]
52
+ }
53
+ ```
53
54
 
54
- ```console
55
- $ eslint "src/**/*.{js,astro}"
56
- # or
57
- $ eslint src --ext .astro
58
- ```
55
+ 2. If you have specified the extension in the CLI, add `.astro` as well.
56
+
57
+ ```console
58
+ $ eslint "src/**/*.{js,astro}"
59
+ # or
60
+ $ eslint src --ext .js,.astro
61
+ ```
62
+
63
+ 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.
59
64
 
60
65
  ## 🔧 Options
61
66
 
@@ -1,4 +1,4 @@
1
- import type { AttributeNode, CommentNode, ExpressionNode, Node, ParentNode, TagLikeNode } from "@astrojs/compiler/types";
1
+ import type { AttributeNode, CommentNode, Node, ParentNode, TagLikeNode } from "@astrojs/compiler/types";
2
2
  import type { Context } from "../context";
3
3
  /**
4
4
  * Checks if the given node is TagLikeNode
@@ -15,35 +15,27 @@ export declare function walk(parent: ParentNode, code: string, enter: (n: Node |
15
15
  /**
16
16
  * Get end offset of start tag
17
17
  */
18
- export declare function getStartTagEndOffset(node: TagLikeNode, ctx: Context): number;
19
- /**
20
- * Get end offset of tag
21
- */
22
- export declare function getTagEndOffset(node: TagLikeNode, ctx: Context): number;
23
- /**
24
- * Get end offset of Expression
25
- */
26
- export declare function getExpressionEndOffset(node: ExpressionNode, ctx: Context): number;
18
+ export declare function calcStartTagEndOffset(node: TagLikeNode, ctx: Context): number;
27
19
  /**
28
20
  * Get end offset of attribute
29
21
  */
30
- export declare function getAttributeEndOffset(node: AttributeNode, ctx: Context): number;
22
+ export declare function calcAttributeEndOffset(node: AttributeNode, ctx: Context): number;
31
23
  /**
32
24
  * Get start offset of attribute value
33
25
  */
34
- export declare function getAttributeValueStartOffset(node: AttributeNode, ctx: Context): number;
26
+ export declare function calcAttributeValueStartOffset(node: AttributeNode, ctx: Context): number;
35
27
  /**
36
- * Get end offset of comment
28
+ * Get end offset of tag
37
29
  */
38
- export declare function getCommentEndOffset(node: CommentNode, ctx: Context): number;
30
+ export declare function getEndOffset(node: Node, ctx: Context): number;
39
31
  /**
40
32
  * Get content end offset
41
33
  */
42
- export declare function getContentEndOffset(parent: ParentNode, ctx: Context): number;
34
+ export declare function calcContentEndOffset(parent: ParentNode, ctx: Context): number;
43
35
  /**
44
36
  * If the given tag is a self-close tag, get the self-closing tag.
45
37
  */
46
- export declare function getSelfClosingTag(node: TagLikeNode, parent: ParentNode, ctx: Context): null | {
38
+ export declare function getSelfClosingTag(node: TagLikeNode, ctx: Context): null | {
47
39
  offset: number;
48
40
  end: "/>" | ">";
49
41
  };
@@ -54,6 +46,10 @@ export declare function getEndTag(node: TagLikeNode, ctx: Context): null | {
54
46
  offset: number;
55
47
  tag: string;
56
48
  };
49
+ /**
50
+ * Get end offset of comment
51
+ */
52
+ export declare function calcCommentEndOffset(node: CommentNode, ctx: Context): number;
57
53
  /**
58
54
  * Skip spaces
59
55
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.skipSpaces = exports.getEndTag = exports.getSelfClosingTag = exports.getContentEndOffset = exports.getCommentEndOffset = exports.getAttributeValueStartOffset = exports.getAttributeEndOffset = exports.getExpressionEndOffset = exports.getTagEndOffset = exports.getStartTagEndOffset = exports.walk = exports.walkElements = exports.isParent = exports.isTag = void 0;
3
+ exports.skipSpaces = exports.calcCommentEndOffset = exports.getEndTag = exports.getSelfClosingTag = exports.calcContentEndOffset = exports.getEndOffset = exports.calcAttributeValueStartOffset = exports.calcAttributeEndOffset = exports.calcStartTagEndOffset = exports.walk = exports.walkElements = exports.isParent = exports.isTag = void 0;
4
4
  const errors_1 = require("../errors");
5
5
  /**
6
6
  * Checks if the given node is TagLikeNode
@@ -49,11 +49,11 @@ exports.walk = walk;
49
49
  /**
50
50
  * Get end offset of start tag
51
51
  */
52
- function getStartTagEndOffset(node, ctx) {
52
+ function calcStartTagEndOffset(node, ctx) {
53
53
  const lastAttr = node.attributes[node.attributes.length - 1];
54
54
  let beforeCloseIndex;
55
55
  if (lastAttr) {
56
- beforeCloseIndex = getAttributeEndOffset(lastAttr, ctx);
56
+ beforeCloseIndex = calcAttributeEndOffset(lastAttr, ctx);
57
57
  }
58
58
  else {
59
59
  const info = getTokenInfo(ctx, [`<${node.name}`], node.position.start.offset);
@@ -62,63 +62,20 @@ function getStartTagEndOffset(node, ctx) {
62
62
  const info = getTokenInfo(ctx, [[">", "/>"]], beforeCloseIndex);
63
63
  return info.index + info.match.length;
64
64
  }
65
- exports.getStartTagEndOffset = getStartTagEndOffset;
66
- /**
67
- * Get end offset of tag
68
- */
69
- function getTagEndOffset(node, ctx) {
70
- var _a;
71
- if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
72
- return node.position.end.offset;
73
- }
74
- let beforeIndex;
75
- if (node.children.length) {
76
- const lastChild = node.children[node.children.length - 1];
77
- beforeIndex = getEndOffset(lastChild, ctx);
78
- }
79
- else {
80
- beforeIndex = getStartTagEndOffset(node, ctx);
81
- }
82
- beforeIndex = skipSpaces(ctx.code, beforeIndex);
83
- if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
84
- beforeIndex = beforeIndex + 2 + node.name.length;
85
- const info = getTokenInfo(ctx, [">"], beforeIndex);
86
- return info.index + info.match.length;
87
- }
88
- return beforeIndex;
89
- }
90
- exports.getTagEndOffset = getTagEndOffset;
91
- /**
92
- * Get end offset of Expression
93
- */
94
- function getExpressionEndOffset(node, ctx) {
95
- var _a;
96
- if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
97
- return node.position.end.offset;
98
- }
99
- if (node.children.length) {
100
- const lastChild = node.children[node.children.length - 1];
101
- const beforeIndex = getEndOffset(lastChild, ctx);
102
- const info = getTokenInfo(ctx, ["}"], beforeIndex);
103
- return info.index + info.match.length;
104
- }
105
- const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
106
- return info.index + info.match.length;
107
- }
108
- exports.getExpressionEndOffset = getExpressionEndOffset;
65
+ exports.calcStartTagEndOffset = calcStartTagEndOffset;
109
66
  /**
110
67
  * Get end offset of attribute
111
68
  */
112
- function getAttributeEndOffset(node, ctx) {
69
+ function calcAttributeEndOffset(node, ctx) {
113
70
  let info;
114
71
  if (node.kind === "empty") {
115
72
  info = getTokenInfo(ctx, [node.name], node.position.start.offset);
116
73
  }
117
74
  else if (node.kind === "quoted") {
118
- info = getTokenInfo(ctx, [[`"${node.value}"`, `'${node.value}'`, node.value]], getAttributeValueStartOffset(node, ctx));
75
+ info = getTokenInfo(ctx, [[`"${node.value}"`, `'${node.value}'`, node.value]], calcAttributeValueStartOffset(node, ctx));
119
76
  }
120
77
  else if (node.kind === "expression") {
121
- info = getTokenInfo(ctx, ["{", node.value, "}"], getAttributeValueStartOffset(node, ctx));
78
+ info = getTokenInfo(ctx, ["{", node.value, "}"], calcAttributeValueStartOffset(node, ctx));
122
79
  }
123
80
  else if (node.kind === "shorthand") {
124
81
  info = getTokenInfo(ctx, ["{", node.name, "}"], node.position.start.offset);
@@ -127,18 +84,18 @@ function getAttributeEndOffset(node, ctx) {
127
84
  info = getTokenInfo(ctx, ["{", "...", node.name, "}"], node.position.start.offset);
128
85
  }
129
86
  else if (node.kind === "template-literal") {
130
- info = getTokenInfo(ctx, [`\`${node.value}\``], getAttributeValueStartOffset(node, ctx));
87
+ info = getTokenInfo(ctx, [`\`${node.value}\``], calcAttributeValueStartOffset(node, ctx));
131
88
  }
132
89
  else {
133
90
  throw new errors_1.ParseError(`Unknown attr kind: ${node.kind}`, node.position.start.offset, ctx);
134
91
  }
135
92
  return info.index + info.match.length;
136
93
  }
137
- exports.getAttributeEndOffset = getAttributeEndOffset;
94
+ exports.calcAttributeEndOffset = calcAttributeEndOffset;
138
95
  /**
139
96
  * Get start offset of attribute value
140
97
  */
141
- function getAttributeValueStartOffset(node, ctx) {
98
+ function calcAttributeValueStartOffset(node, ctx) {
142
99
  let info;
143
100
  if (node.kind === "quoted") {
144
101
  info = getTokenInfo(ctx, [node.name, "=", [`"`, `'`, node.value]], node.position.start.offset);
@@ -154,22 +111,46 @@ function getAttributeValueStartOffset(node, ctx) {
154
111
  }
155
112
  return info.index;
156
113
  }
157
- exports.getAttributeValueStartOffset = getAttributeValueStartOffset;
114
+ exports.calcAttributeValueStartOffset = calcAttributeValueStartOffset;
158
115
  /**
159
- * Get end offset of comment
116
+ * Get end offset of tag
160
117
  */
161
- function getCommentEndOffset(node, ctx) {
162
- const info = getTokenInfo(ctx, ["<!--", node.value, "-->"], node.position.start.offset);
163
- return info.index + info.match.length;
118
+ function getEndOffset(node, ctx) {
119
+ var _a;
120
+ if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
121
+ return node.position.end.offset;
122
+ }
123
+ if (isTag(node))
124
+ return calcTagEndOffset(node, ctx);
125
+ if (node.type === "expression")
126
+ return calcExpressionEndOffset(node, ctx);
127
+ if (node.type === "comment")
128
+ return calcCommentEndOffset(node, ctx);
129
+ if (node.type === "frontmatter") {
130
+ const start = node.position.start.offset;
131
+ return ctx.code.indexOf("---", start + 3) + 3;
132
+ }
133
+ if (node.type === "doctype") {
134
+ const start = node.position.start.offset;
135
+ return ctx.code.indexOf(">", start) + 1;
136
+ }
137
+ if (node.type === "text") {
138
+ const start = node.position.start.offset;
139
+ return start + node.value.length;
140
+ }
141
+ if (node.type === "root") {
142
+ return ctx.code.length;
143
+ }
144
+ throw new Error(`unknown type: ${node.type}`);
164
145
  }
165
- exports.getCommentEndOffset = getCommentEndOffset;
146
+ exports.getEndOffset = getEndOffset;
166
147
  /**
167
148
  * Get content end offset
168
149
  */
169
- function getContentEndOffset(parent, ctx) {
150
+ function calcContentEndOffset(parent, ctx) {
170
151
  const code = ctx.code;
171
152
  if (isTag(parent)) {
172
- const end = getTagEndOffset(parent, ctx);
153
+ const end = getEndOffset(parent, ctx);
173
154
  if (code[end - 1] !== ">") {
174
155
  return end;
175
156
  }
@@ -181,7 +162,7 @@ function getContentEndOffset(parent, ctx) {
181
162
  return end;
182
163
  }
183
164
  else if (parent.type === "expression") {
184
- const end = getExpressionEndOffset(parent, ctx);
165
+ const end = getEndOffset(parent, ctx);
185
166
  return code.lastIndexOf("}", end);
186
167
  }
187
168
  else if (parent.type === "root") {
@@ -189,33 +170,28 @@ function getContentEndOffset(parent, ctx) {
189
170
  }
190
171
  throw new Error(`unknown type: ${parent.type}`);
191
172
  }
192
- exports.getContentEndOffset = getContentEndOffset;
173
+ exports.calcContentEndOffset = calcContentEndOffset;
193
174
  /**
194
175
  * If the given tag is a self-close tag, get the self-closing tag.
195
176
  */
196
- function getSelfClosingTag(node, parent, ctx) {
177
+ function getSelfClosingTag(node, ctx) {
197
178
  if (node.children.length > 0) {
198
179
  return null;
199
180
  }
200
181
  const code = ctx.code;
201
- let nextElementIndex = code.length;
202
- const childIndex = parent.children.indexOf(node);
203
- if (childIndex === parent.children.length - 1) {
204
- // last
205
- nextElementIndex = getContentEndOffset(parent, ctx);
206
- }
207
- else {
208
- const next = parent.children[childIndex + 1];
209
- nextElementIndex = next.position.start.offset;
182
+ const startTagEndOffset = calcStartTagEndOffset(node, ctx);
183
+ if (code.startsWith("/>", startTagEndOffset - 2)) {
184
+ return {
185
+ offset: startTagEndOffset,
186
+ end: "/>",
187
+ };
210
188
  }
211
- const endOffset = getStartTagEndOffset(node, ctx);
212
- if (code.slice(endOffset, nextElementIndex).trim()) {
213
- // has end tag
189
+ if (code.startsWith(`</${node.name}`, startTagEndOffset)) {
214
190
  return null;
215
191
  }
216
192
  return {
217
- offset: endOffset,
218
- end: code.slice(endOffset - 2, endOffset) === "/>" ? "/>" : ">",
193
+ offset: startTagEndOffset,
194
+ end: ">",
219
195
  };
220
196
  }
221
197
  exports.getSelfClosingTag = getSelfClosingTag;
@@ -229,7 +205,7 @@ function getEndTag(node, ctx) {
229
205
  beforeIndex = getEndOffset(lastChild, ctx);
230
206
  }
231
207
  else {
232
- beforeIndex = getStartTagEndOffset(node, ctx);
208
+ beforeIndex = calcStartTagEndOffset(node, ctx);
233
209
  }
234
210
  beforeIndex = skipSpaces(ctx.code, beforeIndex);
235
211
  if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
@@ -245,36 +221,46 @@ function getEndTag(node, ctx) {
245
221
  return null;
246
222
  }
247
223
  exports.getEndTag = getEndTag;
224
+ /**
225
+ * Get end offset of comment
226
+ */
227
+ function calcCommentEndOffset(node, ctx) {
228
+ const info = getTokenInfo(ctx, ["<!--", node.value, "-->"], node.position.start.offset);
229
+ return info.index + info.match.length;
230
+ }
231
+ exports.calcCommentEndOffset = calcCommentEndOffset;
248
232
  /**
249
233
  * Get end offset of tag
250
234
  */
251
- function getEndOffset(node, ctx) {
252
- var _a;
253
- if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
254
- return node.position.end.offset;
255
- }
256
- if (isTag(node))
257
- return getTagEndOffset(node, ctx);
258
- if (node.type === "expression")
259
- return getExpressionEndOffset(node, ctx);
260
- if (node.type === "comment")
261
- return getCommentEndOffset(node, ctx);
262
- if (node.type === "frontmatter") {
263
- const start = node.position.start.offset;
264
- return ctx.code.indexOf("---", start + 3) + 3;
235
+ function calcTagEndOffset(node, ctx) {
236
+ let beforeIndex;
237
+ if (node.children.length) {
238
+ const lastChild = node.children[node.children.length - 1];
239
+ beforeIndex = getEndOffset(lastChild, ctx);
265
240
  }
266
- if (node.type === "doctype") {
267
- const start = node.position.start.offset;
268
- return ctx.code.indexOf(">", start) + 1;
241
+ else {
242
+ beforeIndex = calcStartTagEndOffset(node, ctx);
269
243
  }
270
- if (node.type === "text") {
271
- const start = node.position.start.offset;
272
- return start + node.value.length;
244
+ beforeIndex = skipSpaces(ctx.code, beforeIndex);
245
+ if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
246
+ beforeIndex = beforeIndex + 2 + node.name.length;
247
+ const info = getTokenInfo(ctx, [">"], beforeIndex);
248
+ return info.index + info.match.length;
273
249
  }
274
- if (node.type === "root") {
275
- return ctx.code.length;
250
+ return beforeIndex;
251
+ }
252
+ /**
253
+ * Get end offset of Expression
254
+ */
255
+ function calcExpressionEndOffset(node, ctx) {
256
+ if (node.children.length) {
257
+ const lastChild = node.children[node.children.length - 1];
258
+ const beforeIndex = getEndOffset(lastChild, ctx);
259
+ const info = getTokenInfo(ctx, ["}"], beforeIndex);
260
+ return info.index + info.match.length;
276
261
  }
277
- throw new Error(`unknown type: ${node.type}`);
262
+ const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
263
+ return info.index + info.match.length;
278
264
  }
279
265
  /**
280
266
  * Get token info
@@ -1,6 +1,12 @@
1
1
  import type { Context } from ".";
2
2
  import type { ESLintExtendedProgram } from "../parser";
3
3
  import type { TSESTree } from "@typescript-eslint/types";
4
+ declare class RestoreNodeProcessContext {
5
+ readonly result: ESLintExtendedProgram;
6
+ readonly removeTokens: Set<(token: TSESTree.Token) => boolean>;
7
+ constructor(result: ESLintExtendedProgram);
8
+ addRemoveToken(test: (token: TSESTree.Token) => boolean): void;
9
+ }
4
10
  export declare class ScriptContext {
5
11
  private readonly ctx;
6
12
  script: string;
@@ -14,7 +20,7 @@ export declare class ScriptContext {
14
20
  appendOriginal(index: number): void;
15
21
  appendScript(fragment: string): void;
16
22
  addToken(type: TSESTree.Token["type"], range: TSESTree.Range): void;
17
- addRestoreNodeProcess(process: (node: TSESTree.Node, result: ESLintExtendedProgram, parent: TSESTree.Node) => boolean): void;
23
+ addRestoreNodeProcess(process: (node: TSESTree.Node, context: RestoreNodeProcessContext, parent: TSESTree.Node) => boolean): void;
18
24
  /**
19
25
  * Restore AST nodes
20
26
  */
@@ -22,3 +28,4 @@ export declare class ScriptContext {
22
28
  private remapLocation;
23
29
  private getRemapRange;
24
30
  }
31
+ export {};
@@ -3,6 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ScriptContext = void 0;
4
4
  const traverse_1 = require("../traverse");
5
5
  const errors_1 = require("../errors");
6
+ class RestoreNodeProcessContext {
7
+ constructor(result) {
8
+ this.removeTokens = new Set();
9
+ this.result = result;
10
+ }
11
+ addRemoveToken(test) {
12
+ this.removeTokens.add(test);
13
+ }
14
+ }
6
15
  class ScriptContext {
7
16
  constructor(ctx) {
8
17
  this.script = "";
@@ -38,6 +47,7 @@ class ScriptContext {
38
47
  /**
39
48
  * Restore AST nodes
40
49
  */
50
+ // eslint-disable-next-line complexity -- X(
41
51
  restore(result) {
42
52
  const last = result.ast.body[result.ast.body.length - 1];
43
53
  if (last.type !== "ExpressionStatement") {
@@ -77,11 +87,27 @@ class ScriptContext {
77
87
  for (const token of result.ast.comments || []) {
78
88
  this.remapLocation(token);
79
89
  }
90
+ const context = new RestoreNodeProcessContext(result);
80
91
  let restoreNodeProcesses = this.restoreNodeProcesses;
81
92
  for (const [node, parent] of traversed) {
82
93
  if (!parent)
83
94
  continue;
84
- restoreNodeProcesses = restoreNodeProcesses.filter((proc) => !proc(node, result, parent));
95
+ restoreNodeProcesses = restoreNodeProcesses.filter((proc) => !proc(node, context, parent));
96
+ }
97
+ if (context.removeTokens.size) {
98
+ const tokens = result.ast.tokens || [];
99
+ for (let index = tokens.length - 1; index >= 0; index--) {
100
+ const token = tokens[index];
101
+ for (const rt of context.removeTokens) {
102
+ if (rt(token)) {
103
+ tokens.splice(index, 1);
104
+ context.removeTokens.delete(rt);
105
+ if (!context.removeTokens.size) {
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
85
111
  }
86
112
  // Adjust program node location
87
113
  const first = result.ast.body[0];
@@ -140,16 +140,22 @@ function fixLocations(node, ctx) {
140
140
  start += 1;
141
141
  start += node.name.length;
142
142
  if (!node.attributes.length) {
143
- start = (0, astro_1.getStartTagEndOffset)(node, ctx);
143
+ start = (0, astro_1.calcStartTagEndOffset)(node, ctx);
144
144
  }
145
145
  }
146
146
  else if (node.type === "attribute") {
147
147
  fixLocationForAttr(node, ctx, start);
148
- start = (0, astro_1.getAttributeEndOffset)(node, ctx);
148
+ start = (0, astro_1.calcAttributeEndOffset)(node, ctx);
149
+ if (node.position.end) {
150
+ node.position.end.offset = start;
151
+ }
149
152
  }
150
153
  else if (node.type === "comment") {
151
154
  node.position.start.offset = tokenIndex(ctx, "<!--", start);
152
- start = (0, astro_1.getCommentEndOffset)(node, ctx);
155
+ start = (0, astro_1.calcCommentEndOffset)(node, ctx);
156
+ if (node.position.end) {
157
+ node.position.end.offset = start;
158
+ }
153
159
  }
154
160
  else if (node.type === "text") {
155
161
  if (parent.type === "element" &&
@@ -193,6 +199,9 @@ function fixLocations(node, ctx) {
193
199
  node.value = ctx.code.slice(node.position.start.offset, start);
194
200
  }
195
201
  }
202
+ if (node.position.end) {
203
+ node.position.end.offset = start;
204
+ }
196
205
  }
197
206
  else if (node.type === "expression") {
198
207
  start = node.position.start.offset = tokenIndex(ctx, "{", start);
@@ -217,7 +226,7 @@ function fixLocations(node, ctx) {
217
226
  if (node.type === "attribute") {
218
227
  const attributes = parent.attributes;
219
228
  if (attributes[attributes.length - 1] === node) {
220
- start = (0, astro_1.getStartTagEndOffset)(parent, ctx);
229
+ start = (0, astro_1.calcStartTagEndOffset)(parent, ctx);
221
230
  }
222
231
  }
223
232
  else if (node.type === "expression") {
@@ -227,7 +236,7 @@ function fixLocations(node, ctx) {
227
236
  node.type === "element" ||
228
237
  node.type === "component" ||
229
238
  node.type === "custom-element") {
230
- if (!(0, astro_1.getSelfClosingTag)(node, parent, ctx)) {
239
+ if (!(0, astro_1.getSelfClosingTag)(node, ctx)) {
231
240
  const closeTagStart = tokenIndexSafe(ctx.code, `</${node.name}`, start);
232
241
  if (closeTagStart != null) {
233
242
  start = closeTagStart + 2 + node.name.length;
@@ -24,12 +24,12 @@ function processTemplate(ctx, resultTemplate) {
24
24
  const start = node.position.start.offset;
25
25
  script.appendOriginal(start);
26
26
  script.skipOriginalOffset(3);
27
- const end = node.position.end.offset;
27
+ const end = (0, astro_1.getEndOffset)(node, ctx);
28
28
  script.appendOriginal(end - 3);
29
29
  script.appendScript(";<>");
30
30
  fragmentOpened = true;
31
31
  script.skipOriginalOffset(3);
32
- script.addRestoreNodeProcess((_scriptNode, result) => {
32
+ script.addRestoreNodeProcess((_scriptNode, { result }) => {
33
33
  for (let index = 0; index < result.ast.body.length; index++) {
34
34
  const st = result.ast.body[index];
35
35
  if (st.type === types_1.AST_NODE_TYPES.EmptyStatement) {
@@ -107,7 +107,7 @@ function processTemplate(ctx, resultTemplate) {
107
107
  start + colonIndex + 1,
108
108
  start + attr.name.length,
109
109
  ]);
110
- script.addRestoreNodeProcess((scriptNode, result) => {
110
+ script.addRestoreNodeProcess((scriptNode, context) => {
111
111
  if (scriptNode.type ===
112
112
  types_1.AST_NODE_TYPES.JSXAttribute &&
113
113
  scriptNode.range[0] === start) {
@@ -119,17 +119,10 @@ function processTemplate(ctx, resultTemplate) {
119
119
  scriptNode.name = nsn;
120
120
  nsn.namespace.parent = nsn;
121
121
  nsn.name.parent = nsn;
122
- const tokens = result.ast.tokens || [];
123
- for (let index = 0; index < tokens.length; index++) {
124
- const token = tokens[index];
125
- if (token.range[0] ===
126
- baseNameNode.range[0] &&
127
- token.range[1] ===
128
- baseNameNode.range[1]) {
129
- tokens.splice(index, 1);
130
- break;
131
- }
132
- }
122
+ context.addRemoveToken((token) => token.range[0] ===
123
+ baseNameNode.range[0] &&
124
+ token.range[1] ===
125
+ baseNameNode.range[1]);
133
126
  return true;
134
127
  }
135
128
  return false;
@@ -162,8 +155,8 @@ function processTemplate(ctx, resultTemplate) {
162
155
  }
163
156
  else if (attr.kind === "template-literal") {
164
157
  const attrStart = attr.position.start.offset;
165
- const start = (0, astro_1.getAttributeValueStartOffset)(attr, ctx);
166
- const end = (0, astro_1.getAttributeEndOffset)(attr, ctx);
158
+ const start = (0, astro_1.calcAttributeValueStartOffset)(attr, ctx);
159
+ const end = (0, astro_1.calcAttributeEndOffset)(attr, ctx);
167
160
  script.appendOriginal(start);
168
161
  script.appendScript("{");
169
162
  script.appendOriginal(end);
@@ -181,7 +174,7 @@ function processTemplate(ctx, resultTemplate) {
181
174
  }
182
175
  }
183
176
  // Process for start tag close
184
- const closing = (0, astro_1.getSelfClosingTag)(node, parent, ctx);
177
+ const closing = (0, astro_1.getSelfClosingTag)(node, ctx);
185
178
  if (closing && closing.end === ">") {
186
179
  script.appendOriginal(closing.offset - 1);
187
180
  script.appendScript("/");
@@ -214,7 +207,8 @@ function processTemplate(ctx, resultTemplate) {
214
207
  }
215
208
  else if (node.type === "comment") {
216
209
  const start = node.position.start.offset;
217
- const length = 4 + node.value.length + 3;
210
+ const end = (0, astro_1.getEndOffset)(node, ctx);
211
+ const length = end - start;
218
212
  script.appendOriginal(start);
219
213
  let targetType;
220
214
  if (fragmentOpened) {
@@ -228,7 +222,7 @@ function processTemplate(ctx, resultTemplate) {
228
222
  targetType = types_1.AST_NODE_TYPES.ExpressionStatement;
229
223
  script.skipOriginalOffset(length);
230
224
  }
231
- script.addRestoreNodeProcess((scriptNode, result) => {
225
+ script.addRestoreNodeProcess((scriptNode, context) => {
232
226
  if (scriptNode.range[0] === start &&
233
227
  scriptNode.type === targetType) {
234
228
  delete scriptNode.children;
@@ -238,26 +232,11 @@ function processTemplate(ctx, resultTemplate) {
238
232
  const commentNode = scriptNode;
239
233
  commentNode.type = "AstroHTMLComment";
240
234
  commentNode.value = node.value;
241
- if (fragmentOpened) {
242
- const removeTokenSet = new Set([
243
- (token) => token.value === "<" &&
244
- token.range[0] === scriptNode.range[0],
245
- (token) => token.value === ">" &&
246
- token.range[1] === scriptNode.range[1],
247
- ]);
248
- const tokens = result.ast.tokens || [];
249
- for (let index = tokens.length - 1; index >= 0; index--) {
250
- const token = tokens[index];
251
- for (const rt of removeTokenSet) {
252
- if (rt(token)) {
253
- tokens.splice(index, 1);
254
- removeTokenSet.delete(rt);
255
- if (!removeTokenSet.size) {
256
- break;
257
- }
258
- }
259
- }
260
- }
235
+ if (targetType === types_1.AST_NODE_TYPES.JSXFragment) {
236
+ context.addRemoveToken((token) => token.value === "<" &&
237
+ token.range[0] === scriptNode.range[0]);
238
+ context.addRemoveToken((token) => token.value === ">" &&
239
+ token.range[1] === scriptNode.range[1]);
261
240
  }
262
241
  return true;
263
242
  }
@@ -270,19 +249,22 @@ function processTemplate(ctx, resultTemplate) {
270
249
  }
271
250
  else if (node.type === "doctype") {
272
251
  const start = node.position.start.offset;
273
- const end = node.position.end.offset;
252
+ const end = (0, astro_1.getEndOffset)(node, ctx);
253
+ const length = end - start;
274
254
  script.appendOriginal(start);
275
255
  let targetType;
276
256
  if (fragmentOpened) {
277
- script.appendScript(`<></>`);
257
+ script.appendOriginal(start + 1);
258
+ script.appendScript(`></`);
259
+ script.skipOriginalOffset(length - 2);
278
260
  targetType = types_1.AST_NODE_TYPES.JSXFragment;
279
261
  }
280
262
  else {
281
263
  script.appendScript(`0;`);
282
264
  targetType = types_1.AST_NODE_TYPES.ExpressionStatement;
265
+ script.skipOriginalOffset(length);
283
266
  }
284
- script.skipOriginalOffset(end - start);
285
- script.addRestoreNodeProcess((scriptNode) => {
267
+ script.addRestoreNodeProcess((scriptNode, context) => {
286
268
  if (scriptNode.range[0] === start &&
287
269
  scriptNode.type === targetType) {
288
270
  delete scriptNode.children;
@@ -291,6 +273,12 @@ function processTemplate(ctx, resultTemplate) {
291
273
  delete scriptNode.expression;
292
274
  const doctypeNode = scriptNode;
293
275
  doctypeNode.type = "AstroDoctype";
276
+ if (targetType === types_1.AST_NODE_TYPES.JSXFragment) {
277
+ context.addRemoveToken((token) => token.value === "<" &&
278
+ token.range[0] === scriptNode.range[0]);
279
+ context.addRemoveToken((token) => token.value === ">" &&
280
+ token.range[1] === scriptNode.range[1]);
281
+ }
294
282
  return true;
295
283
  }
296
284
  return false;
@@ -299,11 +287,11 @@ function processTemplate(ctx, resultTemplate) {
299
287
  }
300
288
  }, (node, [parent]) => {
301
289
  if ((0, astro_1.isTag)(node)) {
302
- const closing = (0, astro_1.getSelfClosingTag)(node, parent, ctx);
290
+ const closing = (0, astro_1.getSelfClosingTag)(node, ctx);
303
291
  if (!closing) {
304
292
  const end = (0, astro_1.getEndTag)(node, ctx);
305
293
  if (!end) {
306
- const offset = (0, astro_1.getContentEndOffset)(node, ctx);
294
+ const offset = (0, astro_1.calcContentEndOffset)(node, ctx);
307
295
  script.appendOriginal(offset);
308
296
  script.appendScript(`</${node.name}>`);
309
297
  script.addRestoreNodeProcess((scriptNode, _result, parent) => {
@@ -328,9 +316,7 @@ function processTemplate(ctx, resultTemplate) {
328
316
  const before = parent.children[index - 1];
329
317
  if (before &&
330
318
  ((0, astro_1.isTag)(before) || before.type === "comment")) {
331
- const end = (0, astro_1.isTag)(node)
332
- ? (0, astro_1.getTagEndOffset)(node, ctx)
333
- : (0, astro_1.getCommentEndOffset)(node, ctx);
319
+ const end = (0, astro_1.getEndOffset)(node, ctx);
334
320
  script.appendOriginal(end);
335
321
  script.appendScript("</>");
336
322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-eslint-parser",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "Astro parser for ESLint",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -60,6 +60,7 @@
60
60
  "@types/semver": "^7.3.9",
61
61
  "@typescript-eslint/eslint-plugin": "^5.4.0",
62
62
  "@typescript-eslint/parser": "^5.4.0",
63
+ "astro-eslint-parser": ">=0.0.15",
63
64
  "benchmark": "^2.1.4",
64
65
  "chai": "^4.3.4",
65
66
  "code-red": "^0.2.3",