astro-eslint-parser 0.0.4 → 0.0.5
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 +2 -2
- package/lib/astro/index.d.ts +2 -2
- package/lib/astro/index.js +44 -14
- package/lib/parser/astro-parser/parse.js +4 -1
- package/lib/parser/process-template.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ 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
|
-
Currently this parser relies heavily on the internal API of [@astrojs/compiler]. It may stop working in a future update of [@astrojs/compiler].
|
|
18
|
+
⚠ Currently this parser relies heavily on the internal API of [@astrojs/compiler]. It may stop working in a future update of [@astrojs/compiler]. ⚠
|
|
19
19
|
|
|
20
20
|
[@astrojs/compiler]: https://github.com/withastro/compiler
|
|
21
21
|
|
|
@@ -151,7 +151,7 @@ For example, the [react/jsx-no-target-blank] rule works fine.
|
|
|
151
151
|
## Usage for Custom Rules / Plugins
|
|
152
152
|
|
|
153
153
|
- TBA
|
|
154
|
-
- You can check
|
|
154
|
+
- 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.
|
|
155
155
|
|
|
156
156
|
<!-- - [AST.md](./docs/AST.md) is AST specification. You can check it on the [Online DEMO](https://ota-meshi.github.io/astro-eslint-parser/). -->
|
|
157
157
|
<!-- - I have already [implemented some rules] in the [`@ota-meshi/eslint-plugin-astro`]. The source code for these rules will be helpful to you. -->
|
package/lib/astro/index.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export declare function isTag(node: Node): node is Node & TagLikeNode;
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function isParent(node: Node): node is ParentNode;
|
|
10
10
|
/** walk element nodes */
|
|
11
|
-
export declare function walkElements(parent: ParentNode, cb: (n: Node, parent: ParentNode) => void): void;
|
|
11
|
+
export declare function walkElements(parent: ParentNode, code: string, cb: (n: Node, parent: ParentNode) => void): void;
|
|
12
12
|
/** walk nodes */
|
|
13
|
-
export declare function walk(parent: ParentNode, enter: (n: Node | AttributeNode, parent: ParentNode) => void, leave?: (n: Node | AttributeNode, parent: ParentNode) => void): void;
|
|
13
|
+
export declare function walk(parent: ParentNode, code: string, enter: (n: Node | AttributeNode, parent: ParentNode) => void, leave?: (n: Node | AttributeNode, parent: ParentNode) => void): void;
|
|
14
14
|
/**
|
|
15
15
|
* Get end offset of start tag
|
|
16
16
|
*/
|
package/lib/astro/index.js
CHANGED
|
@@ -19,27 +19,19 @@ function isParent(node) {
|
|
|
19
19
|
}
|
|
20
20
|
exports.isParent = isParent;
|
|
21
21
|
/** walk element nodes */
|
|
22
|
-
function walkElements(parent, cb) {
|
|
23
|
-
|
|
24
|
-
if (parent.type === "root" && children.every((n) => n.position)) {
|
|
25
|
-
// The order of comments and frontmatter may be changed.
|
|
26
|
-
children = [...children].sort((a, b) => a.position.start.offset - b.position.start.offset);
|
|
27
|
-
}
|
|
22
|
+
function walkElements(parent, code, cb) {
|
|
23
|
+
const children = getSortedChildren(parent, code);
|
|
28
24
|
for (const node of children) {
|
|
29
25
|
cb(node, parent);
|
|
30
26
|
if (isParent(node)) {
|
|
31
|
-
walkElements(node, cb);
|
|
27
|
+
walkElements(node, code, cb);
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
}
|
|
35
31
|
exports.walkElements = walkElements;
|
|
36
32
|
/** walk nodes */
|
|
37
|
-
function walk(parent, enter, leave) {
|
|
38
|
-
|
|
39
|
-
if (parent.type === "root" && children.every((n) => n.position)) {
|
|
40
|
-
// The order of comments and frontmatter may be changed.
|
|
41
|
-
children = [...children].sort((a, b) => a.position.start.offset - b.position.start.offset);
|
|
42
|
-
}
|
|
33
|
+
function walk(parent, code, enter, leave) {
|
|
34
|
+
const children = getSortedChildren(parent, code);
|
|
43
35
|
for (const node of children) {
|
|
44
36
|
enter(node, parent);
|
|
45
37
|
if (isTag(node)) {
|
|
@@ -49,7 +41,7 @@ function walk(parent, enter, leave) {
|
|
|
49
41
|
}
|
|
50
42
|
}
|
|
51
43
|
if (isParent(node)) {
|
|
52
|
-
walk(node, enter, leave);
|
|
44
|
+
walk(node, code, enter, leave);
|
|
53
45
|
}
|
|
54
46
|
leave === null || leave === void 0 ? void 0 : leave(node, parent);
|
|
55
47
|
}
|
|
@@ -186,3 +178,41 @@ function skipSpaces(string, position) {
|
|
|
186
178
|
return position;
|
|
187
179
|
}
|
|
188
180
|
exports.skipSpaces = skipSpaces;
|
|
181
|
+
/**
|
|
182
|
+
* Get children
|
|
183
|
+
*/
|
|
184
|
+
function getSortedChildren(parent, code) {
|
|
185
|
+
var _a;
|
|
186
|
+
if (parent.type === "root" && ((_a = parent.children[0]) === null || _a === void 0 ? void 0 : _a.type) === "frontmatter") {
|
|
187
|
+
// The order of comments and frontmatter may be changed.
|
|
188
|
+
const children = [...parent.children];
|
|
189
|
+
if (children.every((n) => n.position)) {
|
|
190
|
+
return children.sort((a, b) => a.position.start.offset - b.position.start.offset);
|
|
191
|
+
}
|
|
192
|
+
let start = skipSpaces(code, 0);
|
|
193
|
+
if (code.startsWith("<!", start)) {
|
|
194
|
+
const frontmatter = children.shift();
|
|
195
|
+
const before = [];
|
|
196
|
+
let first;
|
|
197
|
+
while ((first = children.shift())) {
|
|
198
|
+
start = skipSpaces(code, start);
|
|
199
|
+
if (first.type === "comment" &&
|
|
200
|
+
code.startsWith("<!--", start)) {
|
|
201
|
+
start = code.indexOf("-->", start + 4) + 3;
|
|
202
|
+
before.push(first);
|
|
203
|
+
}
|
|
204
|
+
else if (first.type === "doctype" &&
|
|
205
|
+
code.startsWith("<!", start)) {
|
|
206
|
+
start = code.indexOf(">", start + 2) + 1;
|
|
207
|
+
before.push(first);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
children.unshift(first);
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return [...before, frontmatter, ...children];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return parent.children;
|
|
218
|
+
}
|
|
@@ -41,7 +41,7 @@ exports.parse = parse;
|
|
|
41
41
|
function fixLocations(node, code) {
|
|
42
42
|
// FIXME: Adjust because the parser does not return the correct location.
|
|
43
43
|
let start = 0;
|
|
44
|
-
(0, astro_1.walk)(node, (node) => {
|
|
44
|
+
(0, astro_1.walk)(node, code, (node) => {
|
|
45
45
|
if (node.type === "frontmatter") {
|
|
46
46
|
start = node.position.start.offset = tokenIndex(code, "---", start);
|
|
47
47
|
start = node.position.end.offset =
|
|
@@ -81,6 +81,9 @@ function fixLocations(node, code) {
|
|
|
81
81
|
if (!node.position) {
|
|
82
82
|
node.position = { start: {}, end: {} };
|
|
83
83
|
}
|
|
84
|
+
if (!node.position.end) {
|
|
85
|
+
node.position.end = {};
|
|
86
|
+
}
|
|
84
87
|
start = node.position.start.offset = tokenIndex(code, "<!", start);
|
|
85
88
|
start += 2;
|
|
86
89
|
start = node.position.end.offset =
|
|
@@ -16,7 +16,7 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
16
16
|
fragmentOpened = true;
|
|
17
17
|
}
|
|
18
18
|
// eslint-disable-next-line complexity -- X(
|
|
19
|
-
(0, astro_1.walkElements)(resultTemplate.ast, (node, parent) => {
|
|
19
|
+
(0, astro_1.walkElements)(resultTemplate.ast, ctx.code, (node, parent) => {
|
|
20
20
|
if (node.type === "frontmatter") {
|
|
21
21
|
const start = node.position.start.offset;
|
|
22
22
|
script.appendOriginal(start);
|