astro-eslint-parser 0.0.10 → 0.0.13
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/ast.d.ts +7 -1
- package/lib/astro/index.d.ts +18 -3
- package/lib/astro/index.js +125 -10
- package/lib/parser/astro-parser/parse.js +47 -5
- package/lib/parser/process-template.js +72 -38
- package/lib/visitor-keys.js +1 -0
- package/package.json +2 -1
package/lib/ast.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TSESTree } from "@typescript-eslint/types";
|
|
2
|
-
export declare type AstroNode = AstroProgram | AstroRootFragment | AstroHTMLComment | AstroDoctype | AstroShorthandAttribute | AstroTemplateLiteralAttribute | AstroRawText;
|
|
2
|
+
export declare type AstroNode = AstroProgram | AstroRootFragment | AstroHTMLComment | AstroDoctype | AstroShorthandAttribute | AstroTemplateLiteralAttribute | AstroRawText | AstroFragment;
|
|
3
3
|
/** Node of Astro program root */
|
|
4
4
|
export interface AstroProgram extends Omit<TSESTree.Program, "type" | "body"> {
|
|
5
5
|
type: "Program";
|
|
@@ -45,3 +45,9 @@ export interface AstroRawText extends Omit<TSESTree.JSXText, "type" | "parent">
|
|
|
45
45
|
type: "AstroRawText";
|
|
46
46
|
parent: AstroRootFragment | TSESTree.JSXElement | TSESTree.JSXFragment;
|
|
47
47
|
}
|
|
48
|
+
/** Node of Astro fragment expression */
|
|
49
|
+
export interface AstroFragment extends Omit<TSESTree.BaseNode, "type" | "parent"> {
|
|
50
|
+
type: "AstroFragment";
|
|
51
|
+
children: TSESTree.JSXFragment["children"];
|
|
52
|
+
parent: TSESTree.JSXFragment["parent"];
|
|
53
|
+
}
|
package/lib/astro/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AttributeNode, CommentNode, Node, ParentNode, TagLikeNode } from "@astrojs/compiler/types";
|
|
1
|
+
import type { AttributeNode, CommentNode, ExpressionNode, 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
|
|
@@ -9,13 +9,21 @@ 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,
|
|
12
|
+
export declare function walkElements(parent: ParentNode, code: string, cb: (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,
|
|
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;
|
|
15
15
|
/**
|
|
16
16
|
* Get end offset of start tag
|
|
17
17
|
*/
|
|
18
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, parents: ParentNode[], ctx: Context): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get end offset of Expression
|
|
25
|
+
*/
|
|
26
|
+
export declare function getExpressionEndOffset(node: ExpressionNode, parents: ParentNode[], ctx: Context): number;
|
|
19
27
|
/**
|
|
20
28
|
* Get end offset of attribute
|
|
21
29
|
*/
|
|
@@ -28,6 +36,13 @@ export declare function getAttributeValueStartOffset(node: AttributeNode, ctx: C
|
|
|
28
36
|
* Get end offset of comment
|
|
29
37
|
*/
|
|
30
38
|
export declare function getCommentEndOffset(node: CommentNode, ctx: Context): number;
|
|
39
|
+
/**
|
|
40
|
+
* If the given tag is a void tag, get the self-closing tag.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getSelfClosingTag(node: TagLikeNode, parents: ParentNode[], ctx: Context): null | {
|
|
43
|
+
offset: number;
|
|
44
|
+
end: "/>" | ">";
|
|
45
|
+
};
|
|
31
46
|
/**
|
|
32
47
|
* Skip spaces
|
|
33
48
|
*/
|
package/lib/astro/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.skipSpaces = exports.getCommentEndOffset = exports.getAttributeValueStartOffset = exports.getAttributeEndOffset = exports.getStartTagEndOffset = exports.walk = exports.walkElements = exports.isParent = exports.isTag = void 0;
|
|
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;
|
|
4
4
|
const errors_1 = require("../errors");
|
|
5
5
|
/**
|
|
6
6
|
* Checks if the given node is TagLikeNode
|
|
@@ -20,31 +20,34 @@ function isParent(node) {
|
|
|
20
20
|
}
|
|
21
21
|
exports.isParent = isParent;
|
|
22
22
|
/** walk element nodes */
|
|
23
|
-
function walkElements(parent, code, cb) {
|
|
23
|
+
function walkElements(parent, code, cb, parents = []) {
|
|
24
24
|
const children = getSortedChildren(parent, code);
|
|
25
|
+
const currParents = [parent, ...parents];
|
|
25
26
|
for (const node of children) {
|
|
26
|
-
cb(node,
|
|
27
|
+
cb(node, currParents);
|
|
27
28
|
if (isParent(node)) {
|
|
28
|
-
walkElements(node, code, cb);
|
|
29
|
+
walkElements(node, code, cb, currParents);
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
exports.walkElements = walkElements;
|
|
33
34
|
/** walk nodes */
|
|
34
|
-
function walk(parent, code, enter, leave) {
|
|
35
|
+
function walk(parent, code, enter, leave, parents = []) {
|
|
35
36
|
const children = getSortedChildren(parent, code);
|
|
37
|
+
const currParents = [parent, ...parents];
|
|
36
38
|
for (const node of children) {
|
|
37
|
-
enter(node,
|
|
39
|
+
enter(node, currParents);
|
|
38
40
|
if (isTag(node)) {
|
|
41
|
+
const attrParents = [node, ...currParents];
|
|
39
42
|
for (const attr of node.attributes) {
|
|
40
|
-
enter(attr,
|
|
41
|
-
leave === null || leave === void 0 ? void 0 : leave(attr,
|
|
43
|
+
enter(attr, attrParents);
|
|
44
|
+
leave === null || leave === void 0 ? void 0 : leave(attr, attrParents);
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
if (isParent(node)) {
|
|
45
|
-
walk(node, code, enter, leave);
|
|
48
|
+
walk(node, code, enter, leave, currParents);
|
|
46
49
|
}
|
|
47
|
-
leave === null || leave === void 0 ? void 0 : leave(node,
|
|
50
|
+
leave === null || leave === void 0 ? void 0 : leave(node, currParents);
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
exports.walk = walk;
|
|
@@ -65,6 +68,80 @@ function getStartTagEndOffset(node, ctx) {
|
|
|
65
68
|
return info.index + info.match.length;
|
|
66
69
|
}
|
|
67
70
|
exports.getStartTagEndOffset = getStartTagEndOffset;
|
|
71
|
+
/**
|
|
72
|
+
* Get end offset of tag
|
|
73
|
+
*/
|
|
74
|
+
function getTagEndOffset(node, parents, ctx) {
|
|
75
|
+
var _a;
|
|
76
|
+
if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
|
|
77
|
+
return node.position.end.offset;
|
|
78
|
+
}
|
|
79
|
+
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);
|
|
100
|
+
}
|
|
101
|
+
let beforeIndex = getStartTagEndOffset(node, ctx);
|
|
102
|
+
beforeIndex = skipSpaces(ctx.code, beforeIndex);
|
|
103
|
+
if (ctx.code.startsWith(`</${node.name}`, beforeIndex)) {
|
|
104
|
+
beforeIndex = beforeIndex + 2 + node.name.length;
|
|
105
|
+
const info = getTokenInfo(ctx, [">"], beforeIndex);
|
|
106
|
+
return info.index + info.match.length;
|
|
107
|
+
}
|
|
108
|
+
return ctx.code.length;
|
|
109
|
+
}
|
|
110
|
+
exports.getTagEndOffset = getTagEndOffset;
|
|
111
|
+
/**
|
|
112
|
+
* Get end offset of Expression
|
|
113
|
+
*/
|
|
114
|
+
function getExpressionEndOffset(node, parents, ctx) {
|
|
115
|
+
var _a;
|
|
116
|
+
if (((_a = node.position.end) === null || _a === void 0 ? void 0 : _a.offset) != null) {
|
|
117
|
+
return node.position.end.offset;
|
|
118
|
+
}
|
|
119
|
+
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);
|
|
140
|
+
}
|
|
141
|
+
const info = getTokenInfo(ctx, ["{", "}"], node.position.start.offset);
|
|
142
|
+
return info.index + info.match.length;
|
|
143
|
+
}
|
|
144
|
+
exports.getExpressionEndOffset = getExpressionEndOffset;
|
|
68
145
|
/**
|
|
69
146
|
* Get end offset of attribute
|
|
70
147
|
*/
|
|
@@ -122,6 +199,44 @@ function getCommentEndOffset(node, ctx) {
|
|
|
122
199
|
return info.index + info.match.length;
|
|
123
200
|
}
|
|
124
201
|
exports.getCommentEndOffset = getCommentEndOffset;
|
|
202
|
+
/**
|
|
203
|
+
* If the given tag is a void tag, get the self-closing tag.
|
|
204
|
+
*/
|
|
205
|
+
function getSelfClosingTag(node, parents, ctx) {
|
|
206
|
+
const children = node.children.filter((c) => c.type !== "text" || c.value.trim());
|
|
207
|
+
if (children.length > 0) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
const parent = parents[0];
|
|
211
|
+
const code = ctx.code;
|
|
212
|
+
let nextElementIndex = code.length;
|
|
213
|
+
const childIndex = parent.children.indexOf(node);
|
|
214
|
+
if (childIndex === parent.children.length - 1) {
|
|
215
|
+
// 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
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const next = parent.children[childIndex + 1];
|
|
227
|
+
nextElementIndex = next.position.start.offset;
|
|
228
|
+
}
|
|
229
|
+
const endOffset = getStartTagEndOffset(node, ctx);
|
|
230
|
+
if (code.slice(endOffset, nextElementIndex).trim()) {
|
|
231
|
+
// has end tag
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
offset: endOffset,
|
|
236
|
+
end: code.slice(endOffset - 2, endOffset) === "/>" ? "/>" : ">",
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
exports.getSelfClosingTag = getSelfClosingTag;
|
|
125
240
|
/**
|
|
126
241
|
* Get token info
|
|
127
242
|
*/
|
|
@@ -50,7 +50,8 @@ function parseByService(code) {
|
|
|
50
50
|
return { ast };
|
|
51
51
|
}
|
|
52
52
|
catch (_a) {
|
|
53
|
-
//
|
|
53
|
+
// FIXME: Workaround for escape bugs
|
|
54
|
+
// Adjust because may get the wrong escape as JSON.
|
|
54
55
|
const ast = JSON.parse(jsonAst.replace(/\\./gu, (m) => {
|
|
55
56
|
try {
|
|
56
57
|
JSON.parse(`"${m}"`);
|
|
@@ -117,7 +118,9 @@ function adjustHTMLBody(ast, htmlElement, htmlEnd, bodyElement, ctx) {
|
|
|
117
118
|
function fixLocations(node, ctx) {
|
|
118
119
|
// FIXME: Adjust because the parser does not return the correct location.
|
|
119
120
|
let start = 0;
|
|
120
|
-
(0, astro_1.walk)(node, ctx.code,
|
|
121
|
+
(0, astro_1.walk)(node, ctx.code,
|
|
122
|
+
// eslint-disable-next-line complexity -- X(
|
|
123
|
+
(node, [parent]) => {
|
|
121
124
|
if (node.type === "frontmatter") {
|
|
122
125
|
start = node.position.start.offset = tokenIndex(ctx, "---", start);
|
|
123
126
|
start = node.position.end.offset =
|
|
@@ -146,8 +149,47 @@ function fixLocations(node, ctx) {
|
|
|
146
149
|
start = (0, astro_1.getCommentEndOffset)(node, ctx);
|
|
147
150
|
}
|
|
148
151
|
else if (node.type === "text") {
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
if (parent.type === "element" &&
|
|
153
|
+
(parent.name === "script" || parent.name === "style")) {
|
|
154
|
+
node.position.start.offset = start;
|
|
155
|
+
start = ctx.code.indexOf(`</${parent.name}`, start);
|
|
156
|
+
if (start < 0) {
|
|
157
|
+
start = ctx.code.length;
|
|
158
|
+
}
|
|
159
|
+
// FIXME: Workaround for escape bugs
|
|
160
|
+
node.value = ctx.code.slice(node.position.start.offset, start);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const index = tokenIndexSafe(ctx.code, node.value, start);
|
|
164
|
+
if (index != null) {
|
|
165
|
+
start = node.position.start.offset = index;
|
|
166
|
+
start += node.value.length;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// FIXME: Workaround for escape bugs
|
|
170
|
+
node.position.start.offset = start;
|
|
171
|
+
const value = node.value.replace(/\s+/gu, "");
|
|
172
|
+
for (let charIndex = 0; charIndex < value.length; charIndex++) {
|
|
173
|
+
const char = value[charIndex];
|
|
174
|
+
const index = tokenIndexSafe(ctx.code, char, start);
|
|
175
|
+
if (index != null) {
|
|
176
|
+
start = index + 1;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
start = (0, astro_1.skipSpaces)(ctx.code, start);
|
|
180
|
+
if (ctx.code.startsWith("\\", start)) {
|
|
181
|
+
const codeChar = JSON.parse(`"\\${ctx.code[start + 1]}"`);
|
|
182
|
+
start += 2;
|
|
183
|
+
if (codeChar === char) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
start = tokenIndex(ctx, char, start) + 1;
|
|
188
|
+
}
|
|
189
|
+
start = (0, astro_1.skipSpaces)(ctx.code, start);
|
|
190
|
+
node.value = ctx.code.slice(node.position.start.offset, start);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
151
193
|
}
|
|
152
194
|
else if (node.type === "expression") {
|
|
153
195
|
start = node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
@@ -168,7 +210,7 @@ function fixLocations(node, ctx) {
|
|
|
168
210
|
else if (node.type === "root") {
|
|
169
211
|
// noop
|
|
170
212
|
}
|
|
171
|
-
}, (node, parent) => {
|
|
213
|
+
}, (node, [parent]) => {
|
|
172
214
|
if (node.type === "attribute") {
|
|
173
215
|
const attributes = parent.attributes;
|
|
174
216
|
if (attributes[attributes.length - 1] === node) {
|
|
@@ -18,7 +18,36 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
18
18
|
fragmentOpened = true;
|
|
19
19
|
}
|
|
20
20
|
// eslint-disable-next-line complexity -- X(
|
|
21
|
-
(0, astro_1.walkElements)(resultTemplate.ast, ctx.code, (node,
|
|
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
51
|
if (node.type === "frontmatter") {
|
|
23
52
|
const start = node.position.start.offset;
|
|
24
53
|
script.appendOriginal(start);
|
|
@@ -140,7 +169,7 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
140
169
|
});
|
|
141
170
|
}
|
|
142
171
|
}
|
|
143
|
-
const end =
|
|
172
|
+
const end = (0, astro_1.getSelfClosingTag)(node, parents, ctx);
|
|
144
173
|
if (end && end.end === ">") {
|
|
145
174
|
script.appendOriginal(end.offset - 1);
|
|
146
175
|
script.appendScript("/");
|
|
@@ -176,15 +205,17 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
176
205
|
script.appendOriginal(start);
|
|
177
206
|
let targetType;
|
|
178
207
|
if (fragmentOpened) {
|
|
179
|
-
script.
|
|
208
|
+
script.appendOriginal(start + 1);
|
|
209
|
+
script.appendScript(`></`);
|
|
210
|
+
script.skipOriginalOffset(length - 2);
|
|
180
211
|
targetType = types_1.AST_NODE_TYPES.JSXFragment;
|
|
181
212
|
}
|
|
182
213
|
else {
|
|
183
214
|
script.appendScript(`0;`);
|
|
184
215
|
targetType = types_1.AST_NODE_TYPES.ExpressionStatement;
|
|
216
|
+
script.skipOriginalOffset(length);
|
|
185
217
|
}
|
|
186
|
-
script.
|
|
187
|
-
script.addRestoreNodeProcess((scriptNode) => {
|
|
218
|
+
script.addRestoreNodeProcess((scriptNode, result) => {
|
|
188
219
|
if (scriptNode.range[0] === start &&
|
|
189
220
|
scriptNode.type === targetType) {
|
|
190
221
|
delete scriptNode.children;
|
|
@@ -194,6 +225,27 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
194
225
|
const commentNode = scriptNode;
|
|
195
226
|
commentNode.type = "AstroHTMLComment";
|
|
196
227
|
commentNode.value = node.value;
|
|
228
|
+
if (fragmentOpened) {
|
|
229
|
+
const removeTokenSet = new Set([
|
|
230
|
+
(token) => token.value === "<" &&
|
|
231
|
+
token.range[0] === scriptNode.range[0],
|
|
232
|
+
(token) => token.value === ">" &&
|
|
233
|
+
token.range[1] === scriptNode.range[1],
|
|
234
|
+
]);
|
|
235
|
+
const tokens = result.ast.tokens || [];
|
|
236
|
+
for (let index = tokens.length - 1; index >= 0; index--) {
|
|
237
|
+
const token = tokens[index];
|
|
238
|
+
for (const rt of removeTokenSet) {
|
|
239
|
+
if (rt(token)) {
|
|
240
|
+
tokens.splice(index, 1);
|
|
241
|
+
removeTokenSet.delete(rt);
|
|
242
|
+
if (!removeTokenSet.size) {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
197
249
|
return true;
|
|
198
250
|
}
|
|
199
251
|
return false;
|
|
@@ -232,6 +284,21 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
232
284
|
});
|
|
233
285
|
script.addToken("HTMLDocType", [start, end]);
|
|
234
286
|
}
|
|
287
|
+
if (((0, astro_1.isTag)(node) || node.type === "comment") &&
|
|
288
|
+
parent.type === "expression") {
|
|
289
|
+
const index = parent.children.indexOf(node);
|
|
290
|
+
const after = parent.children[index + 1];
|
|
291
|
+
if (!after || (!(0, astro_1.isTag)(after) && after.type !== "comment")) {
|
|
292
|
+
const before = parent.children[index - 1];
|
|
293
|
+
if (before && ((0, astro_1.isTag)(before) || before.type === "comment")) {
|
|
294
|
+
const end = (0, astro_1.isTag)(node)
|
|
295
|
+
? (0, astro_1.getTagEndOffset)(node, parents, ctx)
|
|
296
|
+
: (0, astro_1.getCommentEndOffset)(node, ctx);
|
|
297
|
+
script.appendOriginal(end);
|
|
298
|
+
script.appendScript("</>");
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
235
302
|
});
|
|
236
303
|
script.appendOriginal(ctx.code.length);
|
|
237
304
|
script.appendScript("</>");
|
|
@@ -249,36 +316,3 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
249
316
|
}
|
|
250
317
|
}
|
|
251
318
|
exports.processTemplate = processTemplate;
|
|
252
|
-
/**
|
|
253
|
-
* If the given tag is a void tag, get the self-closing tag.
|
|
254
|
-
*/
|
|
255
|
-
function getVoidSelfClosingTag(node, parent, ctx) {
|
|
256
|
-
var _a;
|
|
257
|
-
const children = node.children.filter((c) => c.type !== "text" || c.value.trim());
|
|
258
|
-
if (children.length > 0) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
const code = ctx.code;
|
|
262
|
-
let nextElementIndex = code.length;
|
|
263
|
-
const childIndex = parent.children.indexOf(node);
|
|
264
|
-
if (childIndex === parent.children.length - 1) {
|
|
265
|
-
// last
|
|
266
|
-
if ((_a = parent.position) === null || _a === void 0 ? void 0 : _a.end) {
|
|
267
|
-
nextElementIndex = parent.position.end.offset;
|
|
268
|
-
nextElementIndex = code.lastIndexOf("</", nextElementIndex);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
const next = parent.children[childIndex + 1];
|
|
273
|
-
nextElementIndex = next.position.start.offset;
|
|
274
|
-
}
|
|
275
|
-
const endOffset = (0, astro_1.getStartTagEndOffset)(node, ctx);
|
|
276
|
-
if (code.slice(endOffset, nextElementIndex).trim()) {
|
|
277
|
-
// has end tag
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
return {
|
|
281
|
-
offset: endOffset,
|
|
282
|
-
end: code.slice(endOffset - 2, endOffset) === "/>" ? "/>" : ">",
|
|
283
|
-
};
|
|
284
|
-
}
|
package/lib/visitor-keys.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-eslint-parser",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Astro parser for ESLint",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"debug": "mocha --require ts-node/register/transpile-only \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
|
|
21
21
|
"preversion": "npm run lint && npm test",
|
|
22
22
|
"update-fixtures": "ts-node --transpile-only ./tools/update-fixtures.ts",
|
|
23
|
+
"debug-parser": "ts-node --transpile-only ./tools/parser-test.ts",
|
|
23
24
|
"eslint-playground": "eslint tests/fixtures --ext .astro --config .eslintrc-for-playground.js --format codeframe",
|
|
24
25
|
"benchmark": "ts-node --transpile-only benchmark/index.ts"
|
|
25
26
|
},
|