@prisma-next/psl-parser 0.14.0-dev.5 → 0.14.0-dev.51
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 +28 -10
- package/dist/declarations-DR6To8_k.mjs +1060 -0
- package/dist/declarations-DR6To8_k.mjs.map +1 -0
- package/dist/format.d.mts +1 -1
- package/dist/format.mjs +2 -1
- package/dist/format.mjs.map +1 -1
- package/dist/index.d.mts +239 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +785 -3
- package/dist/index.mjs.map +1 -1
- package/dist/parse-3-vr14ej.mjs +626 -0
- package/dist/parse-3-vr14ej.mjs.map +1 -0
- package/dist/{parse-BjZ1LPe6.d.mts → parse-BazJr7Ye.d.mts} +128 -51
- package/dist/parse-BazJr7Ye.d.mts.map +1 -0
- package/dist/syntax.d.mts +20 -2
- package/dist/syntax.d.mts.map +1 -1
- package/dist/syntax.mjs +43 -2
- package/dist/syntax.mjs.map +1 -0
- package/package.json +9 -25
- package/src/attribute-spec/combinators/bool.ts +19 -0
- package/src/attribute-spec/combinators/diagnostic.ts +15 -0
- package/src/attribute-spec/combinators/entity-ref.ts +24 -0
- package/src/attribute-spec/combinators/field-ref.ts +36 -0
- package/src/attribute-spec/combinators/identifier.ts +16 -0
- package/src/attribute-spec/combinators/int.ts +19 -0
- package/src/attribute-spec/combinators/list.ts +43 -0
- package/src/attribute-spec/combinators/one-of.ts +29 -0
- package/src/attribute-spec/combinators/record.ts +43 -0
- package/src/attribute-spec/combinators/str.ts +19 -0
- package/src/attribute-spec/field-attribute.ts +27 -0
- package/src/attribute-spec/interpret.ts +154 -0
- package/src/attribute-spec/model-attribute.ts +27 -0
- package/src/attribute-spec/optional.ts +8 -0
- package/src/attribute-spec/types.ts +72 -0
- package/src/block-reconstruction.ts +139 -0
- package/src/exports/index.ts +57 -3
- package/src/exports/syntax.ts +25 -5
- package/src/extension-block.ts +107 -0
- package/src/parse.ts +23 -5
- package/src/resolve.ts +123 -0
- package/src/source-file.ts +25 -0
- package/src/symbol-table.ts +446 -0
- package/src/syntax/ast/attributes.ts +5 -6
- package/src/syntax/ast/declarations.ts +51 -26
- package/src/syntax/ast/expressions.ts +12 -13
- package/src/syntax/ast/identifier.ts +2 -3
- package/src/syntax/ast/qualified-name.ts +28 -19
- package/src/syntax/ast/type-annotation.ts +4 -5
- package/src/syntax/ast-helpers.ts +27 -3
- package/src/syntax/navigation.ts +55 -0
- package/src/syntax/red.ts +317 -42
- package/dist/parse-B_3gIEFd.mjs +0 -1421
- package/dist/parse-B_3gIEFd.mjs.map +0 -1
- package/dist/parse-BjZ1LPe6.d.mts.map +0 -1
- package/dist/parser-CaplKvRs.mjs +0 -1145
- package/dist/parser-CaplKvRs.mjs.map +0 -1
- package/dist/parser-Dfi3Wfdq.d.mts +0 -7
- package/dist/parser-Dfi3Wfdq.d.mts.map +0 -1
- package/dist/parser.d.mts +0 -3
- package/dist/parser.mjs +0 -3
- package/src/exports/parser.ts +0 -4
- package/src/parser.ts +0 -1642
package/src/syntax/red.ts
CHANGED
|
@@ -1,27 +1,154 @@
|
|
|
1
|
-
import type { Token } from '../tokenizer';
|
|
2
|
-
import type { GreenElement, GreenNode } from './green';
|
|
1
|
+
import type { Token, TokenKind } from '../tokenizer';
|
|
2
|
+
import type { GreenElement, GreenNode, GreenToken } from './green';
|
|
3
3
|
import type { SyntaxKind } from './syntax-kind';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A token in the red tree. Unlike the green-layer {@link Token} (kind + text
|
|
7
|
-
* only), a red token also carries its absolute `offset` within the source
|
|
8
|
-
*
|
|
7
|
+
* only), a red token also carries its absolute `offset` within the source and a
|
|
8
|
+
* link back to its `parent` {@link SyntaxNode}, so a cursor anchored on a token
|
|
9
|
+
* can walk outward (parent, previous/next token, siblings) without re-scanning
|
|
10
|
+
* from the document root.
|
|
9
11
|
*/
|
|
10
|
-
export
|
|
12
|
+
export class SyntaxToken implements Token {
|
|
13
|
+
readonly green: GreenToken;
|
|
14
|
+
readonly kind: TokenKind;
|
|
15
|
+
readonly text: string;
|
|
11
16
|
readonly offset: number;
|
|
17
|
+
readonly parent: SyntaxNode;
|
|
18
|
+
/** Position within the parent's children, enabling O(1) sibling navigation without rescanning the green layer. */
|
|
19
|
+
readonly index: number;
|
|
20
|
+
|
|
21
|
+
constructor(green: GreenToken, offset: number, parent: SyntaxNode, index: number) {
|
|
22
|
+
this.green = green;
|
|
23
|
+
this.kind = green.kind;
|
|
24
|
+
this.text = green.text;
|
|
25
|
+
this.offset = offset;
|
|
26
|
+
this.parent = parent;
|
|
27
|
+
this.index = index;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get textLength(): number {
|
|
31
|
+
return this.text.length;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get endOffset(): number {
|
|
35
|
+
return this.offset + this.textLength;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Whether `offset` falls within this token, inclusive of both ends. */
|
|
39
|
+
isInside(offset: number): boolean {
|
|
40
|
+
return offset >= this.offset && offset <= this.endOffset;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
isOutside(offset: number): boolean {
|
|
44
|
+
return !this.isInside(offset);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The sibling element immediately after this token within its parent. */
|
|
48
|
+
get nextSiblingOrToken(): SyntaxElement | undefined {
|
|
49
|
+
return childAt(this.parent, this.index + 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The sibling element immediately before this token within its parent. */
|
|
53
|
+
get prevSiblingOrToken(): SyntaxElement | undefined {
|
|
54
|
+
return childAt(this.parent, this.index - 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The next token in document order, crossing node boundaries. */
|
|
58
|
+
get nextToken(): SyntaxToken | undefined {
|
|
59
|
+
for (let el = climbingNext(this); el !== undefined; el = climbingNext(el)) {
|
|
60
|
+
const token = firstToken(el);
|
|
61
|
+
if (token !== undefined) return token;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The previous token in document order, crossing node boundaries. */
|
|
67
|
+
get prevToken(): SyntaxToken | undefined {
|
|
68
|
+
for (let el = climbingPrev(this); el !== undefined; el = climbingPrev(el)) {
|
|
69
|
+
const token = lastToken(el);
|
|
70
|
+
if (token !== undefined) return token;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
12
74
|
}
|
|
13
75
|
|
|
14
76
|
export type SyntaxElement = SyntaxNode | SyntaxToken;
|
|
15
77
|
|
|
78
|
+
/**
|
|
79
|
+
* The result of {@link SyntaxNode.tokenAtOffset}: an offset can fall outside
|
|
80
|
+
* every token (`none`), strictly inside a single token (`single`), or exactly on
|
|
81
|
+
* the seam between two adjacent tokens (`between`). `leftBiased` / `rightBiased`
|
|
82
|
+
* collapse the seam case to one side; for `single` both return the same token,
|
|
83
|
+
* for `none` both return `undefined`.
|
|
84
|
+
*/
|
|
85
|
+
type TokenAtOffsetState =
|
|
86
|
+
| { readonly kind: 'none' }
|
|
87
|
+
| { readonly kind: 'single'; readonly token: SyntaxToken }
|
|
88
|
+
| { readonly kind: 'between'; readonly left: SyntaxToken; readonly right: SyntaxToken };
|
|
89
|
+
|
|
90
|
+
export class TokenAtOffset {
|
|
91
|
+
readonly #state: TokenAtOffsetState;
|
|
92
|
+
|
|
93
|
+
private constructor(state: TokenAtOffsetState) {
|
|
94
|
+
this.#state = state;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static none(): TokenAtOffset {
|
|
98
|
+
return new TokenAtOffset({ kind: 'none' });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static single(token: SyntaxToken): TokenAtOffset {
|
|
102
|
+
return new TokenAtOffset({ kind: 'single', token });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static between(left: SyntaxToken, right: SyntaxToken): TokenAtOffset {
|
|
106
|
+
return new TokenAtOffset({ kind: 'between', left, right });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
get isEmpty(): boolean {
|
|
110
|
+
return this.#state.kind === 'none';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get isBetween(): boolean {
|
|
114
|
+
return this.#state.kind === 'between';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
leftBiased(): SyntaxToken | undefined {
|
|
118
|
+
switch (this.#state.kind) {
|
|
119
|
+
case 'none':
|
|
120
|
+
return undefined;
|
|
121
|
+
case 'single':
|
|
122
|
+
return this.#state.token;
|
|
123
|
+
case 'between':
|
|
124
|
+
return this.#state.left;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
rightBiased(): SyntaxToken | undefined {
|
|
129
|
+
switch (this.#state.kind) {
|
|
130
|
+
case 'none':
|
|
131
|
+
return undefined;
|
|
132
|
+
case 'single':
|
|
133
|
+
return this.#state.token;
|
|
134
|
+
case 'between':
|
|
135
|
+
return this.#state.right;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
16
140
|
export class SyntaxNode {
|
|
17
141
|
readonly green: GreenNode;
|
|
18
142
|
readonly offset: number;
|
|
19
143
|
readonly parent: SyntaxNode | undefined;
|
|
144
|
+
/** Position within the parent's children, enabling O(1) sibling navigation without rescanning the green layer. */
|
|
145
|
+
readonly index: number;
|
|
20
146
|
|
|
21
|
-
constructor(green: GreenNode, offset: number, parent: SyntaxNode | undefined) {
|
|
147
|
+
constructor(green: GreenNode, offset: number, parent: SyntaxNode | undefined, index: number) {
|
|
22
148
|
this.green = green;
|
|
23
149
|
this.offset = offset;
|
|
24
150
|
this.parent = parent;
|
|
151
|
+
this.index = index;
|
|
25
152
|
}
|
|
26
153
|
|
|
27
154
|
get kind(): SyntaxKind {
|
|
@@ -32,6 +159,19 @@ export class SyntaxNode {
|
|
|
32
159
|
return this.green.textLength;
|
|
33
160
|
}
|
|
34
161
|
|
|
162
|
+
get endOffset(): number {
|
|
163
|
+
return this.offset + this.textLength;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Whether `offset` falls within this node, inclusive of both ends. */
|
|
167
|
+
isInside(offset: number): boolean {
|
|
168
|
+
return offset >= this.offset && offset <= this.endOffset;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
isOutside(offset: number): boolean {
|
|
172
|
+
return !this.isInside(offset);
|
|
173
|
+
}
|
|
174
|
+
|
|
35
175
|
get firstChild(): SyntaxElement | undefined {
|
|
36
176
|
return childAt(this, 0);
|
|
37
177
|
}
|
|
@@ -43,44 +183,40 @@ export class SyntaxNode {
|
|
|
43
183
|
}
|
|
44
184
|
|
|
45
185
|
get nextSibling(): SyntaxElement | undefined {
|
|
46
|
-
|
|
47
|
-
const siblings = this.parent.green.children;
|
|
48
|
-
let offset = this.parent.offset;
|
|
49
|
-
let found = false;
|
|
50
|
-
for (const child of siblings) {
|
|
51
|
-
if (found) {
|
|
52
|
-
return wrapElement(child, offset, this.parent);
|
|
53
|
-
}
|
|
54
|
-
const childLen = elementTextLength(child);
|
|
55
|
-
if (child.type === 'node' && offset === this.offset && child === this.green) {
|
|
56
|
-
found = true;
|
|
57
|
-
}
|
|
58
|
-
offset += childLen;
|
|
59
|
-
}
|
|
60
|
-
return undefined;
|
|
186
|
+
return this.parent === undefined ? undefined : childAt(this.parent, this.index + 1);
|
|
61
187
|
}
|
|
62
188
|
|
|
63
189
|
get prevSibling(): SyntaxElement | undefined {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
190
|
+
return this.parent === undefined ? undefined : childAt(this.parent, this.index - 1);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** The sibling element immediately after this node within its parent. */
|
|
194
|
+
get nextSiblingOrToken(): SyntaxElement | undefined {
|
|
195
|
+
return this.nextSibling;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** The sibling element immediately before this node within its parent. */
|
|
199
|
+
get prevSiblingOrToken(): SyntaxElement | undefined {
|
|
200
|
+
return this.prevSibling;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** The first token in this subtree (depth-first), or `undefined` if empty. */
|
|
204
|
+
get firstToken(): SyntaxToken | undefined {
|
|
205
|
+
return firstToken(this);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** The last token in this subtree (depth-first), or `undefined` if empty. */
|
|
209
|
+
get lastToken(): SyntaxToken | undefined {
|
|
210
|
+
return lastToken(this);
|
|
77
211
|
}
|
|
78
212
|
|
|
79
213
|
*children(): Iterable<SyntaxElement> {
|
|
80
214
|
let offset = this.offset;
|
|
215
|
+
let index = 0;
|
|
81
216
|
for (const child of this.green.children) {
|
|
82
|
-
yield wrapElement(child, offset, this);
|
|
217
|
+
yield wrapElement(child, offset, this, index);
|
|
83
218
|
offset += elementTextLength(child);
|
|
219
|
+
index++;
|
|
84
220
|
}
|
|
85
221
|
}
|
|
86
222
|
|
|
@@ -98,6 +234,21 @@ export class SyntaxNode {
|
|
|
98
234
|
}
|
|
99
235
|
}
|
|
100
236
|
|
|
237
|
+
/** The nearest match, testing this node itself before walking its ancestors. */
|
|
238
|
+
findAncestor<T>(cast: (node: SyntaxNode) => T | undefined): T | undefined {
|
|
239
|
+
const self = cast(this);
|
|
240
|
+
if (self !== undefined) {
|
|
241
|
+
return self;
|
|
242
|
+
}
|
|
243
|
+
for (const ancestor of this.ancestors()) {
|
|
244
|
+
const result = cast(ancestor);
|
|
245
|
+
if (result !== undefined) {
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
|
|
101
252
|
*descendants(): Iterable<SyntaxElement> {
|
|
102
253
|
const stack: SyntaxElement[] = [this];
|
|
103
254
|
for (let el = stack.pop(); el !== undefined; el = stack.pop()) {
|
|
@@ -116,23 +267,147 @@ export class SyntaxNode {
|
|
|
116
267
|
|
|
117
268
|
*tokens(): Iterable<SyntaxToken> {
|
|
118
269
|
for (const el of this.descendants()) {
|
|
119
|
-
if (
|
|
270
|
+
if (el instanceof SyntaxToken) {
|
|
120
271
|
yield el;
|
|
121
272
|
}
|
|
122
273
|
}
|
|
123
274
|
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* The token(s) at `offset`. The between-two-tokens case (offset exactly on a
|
|
278
|
+
* token seam) is represented explicitly so callers can left/right bias.
|
|
279
|
+
*/
|
|
280
|
+
tokenAtOffset(offset: number): TokenAtOffset {
|
|
281
|
+
return tokenAtOffsetOf(this, offset);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* The smallest element fully containing the range `[start, end]`. At a seam
|
|
286
|
+
* (and for empty ranges) the left-hand element is preferred, matching
|
|
287
|
+
* {@link containsOffset}'s inclusive span.
|
|
288
|
+
*/
|
|
289
|
+
coveringElement(start: number, end: number): SyntaxElement {
|
|
290
|
+
let result: SyntaxElement = this;
|
|
291
|
+
for (;;) {
|
|
292
|
+
if (result instanceof SyntaxToken) return result;
|
|
293
|
+
let next: SyntaxElement | undefined;
|
|
294
|
+
for (const child of result.children()) {
|
|
295
|
+
if (containsRange(child, start, end)) {
|
|
296
|
+
next = child;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (next === undefined) return result;
|
|
301
|
+
result = next;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
124
304
|
}
|
|
125
305
|
|
|
126
306
|
function elementTextLength(el: GreenElement): number {
|
|
127
307
|
return el.type === 'token' ? el.text.length : el.textLength;
|
|
128
308
|
}
|
|
129
309
|
|
|
130
|
-
function
|
|
310
|
+
function elementLength(el: SyntaxElement): number {
|
|
311
|
+
return el instanceof SyntaxToken ? el.text.length : el.textLength;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Whether `el` contains `offset`. The span is inclusive on both ends so a seam
|
|
316
|
+
* offset touches both neighbours.
|
|
317
|
+
*/
|
|
318
|
+
function containsOffset(el: SyntaxElement, offset: number): boolean {
|
|
319
|
+
const start = el.offset;
|
|
320
|
+
const len = elementLength(el);
|
|
321
|
+
return offset >= start && offset <= start + len;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function containsRange(el: SyntaxElement, start: number, end: number): boolean {
|
|
325
|
+
const elStart = el.offset;
|
|
326
|
+
const len = elementLength(el);
|
|
327
|
+
return elStart <= start && end <= elStart + len;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function tokenAtOffsetOf(el: SyntaxElement, offset: number): TokenAtOffset {
|
|
331
|
+
if (el instanceof SyntaxToken) {
|
|
332
|
+
return TokenAtOffset.single(el);
|
|
333
|
+
}
|
|
334
|
+
let left: SyntaxElement | undefined;
|
|
335
|
+
let right: SyntaxElement | undefined;
|
|
336
|
+
for (const child of el.children()) {
|
|
337
|
+
if (!containsOffset(child, offset)) continue;
|
|
338
|
+
if (left === undefined) {
|
|
339
|
+
left = child;
|
|
340
|
+
} else {
|
|
341
|
+
right = child;
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (left === undefined) return TokenAtOffset.none();
|
|
346
|
+
if (right === undefined) return tokenAtOffsetOf(left, offset);
|
|
347
|
+
const leftToken = tokenAtOffsetOf(left, offset).rightBiased();
|
|
348
|
+
const rightToken = tokenAtOffsetOf(right, offset).leftBiased();
|
|
349
|
+
if (leftToken !== undefined && rightToken !== undefined) {
|
|
350
|
+
return TokenAtOffset.between(leftToken, rightToken);
|
|
351
|
+
}
|
|
352
|
+
if (leftToken !== undefined) return TokenAtOffset.single(leftToken);
|
|
353
|
+
if (rightToken !== undefined) return TokenAtOffset.single(rightToken);
|
|
354
|
+
return TokenAtOffset.none();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function firstToken(el: SyntaxElement): SyntaxToken | undefined {
|
|
358
|
+
if (el instanceof SyntaxToken) return el;
|
|
359
|
+
for (const child of el.children()) {
|
|
360
|
+
const token = firstToken(child);
|
|
361
|
+
if (token !== undefined) return token;
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function lastToken(el: SyntaxElement): SyntaxToken | undefined {
|
|
367
|
+
if (el instanceof SyntaxToken) return el;
|
|
368
|
+
const children = Array.from(el.children());
|
|
369
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
370
|
+
const child = children[i];
|
|
371
|
+
if (child !== undefined) {
|
|
372
|
+
const token = lastToken(child);
|
|
373
|
+
if (token !== undefined) return token;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function climbingNext(el: SyntaxElement): SyntaxElement | undefined {
|
|
380
|
+
let current: SyntaxElement = el;
|
|
381
|
+
for (;;) {
|
|
382
|
+
const parent = current.parent;
|
|
383
|
+
if (parent === undefined) return undefined;
|
|
384
|
+
const sibling = childAt(parent, current.index + 1);
|
|
385
|
+
if (sibling !== undefined) return sibling;
|
|
386
|
+
current = parent;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function climbingPrev(el: SyntaxElement): SyntaxElement | undefined {
|
|
391
|
+
let current: SyntaxElement = el;
|
|
392
|
+
for (;;) {
|
|
393
|
+
const parent = current.parent;
|
|
394
|
+
if (parent === undefined) return undefined;
|
|
395
|
+
const sibling = childAt(parent, current.index - 1);
|
|
396
|
+
if (sibling !== undefined) return sibling;
|
|
397
|
+
current = parent;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function wrapElement(
|
|
402
|
+
green: GreenElement,
|
|
403
|
+
offset: number,
|
|
404
|
+
parent: SyntaxNode,
|
|
405
|
+
index: number,
|
|
406
|
+
): SyntaxElement {
|
|
131
407
|
if (green.type === 'token') {
|
|
132
|
-
|
|
133
|
-
return token;
|
|
408
|
+
return new SyntaxToken(green, offset, parent, index);
|
|
134
409
|
}
|
|
135
|
-
return new SyntaxNode(green, offset, parent);
|
|
410
|
+
return new SyntaxNode(green, offset, parent, index);
|
|
136
411
|
}
|
|
137
412
|
|
|
138
413
|
function childAt(node: SyntaxNode, index: number): SyntaxElement | undefined {
|
|
@@ -146,9 +421,9 @@ function childAt(node: SyntaxNode, index: number): SyntaxElement | undefined {
|
|
|
146
421
|
offset += elementTextLength(child);
|
|
147
422
|
}
|
|
148
423
|
}
|
|
149
|
-
return wrapElement(target, offset, node);
|
|
424
|
+
return wrapElement(target, offset, node, index);
|
|
150
425
|
}
|
|
151
426
|
|
|
152
427
|
export function createSyntaxTree(green: GreenNode): SyntaxNode {
|
|
153
|
-
return new SyntaxNode(green, 0, undefined);
|
|
428
|
+
return new SyntaxNode(green, 0, undefined, 0);
|
|
154
429
|
}
|