astro-eslint-parser 0.0.4 → 0.0.7
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,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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AttributeNode, CommentNode, Node, ParentNode, TagLikeNode } from "@astrojs/compiler/types";
|
|
2
|
+
import type { Context } from "../context";
|
|
2
3
|
/**
|
|
3
4
|
* Checks if the given node is TagLikeNode
|
|
4
5
|
*/
|
|
@@ -8,25 +9,25 @@ export declare function isTag(node: Node): node is Node & TagLikeNode;
|
|
|
8
9
|
*/
|
|
9
10
|
export declare function isParent(node: Node): node is ParentNode;
|
|
10
11
|
/** walk element nodes */
|
|
11
|
-
export declare function walkElements(parent: ParentNode, cb: (n: Node, parent: ParentNode) => void): void;
|
|
12
|
+
export declare function walkElements(parent: ParentNode, code: string, cb: (n: Node, parent: ParentNode) => void): void;
|
|
12
13
|
/** walk nodes */
|
|
13
|
-
export declare function walk(parent: ParentNode, enter: (n: Node | AttributeNode, parent: ParentNode) => void, leave?: (n: Node | AttributeNode, parent: ParentNode) => void): void;
|
|
14
|
+
export declare function walk(parent: ParentNode, code: string, enter: (n: Node | AttributeNode, parent: ParentNode) => void, leave?: (n: Node | AttributeNode, parent: ParentNode) => void): void;
|
|
14
15
|
/**
|
|
15
16
|
* Get end offset of start tag
|
|
16
17
|
*/
|
|
17
|
-
export declare function getStartTagEndOffset(node: TagLikeNode,
|
|
18
|
+
export declare function getStartTagEndOffset(node: TagLikeNode, ctx: Context): number;
|
|
18
19
|
/**
|
|
19
20
|
* Get end offset of attribute
|
|
20
21
|
*/
|
|
21
|
-
export declare function getAttributeEndOffset(node: AttributeNode,
|
|
22
|
+
export declare function getAttributeEndOffset(node: AttributeNode, ctx: Context): number;
|
|
22
23
|
/**
|
|
23
24
|
* Get start offset of attribute value
|
|
24
25
|
*/
|
|
25
|
-
export declare function getAttributeValueStartOffset(node: AttributeNode,
|
|
26
|
+
export declare function getAttributeValueStartOffset(node: AttributeNode, ctx: Context): number;
|
|
26
27
|
/**
|
|
27
28
|
* Get end offset of comment
|
|
28
29
|
*/
|
|
29
|
-
export declare function getCommentEndOffset(node: CommentNode,
|
|
30
|
+
export declare function getCommentEndOffset(node: CommentNode, ctx: Context): number;
|
|
30
31
|
/**
|
|
31
32
|
* Skip spaces
|
|
32
33
|
*/
|
package/lib/astro/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.skipSpaces = exports.getCommentEndOffset = exports.getAttributeValueStartOffset = exports.getAttributeEndOffset = exports.getStartTagEndOffset = exports.walk = exports.walkElements = exports.isParent = exports.isTag = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
4
5
|
/**
|
|
5
6
|
* Checks if the given node is TagLikeNode
|
|
6
7
|
*/
|
|
@@ -19,27 +20,19 @@ function isParent(node) {
|
|
|
19
20
|
}
|
|
20
21
|
exports.isParent = isParent;
|
|
21
22
|
/** 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
|
-
}
|
|
23
|
+
function walkElements(parent, code, cb) {
|
|
24
|
+
const children = getSortedChildren(parent, code);
|
|
28
25
|
for (const node of children) {
|
|
29
26
|
cb(node, parent);
|
|
30
27
|
if (isParent(node)) {
|
|
31
|
-
walkElements(node, cb);
|
|
28
|
+
walkElements(node, code, cb);
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
exports.walkElements = walkElements;
|
|
36
33
|
/** 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
|
-
}
|
|
34
|
+
function walk(parent, code, enter, leave) {
|
|
35
|
+
const children = getSortedChildren(parent, code);
|
|
43
36
|
for (const node of children) {
|
|
44
37
|
enter(node, parent);
|
|
45
38
|
if (isTag(node)) {
|
|
@@ -49,7 +42,7 @@ function walk(parent, enter, leave) {
|
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
if (isParent(node)) {
|
|
52
|
-
walk(node, enter, leave);
|
|
45
|
+
walk(node, code, enter, leave);
|
|
53
46
|
}
|
|
54
47
|
leave === null || leave === void 0 ? void 0 : leave(node, parent);
|
|
55
48
|
}
|
|
@@ -58,45 +51,45 @@ exports.walk = walk;
|
|
|
58
51
|
/**
|
|
59
52
|
* Get end offset of start tag
|
|
60
53
|
*/
|
|
61
|
-
function getStartTagEndOffset(node,
|
|
54
|
+
function getStartTagEndOffset(node, ctx) {
|
|
62
55
|
const lastAttr = node.attributes[node.attributes.length - 1];
|
|
63
56
|
let beforeCloseIndex;
|
|
64
57
|
if (lastAttr) {
|
|
65
|
-
beforeCloseIndex = getAttributeEndOffset(lastAttr,
|
|
58
|
+
beforeCloseIndex = getAttributeEndOffset(lastAttr, ctx);
|
|
66
59
|
}
|
|
67
60
|
else {
|
|
68
|
-
const info = getTokenInfo(
|
|
61
|
+
const info = getTokenInfo(ctx, [`<${node.name}`], node.position.start.offset);
|
|
69
62
|
beforeCloseIndex = info.index + info.match.length;
|
|
70
63
|
}
|
|
71
|
-
const info = getTokenInfo(
|
|
64
|
+
const info = getTokenInfo(ctx, [[">", "/>"]], beforeCloseIndex);
|
|
72
65
|
return info.index + info.match.length;
|
|
73
66
|
}
|
|
74
67
|
exports.getStartTagEndOffset = getStartTagEndOffset;
|
|
75
68
|
/**
|
|
76
69
|
* Get end offset of attribute
|
|
77
70
|
*/
|
|
78
|
-
function getAttributeEndOffset(node,
|
|
71
|
+
function getAttributeEndOffset(node, ctx) {
|
|
79
72
|
let info;
|
|
80
73
|
if (node.kind === "empty") {
|
|
81
|
-
info = getTokenInfo(
|
|
74
|
+
info = getTokenInfo(ctx, [node.name], node.position.start.offset);
|
|
82
75
|
}
|
|
83
76
|
else if (node.kind === "quoted") {
|
|
84
|
-
info = getTokenInfo(
|
|
77
|
+
info = getTokenInfo(ctx, [[`"${node.value}"`, `'${node.value}'`, node.value]], getAttributeValueStartOffset(node, ctx));
|
|
85
78
|
}
|
|
86
79
|
else if (node.kind === "expression") {
|
|
87
|
-
info = getTokenInfo(
|
|
80
|
+
info = getTokenInfo(ctx, ["{", node.value, "}"], getAttributeValueStartOffset(node, ctx));
|
|
88
81
|
}
|
|
89
82
|
else if (node.kind === "shorthand") {
|
|
90
|
-
info = getTokenInfo(
|
|
83
|
+
info = getTokenInfo(ctx, ["{", node.name, "}"], node.position.start.offset);
|
|
91
84
|
}
|
|
92
85
|
else if (node.kind === "spread") {
|
|
93
|
-
info = getTokenInfo(
|
|
86
|
+
info = getTokenInfo(ctx, ["{", "...", node.name, "}"], node.position.start.offset);
|
|
94
87
|
}
|
|
95
88
|
else if (node.kind === "template-literal") {
|
|
96
|
-
info = getTokenInfo(
|
|
89
|
+
info = getTokenInfo(ctx, [`\`${node.value}\``], getAttributeValueStartOffset(node, ctx));
|
|
97
90
|
}
|
|
98
91
|
else {
|
|
99
|
-
throw new
|
|
92
|
+
throw new errors_1.ParseError(`Unknown attr kind: ${node.kind}`, node.position.start.offset, ctx);
|
|
100
93
|
}
|
|
101
94
|
return info.index + info.match.length;
|
|
102
95
|
}
|
|
@@ -104,19 +97,19 @@ exports.getAttributeEndOffset = getAttributeEndOffset;
|
|
|
104
97
|
/**
|
|
105
98
|
* Get start offset of attribute value
|
|
106
99
|
*/
|
|
107
|
-
function getAttributeValueStartOffset(node,
|
|
100
|
+
function getAttributeValueStartOffset(node, ctx) {
|
|
108
101
|
let info;
|
|
109
102
|
if (node.kind === "quoted") {
|
|
110
|
-
info = getTokenInfo(
|
|
103
|
+
info = getTokenInfo(ctx, [node.name, "=", [`"`, `'`, node.value]], node.position.start.offset);
|
|
111
104
|
}
|
|
112
105
|
else if (node.kind === "expression") {
|
|
113
|
-
info = getTokenInfo(
|
|
106
|
+
info = getTokenInfo(ctx, [node.name, "=", "{"], node.position.start.offset);
|
|
114
107
|
}
|
|
115
108
|
else if (node.kind === "template-literal") {
|
|
116
|
-
info = getTokenInfo(
|
|
109
|
+
info = getTokenInfo(ctx, [node.name, "=", "`"], node.position.start.offset);
|
|
117
110
|
}
|
|
118
111
|
else {
|
|
119
|
-
throw new
|
|
112
|
+
throw new errors_1.ParseError(`Unknown attr kind: ${node.kind}`, node.position.start.offset, ctx);
|
|
120
113
|
}
|
|
121
114
|
return info.index;
|
|
122
115
|
}
|
|
@@ -124,15 +117,15 @@ exports.getAttributeValueStartOffset = getAttributeValueStartOffset;
|
|
|
124
117
|
/**
|
|
125
118
|
* Get end offset of comment
|
|
126
119
|
*/
|
|
127
|
-
function getCommentEndOffset(node,
|
|
128
|
-
const info = getTokenInfo(
|
|
120
|
+
function getCommentEndOffset(node, ctx) {
|
|
121
|
+
const info = getTokenInfo(ctx, ["<!--", node.value, "-->"], node.position.start.offset);
|
|
129
122
|
return info.index + info.match.length;
|
|
130
123
|
}
|
|
131
124
|
exports.getCommentEndOffset = getCommentEndOffset;
|
|
132
125
|
/**
|
|
133
126
|
* Get token info
|
|
134
127
|
*/
|
|
135
|
-
function getTokenInfo(
|
|
128
|
+
function getTokenInfo(ctx, tokens, position) {
|
|
136
129
|
let lastMatch;
|
|
137
130
|
for (const t of tokens) {
|
|
138
131
|
const index = lastMatch
|
|
@@ -142,7 +135,7 @@ function getTokenInfo(string, tokens, position) {
|
|
|
142
135
|
? matchOfStr(t, index)
|
|
143
136
|
: matchOfForMulti(t, index);
|
|
144
137
|
if (m == null) {
|
|
145
|
-
throw new
|
|
138
|
+
throw new errors_1.ParseError(`Unknown token at ${index}, expected: ${JSON.stringify(t)}, actual: ${JSON.stringify(ctx.code.slice(index, index + 10))}`, index, ctx);
|
|
146
139
|
}
|
|
147
140
|
lastMatch = m;
|
|
148
141
|
}
|
|
@@ -151,8 +144,8 @@ function getTokenInfo(string, tokens, position) {
|
|
|
151
144
|
* For string
|
|
152
145
|
*/
|
|
153
146
|
function matchOfStr(search, position) {
|
|
154
|
-
const index = search.trim() === search ? skipSpaces(
|
|
155
|
-
if (
|
|
147
|
+
const index = search.trim() === search ? skipSpaces(ctx.code, position) : position;
|
|
148
|
+
if (ctx.code.startsWith(search, index)) {
|
|
156
149
|
return {
|
|
157
150
|
match: search,
|
|
158
151
|
index,
|
|
@@ -186,3 +179,41 @@ function skipSpaces(string, position) {
|
|
|
186
179
|
return position;
|
|
187
180
|
}
|
|
188
181
|
exports.skipSpaces = skipSpaces;
|
|
182
|
+
/**
|
|
183
|
+
* Get children
|
|
184
|
+
*/
|
|
185
|
+
function getSortedChildren(parent, code) {
|
|
186
|
+
var _a;
|
|
187
|
+
if (parent.type === "root" && ((_a = parent.children[0]) === null || _a === void 0 ? void 0 : _a.type) === "frontmatter") {
|
|
188
|
+
// The order of comments and frontmatter may be changed.
|
|
189
|
+
const children = [...parent.children];
|
|
190
|
+
if (children.every((n) => n.position)) {
|
|
191
|
+
return children.sort((a, b) => a.position.start.offset - b.position.start.offset);
|
|
192
|
+
}
|
|
193
|
+
let start = skipSpaces(code, 0);
|
|
194
|
+
if (code.startsWith("<!", start)) {
|
|
195
|
+
const frontmatter = children.shift();
|
|
196
|
+
const before = [];
|
|
197
|
+
let first;
|
|
198
|
+
while ((first = children.shift())) {
|
|
199
|
+
start = skipSpaces(code, start);
|
|
200
|
+
if (first.type === "comment" &&
|
|
201
|
+
code.startsWith("<!--", start)) {
|
|
202
|
+
start = code.indexOf("-->", start + 4) + 3;
|
|
203
|
+
before.push(first);
|
|
204
|
+
}
|
|
205
|
+
else if (first.type === "doctype" &&
|
|
206
|
+
code.startsWith("<!", start)) {
|
|
207
|
+
start = code.indexOf(">", start + 2) + 1;
|
|
208
|
+
before.push(first);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
children.unshift(first);
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return [...before, frontmatter, ...children];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return parent.children;
|
|
219
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ParseResult } from "@astrojs/compiler";
|
|
2
|
+
import type { Context } from "../../context";
|
|
2
3
|
/**
|
|
3
4
|
* Parse code by `@astrojs/compiler`
|
|
4
5
|
*/
|
|
5
|
-
export declare function parse(code: string): ParseResult;
|
|
6
|
+
export declare function parse(code: string, ctx: Context): ParseResult;
|
|
@@ -26,26 +26,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.parse = void 0;
|
|
27
27
|
const service = __importStar(require("./astrojs-compiler-service"));
|
|
28
28
|
const astro_1 = require("../../astro");
|
|
29
|
+
const errors_1 = require("../../errors");
|
|
29
30
|
/**
|
|
30
31
|
* Parse code by `@astrojs/compiler`
|
|
31
32
|
*/
|
|
32
|
-
function parse(code) {
|
|
33
|
+
function parse(code, ctx) {
|
|
33
34
|
const ast = service.parse(code, { position: true }).ast;
|
|
34
|
-
fixLocations(ast,
|
|
35
|
+
fixLocations(ast, ctx);
|
|
35
36
|
return { ast };
|
|
36
37
|
}
|
|
37
38
|
exports.parse = parse;
|
|
38
39
|
/**
|
|
39
40
|
* Fix locations
|
|
40
41
|
*/
|
|
41
|
-
function fixLocations(node,
|
|
42
|
+
function fixLocations(node, ctx) {
|
|
42
43
|
// FIXME: Adjust because the parser does not return the correct location.
|
|
43
44
|
let start = 0;
|
|
44
|
-
(0, astro_1.walk)(node, (node) => {
|
|
45
|
+
(0, astro_1.walk)(node, ctx.code, (node) => {
|
|
45
46
|
if (node.type === "frontmatter") {
|
|
46
|
-
start = node.position.start.offset = tokenIndex(
|
|
47
|
+
start = node.position.start.offset = tokenIndex(ctx, "---", start);
|
|
47
48
|
start = node.position.end.offset =
|
|
48
|
-
tokenIndex(
|
|
49
|
+
tokenIndex(ctx, "---", start + 3 + node.value.length) + 3;
|
|
49
50
|
}
|
|
50
51
|
else if (node.type === "fragment" ||
|
|
51
52
|
node.type === "element" ||
|
|
@@ -54,37 +55,40 @@ function fixLocations(node, code) {
|
|
|
54
55
|
if (!node.position) {
|
|
55
56
|
node.position = { start: {}, end: {} };
|
|
56
57
|
}
|
|
57
|
-
start = node.position.start.offset = tokenIndex(
|
|
58
|
+
start = node.position.start.offset = tokenIndex(ctx, "<", start);
|
|
58
59
|
start += 1;
|
|
59
60
|
start += node.name.length;
|
|
60
61
|
if (!node.attributes.length) {
|
|
61
|
-
start = (0, astro_1.getStartTagEndOffset)(node,
|
|
62
|
+
start = (0, astro_1.getStartTagEndOffset)(node, ctx);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
else if (node.type === "attribute") {
|
|
65
|
-
fixLocationForAttr(node,
|
|
66
|
-
start = (0, astro_1.getAttributeEndOffset)(node,
|
|
66
|
+
fixLocationForAttr(node, ctx, start);
|
|
67
|
+
start = (0, astro_1.getAttributeEndOffset)(node, ctx);
|
|
67
68
|
}
|
|
68
69
|
else if (node.type === "comment") {
|
|
69
|
-
node.position.start.offset = tokenIndex(
|
|
70
|
-
start = (0, astro_1.getCommentEndOffset)(node,
|
|
70
|
+
node.position.start.offset = tokenIndex(ctx, "<!--", start);
|
|
71
|
+
start = (0, astro_1.getCommentEndOffset)(node, ctx);
|
|
71
72
|
}
|
|
72
73
|
else if (node.type === "text") {
|
|
73
|
-
start = node.position.start.offset = tokenIndex(
|
|
74
|
+
start = node.position.start.offset = tokenIndex(ctx, node.value, start);
|
|
74
75
|
start += node.value.length;
|
|
75
76
|
}
|
|
76
77
|
else if (node.type === "expression") {
|
|
77
|
-
start = node.position.start.offset = tokenIndex(
|
|
78
|
+
start = node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
78
79
|
start += 1;
|
|
79
80
|
}
|
|
80
81
|
else if (node.type === "doctype") {
|
|
81
82
|
if (!node.position) {
|
|
82
83
|
node.position = { start: {}, end: {} };
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
if (!node.position.end) {
|
|
86
|
+
node.position.end = {};
|
|
87
|
+
}
|
|
88
|
+
start = node.position.start.offset = tokenIndex(ctx, "<!", start);
|
|
85
89
|
start += 2;
|
|
86
90
|
start = node.position.end.offset =
|
|
87
|
-
code.indexOf(">", start) + 1;
|
|
91
|
+
ctx.code.indexOf(">", start) + 1;
|
|
88
92
|
}
|
|
89
93
|
else if (node.type === "root") {
|
|
90
94
|
// noop
|
|
@@ -93,24 +97,21 @@ function fixLocations(node, code) {
|
|
|
93
97
|
if (node.type === "attribute") {
|
|
94
98
|
const attributes = parent.attributes;
|
|
95
99
|
if (attributes[attributes.length - 1] === node) {
|
|
96
|
-
start = (0, astro_1.getStartTagEndOffset)(parent,
|
|
100
|
+
start = (0, astro_1.getStartTagEndOffset)(parent, ctx);
|
|
97
101
|
}
|
|
98
102
|
return;
|
|
99
103
|
}
|
|
100
104
|
if (node.type === "expression") {
|
|
101
|
-
start = tokenIndex(
|
|
105
|
+
start = tokenIndex(ctx, "}", start) + 1;
|
|
102
106
|
}
|
|
103
107
|
else if (node.type === "fragment" ||
|
|
104
108
|
node.type === "element" ||
|
|
105
109
|
node.type === "component" ||
|
|
106
110
|
node.type === "custom-element") {
|
|
107
|
-
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const closeTagStart = tokenIndexSafe(code, `</${node.name}`, start);
|
|
111
|
+
const closeTagStart = tokenIndexSafe(ctx.code, `</${node.name}`, start);
|
|
111
112
|
if (closeTagStart != null) {
|
|
112
113
|
start = closeTagStart + 2 + node.name.length;
|
|
113
|
-
start = tokenIndex(
|
|
114
|
+
start = tokenIndex(ctx, ">", start) + 1;
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
else {
|
|
@@ -124,37 +125,37 @@ function fixLocations(node, code) {
|
|
|
124
125
|
/**
|
|
125
126
|
* Fix locations
|
|
126
127
|
*/
|
|
127
|
-
function fixLocationForAttr(node,
|
|
128
|
+
function fixLocationForAttr(node, ctx, start) {
|
|
128
129
|
if (node.kind === "empty") {
|
|
129
|
-
node.position.start.offset = tokenIndex(
|
|
130
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
130
131
|
}
|
|
131
132
|
else if (node.kind === "quoted") {
|
|
132
|
-
node.position.start.offset = tokenIndex(
|
|
133
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
133
134
|
}
|
|
134
135
|
else if (node.kind === "expression") {
|
|
135
|
-
node.position.start.offset = tokenIndex(
|
|
136
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
136
137
|
}
|
|
137
138
|
else if (node.kind === "shorthand") {
|
|
138
|
-
node.position.start.offset = tokenIndex(
|
|
139
|
+
node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
139
140
|
}
|
|
140
141
|
else if (node.kind === "spread") {
|
|
141
|
-
node.position.start.offset = tokenIndex(
|
|
142
|
+
node.position.start.offset = tokenIndex(ctx, "{", start);
|
|
142
143
|
}
|
|
143
144
|
else if (node.kind === "template-literal") {
|
|
144
|
-
node.position.start.offset = tokenIndex(
|
|
145
|
+
node.position.start.offset = tokenIndex(ctx, node.name, start);
|
|
145
146
|
}
|
|
146
147
|
else {
|
|
147
|
-
throw new
|
|
148
|
+
throw new errors_1.ParseError(`Unknown attr kind: ${node.kind}`, node.position.start.offset, ctx);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
/**
|
|
151
152
|
* Get token index
|
|
152
153
|
*/
|
|
153
|
-
function tokenIndex(
|
|
154
|
-
const index = tokenIndexSafe(
|
|
154
|
+
function tokenIndex(ctx, token, position) {
|
|
155
|
+
const index = tokenIndexSafe(ctx.code, token, position);
|
|
155
156
|
if (index == null) {
|
|
156
|
-
const start = token.trim() === token ? (0, astro_1.skipSpaces)(
|
|
157
|
-
throw new
|
|
157
|
+
const start = token.trim() === token ? (0, astro_1.skipSpaces)(ctx.code, position) : position;
|
|
158
|
+
throw new errors_1.ParseError(`Unknown token at ${start}, expected: ${JSON.stringify(token)}, actual: ${JSON.stringify(ctx.code.slice(start, start + 10))}`, start, ctx);
|
|
158
159
|
}
|
|
159
160
|
return index;
|
|
160
161
|
}
|
package/lib/parser/index.js
CHANGED
|
@@ -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);
|
|
@@ -115,8 +115,8 @@ function processTemplate(ctx, resultTemplate) {
|
|
|
115
115
|
}
|
|
116
116
|
else if (attr.kind === "template-literal") {
|
|
117
117
|
const attrStart = attr.position.start.offset;
|
|
118
|
-
const start = (0, astro_1.getAttributeValueStartOffset)(attr, ctx
|
|
119
|
-
const end = (0, astro_1.getAttributeEndOffset)(attr, ctx
|
|
118
|
+
const start = (0, astro_1.getAttributeValueStartOffset)(attr, ctx);
|
|
119
|
+
const end = (0, astro_1.getAttributeEndOffset)(attr, ctx);
|
|
120
120
|
script.appendOriginal(start);
|
|
121
121
|
script.appendScript("{");
|
|
122
122
|
script.appendOriginal(end);
|
|
@@ -253,7 +253,7 @@ function getVoidSelfClosingTag(node, parent, ctx) {
|
|
|
253
253
|
const next = parent.children[childIndex + 1];
|
|
254
254
|
nextElementIndex = next.position.start.offset;
|
|
255
255
|
}
|
|
256
|
-
const endOffset = (0, astro_1.getStartTagEndOffset)(node,
|
|
256
|
+
const endOffset = (0, astro_1.getStartTagEndOffset)(node, ctx);
|
|
257
257
|
if (code.slice(endOffset, nextElementIndex).trim()) {
|
|
258
258
|
// has end tag
|
|
259
259
|
return null;
|