astro-eslint-parser 0.0.13 → 0.0.14

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.
@@ -9,9 +9,9 @@ export declare function isTag(node: Node): node is Node & TagLikeNode;
9
9
  */
10
10
  export declare function isParent(node: Node): node is ParentNode;
11
11
  /** walk element nodes */
12
- export declare function walkElements(parent: ParentNode, code: string, cb: (n: Node, parents: ParentNode[]) => void, parents?: ParentNode[]): void;
12
+ export declare function walkElements(parent: ParentNode, code: string, enter: (n: Node, parents: ParentNode[]) => void, leave: (n: Node, parents: ParentNode[]) => void, parents?: ParentNode[]): void;
13
13
  /** walk nodes */
14
- export declare function walk(parent: ParentNode, code: string, enter: (n: Node | AttributeNode, parents: ParentNode[]) => void, leave?: (n: Node | AttributeNode, parents: ParentNode[]) => void, parents?: ParentNode[]): void;
14
+ export declare function walk(parent: ParentNode, code: string, enter: (n: Node | AttributeNode, parents: ParentNode[]) => void, leave: (n: Node | AttributeNode, parents: ParentNode[]) => void): void;
15
15
  /**
16
16
  * Get end offset of start tag
17
17
  */
@@ -37,12 +37,23 @@ export declare function getAttributeValueStartOffset(node: AttributeNode, ctx: C
37
37
  */
38
38
  export declare function getCommentEndOffset(node: CommentNode, ctx: Context): number;
39
39
  /**
40
- * If the given tag is a void tag, get the self-closing tag.
40
+ * Get content end offset
41
+ */
42
+ export declare function getContentEndOffset(parent: ParentNode, parents: ParentNode[], ctx: Context): number;
43
+ /**
44
+ * If the given tag is a self-close tag, get the self-closing tag.
41
45
  */
42
46
  export declare function getSelfClosingTag(node: TagLikeNode, parents: ParentNode[], ctx: Context): null | {
43
47
  offset: number;
44
48
  end: "/>" | ">";
45
49
  };
50
+ /**
51
+ * If the given tag has a end tag, get the end tag.
52
+ */
53
+ export declare function getEndTag(node: TagLikeNode, parents: ParentNode[], ctx: Context): null | {
54
+ offset: number;
55
+ tag: string;
56
+ };
46
57
  /**
47
58
  * Skip spaces
48
59
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.skipSpaces = exports.getSelfClosingTag = 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.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;
4
4
  const errors_1 = require("../errors");
5
5
  /**
6
6
  * Checks if the given node is TagLikeNode
@@ -20,35 +20,30 @@ function isParent(node) {
20
20
  }
21
21
  exports.isParent = isParent;
22
22
  /** walk element nodes */
23
- function walkElements(parent, code, cb, parents = []) {
23
+ function walkElements(parent, code, enter, leave, parents = []) {
24
24
  const children = getSortedChildren(parent, code);
25
25
  const currParents = [parent, ...parents];
26
26
  for (const node of children) {
27
- cb(node, currParents);
27
+ enter(node, currParents);
28
28
  if (isParent(node)) {
29
- walkElements(node, code, cb, currParents);
29
+ walkElements(node, code, enter, leave, currParents);
30
30
  }
31
+ leave(node, currParents);
31
32
  }
32
33
  }
33
34
  exports.walkElements = walkElements;
34
35
  /** walk nodes */
35
- function walk(parent, code, enter, leave, parents = []) {
36
- const children = getSortedChildren(parent, code);
37
- const currParents = [parent, ...parents];
38
- for (const node of children) {
39
- enter(node, currParents);
36
+ function walk(parent, code, enter, leave) {
37
+ walkElements(parent, code, (node, parents) => {
38
+ enter(node, parents);
40
39
  if (isTag(node)) {
41
- const attrParents = [node, ...currParents];
40
+ const attrParents = [node, ...parents];
42
41
  for (const attr of node.attributes) {
43
42
  enter(attr, attrParents);
44
- leave === null || leave === void 0 ? void 0 : leave(attr, attrParents);
43
+ leave(attr, attrParents);
45
44
  }
46
45
  }
47
- if (isParent(node)) {
48
- walk(node, code, enter, leave, currParents);
49
- }
50
- leave === null || leave === void 0 ? void 0 : leave(node, currParents);
51
- }
46
+ }, leave);
52
47
  }
53
48
  exports.walk = walk;
54
49
  /**
@@ -76,36 +71,21 @@ function getTagEndOffset(node, parents, ctx) {
76
71
  if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
77
72
  return node.position.end.offset;
78
73
  }
74
+ let beforeIndex;
79
75
  if (node.children.length) {
80
- const code = ctx.code;
81
- let nextElementIndex = code.length;
82
- const parent = parents[0];
83
- const childIndex = parent.children.indexOf(node);
84
- if (childIndex === parent.children.length - 1) {
85
- // last
86
- if (isTag(parent)) {
87
- nextElementIndex = getTagEndOffset(parent, parents.slice(1), ctx);
88
- nextElementIndex = code.lastIndexOf("</", nextElementIndex);
89
- }
90
- else if (parent.type === "expression") {
91
- nextElementIndex = getExpressionEndOffset(parent, parents.slice(1), ctx);
92
- nextElementIndex = code.lastIndexOf("}", nextElementIndex);
93
- }
94
- }
95
- else {
96
- const next = parent.children[childIndex + 1];
97
- nextElementIndex = next.position.start.offset;
98
- }
99
- return code.lastIndexOf(">", nextElementIndex);
76
+ const lastChild = node.children[node.children.length - 1];
77
+ beforeIndex = getEndOffset(lastChild, [node, ...parents], ctx);
78
+ }
79
+ else {
80
+ beforeIndex = getStartTagEndOffset(node, ctx);
100
81
  }
101
- let beforeIndex = getStartTagEndOffset(node, ctx);
102
82
  beforeIndex = skipSpaces(ctx.code, beforeIndex);
103
83
  if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
104
84
  beforeIndex = beforeIndex + 2 + node.name.length;
105
85
  const info = getTokenInfo(ctx, [">"], beforeIndex);
106
86
  return info.index + info.match.length;
107
87
  }
108
- return ctx.code.length;
88
+ return beforeIndex;
109
89
  }
110
90
  exports.getTagEndOffset = getTagEndOffset;
111
91
  /**
@@ -117,26 +97,10 @@ function getExpressionEndOffset(node, parents, ctx) {
117
97
  return node.position.end.offset;
118
98
  }
119
99
  if (node.children.length) {
120
- const code = ctx.code;
121
- let nextElementIndex = code.length;
122
- const parent = parents[0];
123
- const childIndex = parent.children.indexOf(node);
124
- if (childIndex === parent.children.length - 1) {
125
- // last
126
- if (isTag(parent)) {
127
- nextElementIndex = getTagEndOffset(parent, parents.slice(1), ctx);
128
- nextElementIndex = code.lastIndexOf("</", nextElementIndex);
129
- }
130
- else if (parent.type === "expression") {
131
- nextElementIndex = getExpressionEndOffset(parent, parents.slice(1), ctx);
132
- nextElementIndex = code.lastIndexOf("}", nextElementIndex);
133
- }
134
- }
135
- else {
136
- const next = parent.children[childIndex + 1];
137
- nextElementIndex = next.position.start.offset;
138
- }
139
- return code.lastIndexOf("}", nextElementIndex);
100
+ const lastChild = node.children[node.children.length - 1];
101
+ const beforeIndex = getEndOffset(lastChild, [node, ...parents], ctx);
102
+ const info = getTokenInfo(ctx, ["}"], beforeIndex);
103
+ return info.index + info.match.length;
140
104
  }
141
105
  const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
142
106
  return info.index + info.match.length;
@@ -200,7 +164,33 @@ function getCommentEndOffset(node, ctx) {
200
164
  }
201
165
  exports.getCommentEndOffset = getCommentEndOffset;
202
166
  /**
203
- * If the given tag is a void tag, get the self-closing tag.
167
+ * Get content end offset
168
+ */
169
+ function getContentEndOffset(parent, parents, ctx) {
170
+ const code = ctx.code;
171
+ if (isTag(parent)) {
172
+ const end = getTagEndOffset(parent, parents, ctx);
173
+ if (code[end - 1] !== ">") {
174
+ return end;
175
+ }
176
+ const index = code.lastIndexOf("</", end);
177
+ if (index >= 0 && code.slice(index, end).trim() === parent.name) {
178
+ return index;
179
+ }
180
+ return end;
181
+ }
182
+ else if (parent.type === "expression") {
183
+ const end = getExpressionEndOffset(parent, parents, ctx);
184
+ return code.lastIndexOf("}", end);
185
+ }
186
+ else if (parent.type === "root") {
187
+ return code.length;
188
+ }
189
+ throw new Error(`unknown type: ${parent.type}`);
190
+ }
191
+ exports.getContentEndOffset = getContentEndOffset;
192
+ /**
193
+ * If the given tag is a self-close tag, get the self-closing tag.
204
194
  */
205
195
  function getSelfClosingTag(node, parents, ctx) {
206
196
  const children = node.children.filter((c) => c.type !== "text" || c.value.trim());
@@ -213,14 +203,7 @@ function getSelfClosingTag(node, parents, ctx) {
213
203
  const childIndex = parent.children.indexOf(node);
214
204
  if (childIndex === parent.children.length - 1) {
215
205
  // last
216
- if (isTag(parent)) {
217
- nextElementIndex = getTagEndOffset(parent, parents.slice(1), ctx);
218
- nextElementIndex = code.lastIndexOf("</", nextElementIndex);
219
- }
220
- else if (parent.type === "expression") {
221
- nextElementIndex = getExpressionEndOffset(parent, parents.slice(1), ctx);
222
- nextElementIndex = code.lastIndexOf("}", nextElementIndex);
223
- }
206
+ nextElementIndex = getContentEndOffset(parent, parents.slice(1), ctx);
224
207
  }
225
208
  else {
226
209
  const next = parent.children[childIndex + 1];
@@ -237,6 +220,63 @@ function getSelfClosingTag(node, parents, ctx) {
237
220
  };
238
221
  }
239
222
  exports.getSelfClosingTag = getSelfClosingTag;
223
+ /**
224
+ * If the given tag has a end tag, get the end tag.
225
+ */
226
+ function getEndTag(node, parents, ctx) {
227
+ let beforeIndex;
228
+ if (node.children.length) {
229
+ const lastChild = node.children[node.children.length - 1];
230
+ beforeIndex = getEndOffset(lastChild, [node, ...parents], ctx);
231
+ }
232
+ else {
233
+ beforeIndex = getStartTagEndOffset(node, ctx);
234
+ }
235
+ beforeIndex = skipSpaces(ctx.code, beforeIndex);
236
+ if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
237
+ const offset = beforeIndex;
238
+ beforeIndex = beforeIndex + 2 + node.name.length;
239
+ const info = getTokenInfo(ctx, [">"], beforeIndex);
240
+ const end = info.index + info.match.length;
241
+ return {
242
+ offset,
243
+ tag: ctx.code.slice(offset, end),
244
+ };
245
+ }
246
+ return null;
247
+ }
248
+ exports.getEndTag = getEndTag;
249
+ /**
250
+ * Get end offset of tag
251
+ */
252
+ function getEndOffset(node, parents, ctx) {
253
+ var _a;
254
+ if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
255
+ return node.position.end.offset;
256
+ }
257
+ if (isTag(node))
258
+ return getTagEndOffset(node, parents, ctx);
259
+ if (node.type === "expression")
260
+ return getExpressionEndOffset(node, parents, ctx);
261
+ if (node.type === "comment")
262
+ return getCommentEndOffset(node, ctx);
263
+ if (node.type === "frontmatter") {
264
+ const start = node.position.start.offset;
265
+ return ctx.code.indexOf("---", start + 3) + 3;
266
+ }
267
+ if (node.type === "doctype") {
268
+ const start = node.position.start.offset;
269
+ return ctx.code.indexOf(">", start) + 1;
270
+ }
271
+ if (node.type === "text") {
272
+ const start = node.position.start.offset;
273
+ return start + node.value.length;
274
+ }
275
+ if (node.type === "root") {
276
+ return ctx.code.length;
277
+ }
278
+ throw new Error(`unknown type: ${node.type}`);
279
+ }
240
280
  /**
241
281
  * Get token info
242
282
  */
@@ -9,7 +9,7 @@ export declare class Context {
9
9
  readonly parserOptions: any;
10
10
  readonly locs: LinesAndColumns;
11
11
  private readonly locsMap;
12
- private state;
12
+ private readonly state;
13
13
  constructor(code: string, parserOptions: any);
14
14
  getLocFromIndex(index: number): {
15
15
  line: number;
@@ -29,6 +29,8 @@ export declare class Context {
29
29
  getText(range: TSESTree.Range): string;
30
30
  isTypeScript(): boolean;
31
31
  remapCR({ ast, visitorKeys }: ESLintExtendedProgram): void;
32
+ get originalAST(): any;
33
+ set originalAST(originalAST: any);
32
34
  }
33
35
  export declare class LinesAndColumns {
34
36
  readonly code: string;
@@ -129,6 +129,12 @@ class Context {
129
129
  comment.range = remapRange(comment.range);
130
130
  }
131
131
  }
132
+ get originalAST() {
133
+ return this.state.originalAST;
134
+ }
135
+ set originalAST(originalAST) {
136
+ this.state.originalAST = originalAST;
137
+ }
132
138
  }
133
139
  exports.Context = Context;
134
140
  class LinesAndColumns {
@@ -14,7 +14,7 @@ export declare class ScriptContext {
14
14
  appendOriginal(index: number): void;
15
15
  appendScript(fragment: string): void;
16
16
  addToken(type: TSESTree.Token["type"], range: TSESTree.Range): void;
17
- addRestoreNodeProcess(process: (node: TSESTree.Node, result: ESLintExtendedProgram) => boolean): void;
17
+ addRestoreNodeProcess(process: (node: TSESTree.Node, result: ESLintExtendedProgram, parent: TSESTree.Node) => boolean): void;
18
18
  /**
19
19
  * Restore AST nodes
20
20
  */
@@ -52,12 +52,12 @@ class ScriptContext {
52
52
  delete rootFragment.openingFragment;
53
53
  rootFragment.type = "AstroRootFragment";
54
54
  // remap locations
55
- const traversed = new Set();
55
+ const traversed = new Map();
56
56
  (0, traverse_1.traverseNodes)(result.ast, {
57
57
  visitorKeys: result.visitorKeys,
58
- enterNode: (node) => {
58
+ enterNode: (node, p) => {
59
59
  if (!traversed.has(node)) {
60
- traversed.add(node);
60
+ traversed.set(node, p);
61
61
  this.remapLocation(node);
62
62
  }
63
63
  },
@@ -78,8 +78,10 @@ class ScriptContext {
78
78
  this.remapLocation(token);
79
79
  }
80
80
  let restoreNodeProcesses = this.restoreNodeProcesses;
81
- for (const node of traversed) {
82
- restoreNodeProcesses = restoreNodeProcesses.filter((proc) => !proc(node, result));
81
+ for (const [node, parent] of traversed) {
82
+ if (!parent)
83
+ continue;
84
+ restoreNodeProcesses = restoreNodeProcesses.filter((proc) => !proc(node, result, parent));
83
85
  }
84
86
  // Adjust program node location
85
87
  const first = result.ast.body[0];
package/lib/errors.d.ts CHANGED
@@ -6,6 +6,7 @@ export declare class ParseError extends SyntaxError {
6
6
  index: number;
7
7
  lineNumber: number;
8
8
  column: number;
9
+ originalAST: any;
9
10
  /**
10
11
  * Initialize this ParseError instance.
11
12
  */
package/lib/errors.js CHANGED
@@ -14,6 +14,7 @@ class ParseError extends SyntaxError {
14
14
  const loc = ctx.getLocFromIndex(offset);
15
15
  this.lineNumber = loc.line;
16
16
  this.column = loc.column;
17
+ this.originalAST = ctx.originalAST;
17
18
  }
18
19
  }
19
20
  exports.ParseError = ParseError;
@@ -31,7 +31,7 @@ const errors_1 = require("../../errors");
31
31
  * Parse code by `@astrojs/compiler`
32
32
  */
33
33
  function parse(code, ctx) {
34
- const ast = parseByService(code).ast;
34
+ const ast = parseByService(code, ctx).ast;
35
35
  const htmlElement = ast.children.find((n) => n.type === "element" && n.name === "html");
36
36
  if (htmlElement) {
37
37
  adjustHTML(ast, htmlElement, ctx);
@@ -43,10 +43,12 @@ exports.parse = parse;
43
43
  /**
44
44
  * Parse code by `@astrojs/compiler`
45
45
  */
46
- function parseByService(code) {
46
+ function parseByService(code, ctx) {
47
47
  const jsonAst = service.parse(code, { position: true }).ast;
48
+ ctx.originalAST = jsonAst;
48
49
  try {
49
50
  const ast = JSON.parse(jsonAst);
51
+ ctx.originalAST = ast;
50
52
  return { ast };
51
53
  }
52
54
  catch (_a) {
@@ -61,6 +63,7 @@ function parseByService(code) {
61
63
  return `\\${m}`;
62
64
  }
63
65
  }));
66
+ ctx.originalAST = ast;
64
67
  return { ast };
65
68
  }
66
69
  }
@@ -17,37 +17,9 @@ function processTemplate(ctx, resultTemplate) {
17
17
  script.appendScript("<>");
18
18
  fragmentOpened = true;
19
19
  }
20
+ (0, astro_1.walkElements)(resultTemplate.ast, ctx.code,
20
21
  // eslint-disable-next-line complexity -- X(
21
- (0, astro_1.walkElements)(resultTemplate.ast, ctx.code, (node, parents) => {
22
- const parent = parents[0];
23
- if ((0, astro_1.isTag)(node) && parent.type === "expression") {
24
- const index = parent.children.indexOf(node);
25
- const before = parent.children[index - 1];
26
- if (!before || !(0, astro_1.isTag)(before)) {
27
- const after = parent.children[index + 1];
28
- if (after && ((0, astro_1.isTag)(after) || after.type === "comment")) {
29
- const start = node.position.start.offset;
30
- script.appendOriginal(start);
31
- script.appendScript("<>");
32
- script.addRestoreNodeProcess((scriptNode) => {
33
- if (scriptNode.range[0] === start &&
34
- scriptNode.type === types_1.AST_NODE_TYPES.JSXFragment) {
35
- delete scriptNode.openingFragment;
36
- delete scriptNode.closingFragment;
37
- const fragmentNode = scriptNode;
38
- fragmentNode.type = "AstroFragment";
39
- const last = fragmentNode.children[fragmentNode.children.length - 1];
40
- if (fragmentNode.range[1] < last.range[1]) {
41
- fragmentNode.range[1] = last.range[1];
42
- fragmentNode.loc.end = ctx.getLocFromIndex(fragmentNode.range[1]);
43
- }
44
- return true;
45
- }
46
- return false;
47
- });
48
- }
49
- }
50
- }
22
+ (node, parents) => {
51
23
  if (node.type === "frontmatter") {
52
24
  const start = node.position.start.offset;
53
25
  script.appendOriginal(start);
@@ -61,7 +33,8 @@ function processTemplate(ctx, resultTemplate) {
61
33
  for (let index = 0; index < result.ast.body.length; index++) {
62
34
  const st = result.ast.body[index];
63
35
  if (st.type === types_1.AST_NODE_TYPES.EmptyStatement) {
64
- if (st.range[0] === end - 3 && st.range[1] === end) {
36
+ if (st.range[0] === end - 3 &&
37
+ st.range[1] === end) {
65
38
  result.ast.body.splice(index, 1);
66
39
  break;
67
40
  }
@@ -76,8 +49,43 @@ function processTemplate(ctx, resultTemplate) {
76
49
  script.addToken(types_1.AST_TOKEN_TYPES.Punctuator, [end - 3, end]);
77
50
  }
78
51
  else if ((0, astro_1.isTag)(node)) {
52
+ // Process for multiple tag
53
+ const parent = parents[0];
54
+ if (parent.type === "expression") {
55
+ const index = parent.children.indexOf(node);
56
+ const before = parent.children[index - 1];
57
+ if (!before || !(0, astro_1.isTag)(before)) {
58
+ const after = parent.children[index + 1];
59
+ if (after &&
60
+ ((0, astro_1.isTag)(after) || after.type === "comment")) {
61
+ const start = node.position.start.offset;
62
+ script.appendOriginal(start);
63
+ script.appendScript("<>");
64
+ script.addRestoreNodeProcess((scriptNode) => {
65
+ if (scriptNode.range[0] === start &&
66
+ scriptNode.type ===
67
+ types_1.AST_NODE_TYPES.JSXFragment) {
68
+ delete scriptNode.openingFragment;
69
+ delete scriptNode.closingFragment;
70
+ const fragmentNode = scriptNode;
71
+ fragmentNode.type = "AstroFragment";
72
+ const last = fragmentNode.children[fragmentNode.children.length - 1];
73
+ if (fragmentNode.range[1] < last.range[1]) {
74
+ fragmentNode.range[1] = last.range[1];
75
+ fragmentNode.loc.end =
76
+ ctx.getLocFromIndex(fragmentNode.range[1]);
77
+ }
78
+ return true;
79
+ }
80
+ return false;
81
+ });
82
+ }
83
+ }
84
+ }
85
+ // Process for attributes
79
86
  for (const attr of node.attributes) {
80
- if ((node.type === "component" || node.type === "fragment") &&
87
+ if ((node.type === "component" ||
88
+ node.type === "fragment") &&
81
89
  (attr.kind === "quoted" ||
82
90
  attr.kind === "empty" ||
83
91
  attr.kind === "expression" ||
@@ -105,7 +113,8 @@ function processTemplate(ctx, resultTemplate) {
105
113
  types_1.AST_NODE_TYPES.JSXAttribute &&
106
114
  scriptNode.range[0] === start) {
107
115
  const baseNameNode = scriptNode.name;
108
- const nsn = Object.assign(Object.assign({}, baseNameNode), { type: types_1.AST_NODE_TYPES.JSXNamespacedName, namespace: Object.assign({ type: types_1.AST_NODE_TYPES.JSXIdentifier, name: attr.name.slice(0, colonIndex) }, ctx.getLocations(baseNameNode.range[0], baseNameNode.range[0] + colonIndex)), name: Object.assign({ type: types_1.AST_NODE_TYPES.JSXIdentifier, name: attr.name.slice(colonIndex + 1) }, ctx.getLocations(baseNameNode.range[0] +
116
+ const nsn = Object.assign(Object.assign({}, baseNameNode), { type: types_1.AST_NODE_TYPES.JSXNamespacedName, namespace: Object.assign({ type: types_1.AST_NODE_TYPES.JSXIdentifier, name: attr.name.slice(0, colonIndex) }, ctx.getLocations(baseNameNode.range[0], baseNameNode.range[0] +
117
+ colonIndex)), name: Object.assign({ type: types_1.AST_NODE_TYPES.JSXIdentifier, name: attr.name.slice(colonIndex + 1) }, ctx.getLocations(baseNameNode.range[0] +
109
118
  colonIndex +
110
119
  1, baseNameNode.range[1])) });
111
120
  scriptNode.name = nsn;
@@ -116,7 +125,8 @@ function processTemplate(ctx, resultTemplate) {
116
125
  const token = tokens[index];
117
126
  if (token.range[0] ===
118
127
  baseNameNode.range[0] &&
119
- token.range[1] === baseNameNode.range[1]) {
128
+ token.range[1] ===
129
+ baseNameNode.range[1]) {
120
130
  tokens.splice(index, 1);
121
131
  break;
122
132
  }
@@ -135,7 +145,8 @@ function processTemplate(ctx, resultTemplate) {
135
145
  : attr.name;
136
146
  script.appendScript(`${jsxName}=`);
137
147
  script.addRestoreNodeProcess((scriptNode) => {
138
- if (scriptNode.type === types_1.AST_NODE_TYPES.JSXAttribute &&
148
+ if (scriptNode.type ===
149
+ types_1.AST_NODE_TYPES.JSXAttribute &&
139
150
  scriptNode.range[0] === start) {
140
151
  const attrNode = scriptNode;
141
152
  attrNode.type = "AstroShorthandAttribute";
@@ -159,7 +170,8 @@ function processTemplate(ctx, resultTemplate) {
159
170
  script.appendOriginal(end);
160
171
  script.appendScript("}");
161
172
  script.addRestoreNodeProcess((scriptNode) => {
162
- if (scriptNode.type === types_1.AST_NODE_TYPES.JSXAttribute &&
173
+ if (scriptNode.type ===
174
+ types_1.AST_NODE_TYPES.JSXAttribute &&
163
175
  scriptNode.range[0] === attrStart) {
164
176
  const attrNode = scriptNode;
165
177
  attrNode.type = "AstroTemplateLiteralAttribute";
@@ -169,11 +181,13 @@ function processTemplate(ctx, resultTemplate) {
169
181
  });
170
182
  }
171
183
  }
172
- const end = (0, astro_1.getSelfClosingTag)(node, parents, ctx);
173
- if (end && end.end === ">") {
174
- script.appendOriginal(end.offset - 1);
184
+ // Process for start tag close
185
+ const closing = (0, astro_1.getSelfClosingTag)(node, parents, ctx);
186
+ if (closing && closing.end === ">") {
187
+ script.appendOriginal(closing.offset - 1);
175
188
  script.appendScript("/");
176
189
  }
190
+ // Process for raw text
177
191
  if (node.name === "script" || node.name === "style") {
178
192
  const text = node.children[0];
179
193
  if (text && text.type === "text") {
@@ -284,13 +298,38 @@ function processTemplate(ctx, resultTemplate) {
284
298
  });
285
299
  script.addToken("HTMLDocType", [start, end]);
286
300
  }
301
+ }, (node, parents) => {
302
+ if ((0, astro_1.isTag)(node)) {
303
+ const closing = (0, astro_1.getSelfClosingTag)(node, parents, ctx);
304
+ if (!closing) {
305
+ const end = (0, astro_1.getEndTag)(node, parents, ctx);
306
+ if (!end) {
307
+ const offset = (0, astro_1.getContentEndOffset)(node, parents, ctx);
308
+ script.appendOriginal(offset);
309
+ script.appendScript(`</${node.name}>`);
310
+ script.addRestoreNodeProcess((scriptNode, _result, parent) => {
311
+ if (scriptNode.range[0] === offset &&
312
+ scriptNode.type ===
313
+ types_1.AST_NODE_TYPES.JSXClosingElement &&
314
+ parent.type === types_1.AST_NODE_TYPES.JSXElement) {
315
+ parent.closingElement = null;
316
+ return true;
317
+ }
318
+ return false;
319
+ });
320
+ }
321
+ }
322
+ }
323
+ // Process for multiple tag
324
+ const parent = parents[0];
287
325
  if (((0, astro_1.isTag)(node) || node.type === "comment") &&
288
326
  parent.type === "expression") {
289
327
  const index = parent.children.indexOf(node);
290
328
  const after = parent.children[index + 1];
291
329
  if (!after || (!(0, astro_1.isTag)(after) && after.type !== "comment")) {
292
330
  const before = parent.children[index - 1];
293
- if (before && ((0, astro_1.isTag)(before) || before.type === "comment")) {
331
+ if (before &&
332
+ ((0, astro_1.isTag)(before) || before.type === "comment")) {
294
333
  const end = (0, astro_1.isTag)(node)
295
334
  ? (0, astro_1.getTagEndOffset)(node, parents, ctx)
296
335
  : (0, astro_1.getCommentEndOffset)(node, ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-eslint-parser",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "Astro parser for ESLint",
5
5
  "main": "lib/index.js",
6
6
  "files": [