@prisma-next/psl-parser 0.14.0-dev.3 → 0.14.0-dev.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/dist/syntax.mjs CHANGED
@@ -1,1421 +1,2 @@
1
- import { n as isTerminatedStringLiteral, t as Tokenizer } from "./tokenizer-1hAHZzmp.mjs";
2
- import { UNSPECIFIED_PSL_NAMESPACE_ID } from "@prisma-next/framework-components/psl-ast";
3
- //#region src/source-file.ts
4
- const LINE_FEED = 10;
5
- var SourceFile = class {
6
- #text;
7
- #lineStarts;
8
- constructor(text) {
9
- this.#text = text;
10
- const lineStarts = [0];
11
- for (let offset = 0; offset < text.length; offset++) if (text.charCodeAt(offset) === LINE_FEED) lineStarts.push(offset + 1);
12
- this.#lineStarts = lineStarts;
13
- }
14
- get text() {
15
- return this.#text;
16
- }
17
- get length() {
18
- return this.#text.length;
19
- }
20
- get lineCount() {
21
- return this.#lineStarts.length;
22
- }
23
- lineStartOffsets() {
24
- return this.#lineStarts;
25
- }
26
- positionAt(offset) {
27
- const clamped = clamp(offset, 0, this.#text.length);
28
- const line = this.#lineIndexAt(clamped);
29
- return {
30
- line,
31
- character: clamped - this.#lineStartAt(line)
32
- };
33
- }
34
- offsetAt(position) {
35
- const line = clamp(position.line, 0, this.#lineStarts.length - 1);
36
- const lineStart = this.#lineStartAt(line);
37
- const lineEnd = this.#lineEndAt(line);
38
- return clamp(lineStart + position.character, lineStart, lineEnd);
39
- }
40
- #lineStartAt(line) {
41
- return this.#lineStarts[line] ?? 0;
42
- }
43
- #lineEndAt(line) {
44
- return line + 1 < this.#lineStarts.length ? this.#lineStartAt(line + 1) - 1 : this.#text.length;
45
- }
46
- #lineIndexAt(offset) {
47
- const lineStarts = this.#lineStarts;
48
- let low = 0;
49
- let high = lineStarts.length - 1;
50
- while (low < high) {
51
- const mid = low + high + 1 >>> 1;
52
- if ((lineStarts[mid] ?? 0) <= offset) low = mid;
53
- else high = mid - 1;
54
- }
55
- return low;
56
- }
57
- };
58
- function clamp(value, min, max) {
59
- if (value < min) return min;
60
- if (value > max) return max;
61
- return value;
62
- }
63
- //#endregion
64
- //#region src/syntax/red.ts
65
- var SyntaxNode = class SyntaxNode {
66
- green;
67
- offset;
68
- parent;
69
- constructor(green, offset, parent) {
70
- this.green = green;
71
- this.offset = offset;
72
- this.parent = parent;
73
- }
74
- get kind() {
75
- return this.green.kind;
76
- }
77
- get textLength() {
78
- return this.green.textLength;
79
- }
80
- get firstChild() {
81
- return childAt(this, 0);
82
- }
83
- get lastChild() {
84
- const len = this.green.children.length;
85
- if (len === 0) return void 0;
86
- return childAt(this, len - 1);
87
- }
88
- get nextSibling() {
89
- if (!this.parent) return void 0;
90
- const siblings = this.parent.green.children;
91
- let offset = this.parent.offset;
92
- let found = false;
93
- for (const child of siblings) {
94
- if (found) return wrapElement(child, offset, this.parent);
95
- const childLen = elementTextLength(child);
96
- if (child.type === "node" && offset === this.offset && child === this.green) found = true;
97
- offset += childLen;
98
- }
99
- }
100
- get prevSibling() {
101
- if (!this.parent) return void 0;
102
- const siblings = this.parent.green.children;
103
- let offset = this.parent.offset;
104
- let prev;
105
- for (const child of siblings) {
106
- if (child.type === "node" && offset === this.offset && child === this.green) {
107
- if (!prev) return void 0;
108
- return wrapElement(prev.green, prev.offset, this.parent);
109
- }
110
- prev = {
111
- green: child,
112
- offset
113
- };
114
- offset += elementTextLength(child);
115
- }
116
- }
117
- *children() {
118
- let offset = this.offset;
119
- for (const child of this.green.children) {
120
- yield wrapElement(child, offset, this);
121
- offset += elementTextLength(child);
122
- }
123
- }
124
- *childNodes() {
125
- for (const child of this.children()) if (child instanceof SyntaxNode) yield child;
126
- }
127
- *ancestors() {
128
- let current = this.parent;
129
- while (current) {
130
- yield current;
131
- current = current.parent;
132
- }
133
- }
134
- *descendants() {
135
- const stack = [this];
136
- for (let el = stack.pop(); el !== void 0; el = stack.pop()) {
137
- yield el;
138
- if (el instanceof SyntaxNode) {
139
- const children = Array.from(el.children());
140
- for (let i = children.length - 1; i >= 0; i--) {
141
- const child = children[i];
142
- if (child !== void 0) stack.push(child);
143
- }
144
- }
145
- }
146
- }
147
- *tokens() {
148
- for (const el of this.descendants()) if (!(el instanceof SyntaxNode)) yield el;
149
- }
150
- };
151
- function elementTextLength(el) {
152
- return el.type === "token" ? el.text.length : el.textLength;
153
- }
154
- function wrapElement(green, offset, parent) {
155
- if (green.type === "token") return {
156
- kind: green.kind,
157
- text: green.text,
158
- offset
159
- };
160
- return new SyntaxNode(green, offset, parent);
161
- }
162
- function childAt(node, index) {
163
- const children = node.green.children;
164
- const target = children[index];
165
- if (target === void 0) return void 0;
166
- let offset = node.offset;
167
- for (let i = 0; i < index; i++) {
168
- const child = children[i];
169
- if (child !== void 0) offset += elementTextLength(child);
170
- }
171
- return wrapElement(target, offset, node);
172
- }
173
- function createSyntaxTree(green) {
174
- return new SyntaxNode(green, 0, void 0);
175
- }
176
- //#endregion
177
- //#region src/syntax/ast-helpers.ts
178
- function findChildToken(node, kind) {
179
- for (const child of node.children()) if (!(child instanceof SyntaxNode) && child.kind === kind) return child;
180
- }
181
- function findFirstChild(node, cast) {
182
- for (const child of node.childNodes()) {
183
- const result = cast(child);
184
- if (result !== void 0) return result;
185
- }
186
- }
187
- function* filterChildren(node, cast) {
188
- for (const child of node.childNodes()) {
189
- const result = cast(child);
190
- if (result !== void 0) yield result;
191
- }
192
- }
193
- /**
194
- * Raw source text of a CST node, verbatim (quotes and brackets preserved). For
195
- * the decoded value of a string literal, decode it instead.
196
- */
197
- function printSyntax(node) {
198
- let text = "";
199
- for (const token of node.tokens()) text += token.text;
200
- return text;
201
- }
202
- //#endregion
203
- //#region src/syntax/ast/identifier.ts
204
- var IdentifierAst = class IdentifierAst {
205
- syntax;
206
- constructor(syntax) {
207
- this.syntax = syntax;
208
- }
209
- token() {
210
- return findChildToken(this.syntax, "Ident");
211
- }
212
- name() {
213
- return this.token()?.text;
214
- }
215
- static cast(node) {
216
- return node.kind === "Identifier" ? new IdentifierAst(node) : void 0;
217
- }
218
- };
219
- //#endregion
220
- //#region src/syntax/ast/qualified-name.ts
221
- /** A namespace-qualified name, e.g. `pgvector.Vector` or `supabase:auth.User`. */
222
- var QualifiedNameAst = class QualifiedNameAst {
223
- syntax;
224
- constructor(syntax) {
225
- this.syntax = syntax;
226
- }
227
- #lastSegment() {
228
- let last;
229
- for (const segment of filterChildren(this.syntax, IdentifierAst.cast)) last = segment;
230
- return last;
231
- }
232
- #penultimateSegment() {
233
- let last;
234
- let penultimate;
235
- for (const segment of filterChildren(this.syntax, IdentifierAst.cast)) {
236
- penultimate = last;
237
- last = segment;
238
- }
239
- return penultimate;
240
- }
241
- #separatorCount(kind) {
242
- let count = 0;
243
- for (const child of this.syntax.children()) if (!(child instanceof SyntaxNode) && child.kind === kind) count++;
244
- return count;
245
- }
246
- colon() {
247
- return findChildToken(this.syntax, "Colon");
248
- }
249
- dot() {
250
- return findChildToken(this.syntax, "Dot");
251
- }
252
- space() {
253
- if (!this.colon()) return void 0;
254
- return findFirstChild(this.syntax, IdentifierAst.cast);
255
- }
256
- namespace() {
257
- if (!this.dot()) return void 0;
258
- return this.#penultimateSegment();
259
- }
260
- identifier() {
261
- return this.#lastSegment();
262
- }
263
- /**
264
- * Every identifier segment, in source order. A bare `Vector` yields
265
- * `['Vector']`; a qualified `pgvector.Vector` yields `['pgvector', 'Vector']`.
266
- */
267
- path() {
268
- const segments = [];
269
- for (const segment of filterChildren(this.syntax, IdentifierAst.cast)) {
270
- const text = segment.token()?.text;
271
- if (text !== void 0) segments.push(text);
272
- }
273
- return segments;
274
- }
275
- /**
276
- * Flags a malformed name with more qualifier segments than allowed (a second
277
- * `:`-space or a second `.`-namespace).
278
- */
279
- isOverQualified() {
280
- return this.#separatorCount("Dot") > 1 || this.#separatorCount("Colon") > 1;
281
- }
282
- static cast(node) {
283
- return node.kind === "QualifiedName" ? new QualifiedNameAst(node) : void 0;
284
- }
285
- };
286
- //#endregion
287
- //#region src/syntax/ast/expressions.ts
288
- var FunctionCallAst = class FunctionCallAst {
289
- syntax;
290
- constructor(syntax) {
291
- this.syntax = syntax;
292
- }
293
- /** The qualified-name callee, or `undefined` when identifier segments sit directly under the node. */
294
- name() {
295
- return findFirstChild(this.syntax, QualifiedNameAst.cast);
296
- }
297
- /**
298
- * The dotted call path, in source order. A bare `Vector(…)` yields
299
- * `['Vector']`; a namespace-qualified `pgvector.Vector(…)` yields
300
- * `['pgvector', 'Vector']`. Empty when the call carries no identifier.
301
- */
302
- path() {
303
- const qualified = this.name();
304
- const segments = [];
305
- for (const segment of filterChildren(qualified?.syntax ?? this.syntax, IdentifierAst.cast)) {
306
- const text = segment.token()?.text;
307
- if (text !== void 0) segments.push(text);
308
- }
309
- return segments;
310
- }
311
- lparen() {
312
- return findChildToken(this.syntax, "LParen");
313
- }
314
- rparen() {
315
- return findChildToken(this.syntax, "RParen");
316
- }
317
- *args() {
318
- yield* filterChildren(this.syntax, AttributeArgAst.cast);
319
- }
320
- static cast(node) {
321
- return node.kind === "FunctionCall" ? new FunctionCallAst(node) : void 0;
322
- }
323
- };
324
- var ArrayLiteralAst = class ArrayLiteralAst {
325
- syntax;
326
- constructor(syntax) {
327
- this.syntax = syntax;
328
- }
329
- lbracket() {
330
- return findChildToken(this.syntax, "LBracket");
331
- }
332
- rbracket() {
333
- return findChildToken(this.syntax, "RBracket");
334
- }
335
- *elements() {
336
- yield* filterChildren(this.syntax, castExpression);
337
- }
338
- static cast(node) {
339
- return node.kind === "ArrayLiteral" ? new ArrayLiteralAst(node) : void 0;
340
- }
341
- };
342
- const HEX = /^[0-9a-fA-F]+$/;
343
- function decodeFixedHex(raw, start, width) {
344
- if (start + width > raw.length) return void 0;
345
- const hex = raw.slice(start, start + width);
346
- if (!HEX.test(hex)) return void 0;
347
- return String.fromCharCode(Number.parseInt(hex, 16));
348
- }
349
- function decodeStringLiteral(raw) {
350
- let out = "";
351
- let i = 0;
352
- while (i < raw.length) {
353
- const ch = raw.charAt(i);
354
- if (ch !== "\\" || i + 1 >= raw.length) {
355
- out += ch;
356
- i++;
357
- continue;
358
- }
359
- const next = raw.charAt(i + 1);
360
- switch (next) {
361
- case "n":
362
- out += "\n";
363
- i += 2;
364
- continue;
365
- case "r":
366
- out += "\r";
367
- i += 2;
368
- continue;
369
- case "t":
370
- out += " ";
371
- i += 2;
372
- continue;
373
- case "\"":
374
- out += "\"";
375
- i += 2;
376
- continue;
377
- case "'":
378
- out += "'";
379
- i += 2;
380
- continue;
381
- case "\\":
382
- out += "\\";
383
- i += 2;
384
- continue;
385
- case "x": {
386
- const decoded = decodeFixedHex(raw, i + 2, 2);
387
- if (decoded === void 0) {
388
- out += "\\x";
389
- i += 2;
390
- continue;
391
- }
392
- out += decoded;
393
- i += 4;
394
- continue;
395
- }
396
- case "u": {
397
- const decoded = decodeFixedHex(raw, i + 2, 4);
398
- if (decoded === void 0) {
399
- out += "\\u";
400
- i += 2;
401
- continue;
402
- }
403
- out += decoded;
404
- i += 6;
405
- continue;
406
- }
407
- default:
408
- out += `\\${next}`;
409
- i += 2;
410
- continue;
411
- }
412
- }
413
- return out;
414
- }
415
- var StringLiteralExprAst = class StringLiteralExprAst {
416
- syntax;
417
- constructor(syntax) {
418
- this.syntax = syntax;
419
- }
420
- token() {
421
- return findChildToken(this.syntax, "StringLiteral");
422
- }
423
- value() {
424
- const tok = this.token();
425
- if (!tok) return void 0;
426
- return decodeStringLiteral(tok.text.slice(1, -1));
427
- }
428
- static cast(node) {
429
- return node.kind === "StringLiteralExpr" ? new StringLiteralExprAst(node) : void 0;
430
- }
431
- };
432
- var NumberLiteralExprAst = class NumberLiteralExprAst {
433
- syntax;
434
- constructor(syntax) {
435
- this.syntax = syntax;
436
- }
437
- token() {
438
- return findChildToken(this.syntax, "NumberLiteral");
439
- }
440
- value() {
441
- const tok = this.token();
442
- if (!tok) return void 0;
443
- return Number(tok.text);
444
- }
445
- static cast(node) {
446
- return node.kind === "NumberLiteralExpr" ? new NumberLiteralExprAst(node) : void 0;
447
- }
448
- };
449
- var BooleanLiteralExprAst = class BooleanLiteralExprAst {
450
- syntax;
451
- constructor(syntax) {
452
- this.syntax = syntax;
453
- }
454
- token() {
455
- return findChildToken(this.syntax, "Ident");
456
- }
457
- value() {
458
- const tok = this.token();
459
- if (!tok) return void 0;
460
- if (tok.text === "true") return true;
461
- if (tok.text === "false") return false;
462
- }
463
- static cast(node) {
464
- return node.kind === "BooleanLiteralExpr" ? new BooleanLiteralExprAst(node) : void 0;
465
- }
466
- };
467
- var ObjectLiteralExprAst = class ObjectLiteralExprAst {
468
- syntax;
469
- constructor(syntax) {
470
- this.syntax = syntax;
471
- }
472
- lbrace() {
473
- return findChildToken(this.syntax, "LBrace");
474
- }
475
- rbrace() {
476
- return findChildToken(this.syntax, "RBrace");
477
- }
478
- *fields() {
479
- yield* filterChildren(this.syntax, ObjectFieldAst.cast);
480
- }
481
- static cast(node) {
482
- return node.kind === "ObjectLiteralExpr" ? new ObjectLiteralExprAst(node) : void 0;
483
- }
484
- };
485
- var ObjectFieldAst = class ObjectFieldAst {
486
- syntax;
487
- constructor(syntax) {
488
- this.syntax = syntax;
489
- }
490
- key() {
491
- for (const child of this.syntax.children()) {
492
- if (!(child instanceof SyntaxNode)) {
493
- if (child.kind === "Colon") break;
494
- continue;
495
- }
496
- return IdentifierAst.cast(child);
497
- }
498
- }
499
- /**
500
- * The field's logical key name, unquoted. An identifier key (`length:`) yields
501
- * its text; a string-literal key (`"length":`) yields the decoded string.
502
- * `undefined` when the field carries no key node.
503
- */
504
- keyName() {
505
- for (const child of this.syntax.children()) {
506
- if (!(child instanceof SyntaxNode)) {
507
- if (child.kind === "Colon") break;
508
- continue;
509
- }
510
- const identifier = IdentifierAst.cast(child);
511
- if (identifier) return identifier.token()?.text;
512
- const stringKey = StringLiteralExprAst.cast(child);
513
- if (stringKey) return stringKey.value();
514
- return;
515
- }
516
- }
517
- colon() {
518
- return findChildToken(this.syntax, "Colon");
519
- }
520
- value() {
521
- if (this.colon()) {
522
- let pastColon = false;
523
- for (const child of this.syntax.children()) {
524
- if (!(child instanceof SyntaxNode)) {
525
- if (child.kind === "Colon") pastColon = true;
526
- continue;
527
- }
528
- if (pastColon) {
529
- const expr = castExpression(child);
530
- if (expr) return expr;
531
- }
532
- }
533
- return;
534
- }
535
- return findFirstChild(this.syntax, castExpression);
536
- }
537
- static cast(node) {
538
- return node.kind === "ObjectField" ? new ObjectFieldAst(node) : void 0;
539
- }
540
- };
541
- function castExpression(node) {
542
- return FunctionCallAst.cast(node) ?? ArrayLiteralAst.cast(node) ?? StringLiteralExprAst.cast(node) ?? NumberLiteralExprAst.cast(node) ?? BooleanLiteralExprAst.cast(node) ?? ObjectLiteralExprAst.cast(node) ?? IdentifierAst.cast(node);
543
- }
544
- var AttributeArgAst = class AttributeArgAst {
545
- syntax;
546
- constructor(syntax) {
547
- this.syntax = syntax;
548
- }
549
- name() {
550
- if (!this.colon()) return void 0;
551
- return findFirstChild(this.syntax, IdentifierAst.cast);
552
- }
553
- colon() {
554
- return findChildToken(this.syntax, "Colon");
555
- }
556
- value() {
557
- if (this.colon()) {
558
- let pastColon = false;
559
- for (const child of this.syntax.children()) {
560
- if (!(child instanceof SyntaxNode)) {
561
- if (child.kind === "Colon") pastColon = true;
562
- continue;
563
- }
564
- if (pastColon) {
565
- const expr = castExpression(child);
566
- if (expr) return expr;
567
- }
568
- }
569
- return;
570
- }
571
- return findFirstChild(this.syntax, castExpression);
572
- }
573
- static cast(node) {
574
- return node.kind === "AttributeArg" ? new AttributeArgAst(node) : void 0;
575
- }
576
- };
577
- //#endregion
578
- //#region src/syntax/ast/attributes.ts
579
- var AttributeArgListAst = class AttributeArgListAst {
580
- syntax;
581
- constructor(syntax) {
582
- this.syntax = syntax;
583
- }
584
- lparen() {
585
- return findChildToken(this.syntax, "LParen");
586
- }
587
- rparen() {
588
- return findChildToken(this.syntax, "RParen");
589
- }
590
- *args() {
591
- yield* filterChildren(this.syntax, AttributeArgAst.cast);
592
- }
593
- static cast(node) {
594
- return node.kind === "AttributeArgList" ? new AttributeArgListAst(node) : void 0;
595
- }
596
- };
597
- var FieldAttributeAst = class FieldAttributeAst {
598
- syntax;
599
- constructor(syntax) {
600
- this.syntax = syntax;
601
- }
602
- at() {
603
- return findChildToken(this.syntax, "At");
604
- }
605
- name() {
606
- return findFirstChild(this.syntax, QualifiedNameAst.cast);
607
- }
608
- argList() {
609
- return findFirstChild(this.syntax, AttributeArgListAst.cast);
610
- }
611
- static cast(node) {
612
- return node.kind === "FieldAttribute" ? new FieldAttributeAst(node) : void 0;
613
- }
614
- };
615
- var ModelAttributeAst = class ModelAttributeAst {
616
- syntax;
617
- constructor(syntax) {
618
- this.syntax = syntax;
619
- }
620
- doubleAt() {
621
- return findChildToken(this.syntax, "DoubleAt");
622
- }
623
- name() {
624
- return findFirstChild(this.syntax, QualifiedNameAst.cast);
625
- }
626
- argList() {
627
- return findFirstChild(this.syntax, AttributeArgListAst.cast);
628
- }
629
- static cast(node) {
630
- return node.kind === "ModelAttribute" ? new ModelAttributeAst(node) : void 0;
631
- }
632
- };
633
- //#endregion
634
- //#region src/syntax/ast/type-annotation.ts
635
- var TypeAnnotationAst = class TypeAnnotationAst {
636
- syntax;
637
- constructor(syntax) {
638
- this.syntax = syntax;
639
- }
640
- /** The annotation's reference, doubling as the constructor callee when an {@link argList} follows. */
641
- name() {
642
- return findFirstChild(this.syntax, QualifiedNameAst.cast);
643
- }
644
- /** Present when the annotation is a constructor (`Vector(1536)`) rather than a plain reference. */
645
- argList() {
646
- return findFirstChild(this.syntax, AttributeArgListAst.cast);
647
- }
648
- isConstructor() {
649
- return this.argList() !== void 0;
650
- }
651
- lbracket() {
652
- return findChildToken(this.syntax, "LBracket");
653
- }
654
- rbracket() {
655
- return findChildToken(this.syntax, "RBracket");
656
- }
657
- questionMark() {
658
- return findChildToken(this.syntax, "Question");
659
- }
660
- isList() {
661
- return this.lbracket() !== void 0;
662
- }
663
- isOptional() {
664
- return this.questionMark() !== void 0;
665
- }
666
- static cast(node) {
667
- return node.kind === "TypeAnnotation" ? new TypeAnnotationAst(node) : void 0;
668
- }
669
- };
670
- //#endregion
671
- //#region src/syntax/ast/declarations.ts
672
- function castNamespaceMember(node) {
673
- return ModelDeclarationAst.cast(node) ?? CompositeTypeDeclarationAst.cast(node) ?? GenericBlockDeclarationAst.cast(node);
674
- }
675
- var DocumentAst = class DocumentAst {
676
- syntax;
677
- constructor(syntax) {
678
- this.syntax = syntax;
679
- }
680
- *declarations() {
681
- yield* filterChildren(this.syntax, (node) => castNamespaceMember(node) ?? TypesBlockAst.cast(node) ?? NamespaceDeclarationAst.cast(node));
682
- }
683
- static cast(node) {
684
- return node.kind === "Document" ? new DocumentAst(node) : void 0;
685
- }
686
- };
687
- var ModelDeclarationAst = class ModelDeclarationAst {
688
- syntax;
689
- constructor(syntax) {
690
- this.syntax = syntax;
691
- }
692
- keyword() {
693
- return findChildToken(this.syntax, "Ident");
694
- }
695
- name() {
696
- return findFirstChild(this.syntax, IdentifierAst.cast);
697
- }
698
- lbrace() {
699
- return findChildToken(this.syntax, "LBrace");
700
- }
701
- rbrace() {
702
- return findChildToken(this.syntax, "RBrace");
703
- }
704
- *fields() {
705
- yield* filterChildren(this.syntax, FieldDeclarationAst.cast);
706
- }
707
- *attributes() {
708
- yield* filterChildren(this.syntax, ModelAttributeAst.cast);
709
- }
710
- static cast(node) {
711
- return node.kind === "ModelDeclaration" ? new ModelDeclarationAst(node) : void 0;
712
- }
713
- };
714
- var CompositeTypeDeclarationAst = class CompositeTypeDeclarationAst {
715
- syntax;
716
- constructor(syntax) {
717
- this.syntax = syntax;
718
- }
719
- keyword() {
720
- return findChildToken(this.syntax, "Ident");
721
- }
722
- name() {
723
- return findFirstChild(this.syntax, IdentifierAst.cast);
724
- }
725
- lbrace() {
726
- return findChildToken(this.syntax, "LBrace");
727
- }
728
- rbrace() {
729
- return findChildToken(this.syntax, "RBrace");
730
- }
731
- *fields() {
732
- yield* filterChildren(this.syntax, FieldDeclarationAst.cast);
733
- }
734
- *attributes() {
735
- yield* filterChildren(this.syntax, ModelAttributeAst.cast);
736
- }
737
- static cast(node) {
738
- return node.kind === "CompositeTypeDeclaration" ? new CompositeTypeDeclarationAst(node) : void 0;
739
- }
740
- };
741
- var NamespaceDeclarationAst = class NamespaceDeclarationAst {
742
- syntax;
743
- constructor(syntax) {
744
- this.syntax = syntax;
745
- }
746
- keyword() {
747
- return findChildToken(this.syntax, "Ident");
748
- }
749
- name() {
750
- return findFirstChild(this.syntax, IdentifierAst.cast);
751
- }
752
- lbrace() {
753
- return findChildToken(this.syntax, "LBrace");
754
- }
755
- rbrace() {
756
- return findChildToken(this.syntax, "RBrace");
757
- }
758
- *declarations() {
759
- yield* filterChildren(this.syntax, castNamespaceMember);
760
- }
761
- static cast(node) {
762
- return node.kind === "Namespace" ? new NamespaceDeclarationAst(node) : void 0;
763
- }
764
- };
765
- var TypesBlockAst = class TypesBlockAst {
766
- syntax;
767
- constructor(syntax) {
768
- this.syntax = syntax;
769
- }
770
- keyword() {
771
- return findChildToken(this.syntax, "Ident");
772
- }
773
- lbrace() {
774
- return findChildToken(this.syntax, "LBrace");
775
- }
776
- rbrace() {
777
- return findChildToken(this.syntax, "RBrace");
778
- }
779
- *declarations() {
780
- yield* filterChildren(this.syntax, NamedTypeDeclarationAst.cast);
781
- }
782
- static cast(node) {
783
- return node.kind === "TypesBlock" ? new TypesBlockAst(node) : void 0;
784
- }
785
- };
786
- var GenericBlockDeclarationAst = class GenericBlockDeclarationAst {
787
- syntax;
788
- constructor(syntax) {
789
- this.syntax = syntax;
790
- }
791
- keyword() {
792
- return findChildToken(this.syntax, "Ident");
793
- }
794
- name() {
795
- return findFirstChild(this.syntax, IdentifierAst.cast);
796
- }
797
- lbrace() {
798
- return findChildToken(this.syntax, "LBrace");
799
- }
800
- rbrace() {
801
- return findChildToken(this.syntax, "RBrace");
802
- }
803
- *entries() {
804
- yield* filterChildren(this.syntax, KeyValuePairAst.cast);
805
- }
806
- *attributes() {
807
- yield* filterChildren(this.syntax, ModelAttributeAst.cast);
808
- }
809
- static cast(node) {
810
- return node.kind === "GenericBlockDeclaration" ? new GenericBlockDeclarationAst(node) : void 0;
811
- }
812
- };
813
- var KeyValuePairAst = class KeyValuePairAst {
814
- syntax;
815
- constructor(syntax) {
816
- this.syntax = syntax;
817
- }
818
- key() {
819
- return findFirstChild(this.syntax, IdentifierAst.cast);
820
- }
821
- equals() {
822
- return findChildToken(this.syntax, "Equals");
823
- }
824
- value() {
825
- let pastEquals = false;
826
- for (const child of this.syntax.children()) {
827
- if (!(child instanceof SyntaxNode)) {
828
- if (child.kind === "Equals") pastEquals = true;
829
- continue;
830
- }
831
- if (pastEquals) {
832
- const expr = castExpression(child);
833
- if (expr) return expr;
834
- }
835
- }
836
- }
837
- static cast(node) {
838
- return node.kind === "KeyValuePair" ? new KeyValuePairAst(node) : void 0;
839
- }
840
- };
841
- var FieldDeclarationAst = class FieldDeclarationAst {
842
- syntax;
843
- constructor(syntax) {
844
- this.syntax = syntax;
845
- }
846
- name() {
847
- return findFirstChild(this.syntax, IdentifierAst.cast);
848
- }
849
- typeAnnotation() {
850
- return findFirstChild(this.syntax, TypeAnnotationAst.cast);
851
- }
852
- *attributes() {
853
- yield* filterChildren(this.syntax, FieldAttributeAst.cast);
854
- }
855
- static cast(node) {
856
- return node.kind === "FieldDeclaration" ? new FieldDeclarationAst(node) : void 0;
857
- }
858
- };
859
- var NamedTypeDeclarationAst = class NamedTypeDeclarationAst {
860
- syntax;
861
- constructor(syntax) {
862
- this.syntax = syntax;
863
- }
864
- name() {
865
- return findFirstChild(this.syntax, IdentifierAst.cast);
866
- }
867
- equals() {
868
- return findChildToken(this.syntax, "Equals");
869
- }
870
- typeAnnotation() {
871
- return findFirstChild(this.syntax, TypeAnnotationAst.cast);
872
- }
873
- *attributes() {
874
- yield* filterChildren(this.syntax, FieldAttributeAst.cast);
875
- }
876
- static cast(node) {
877
- return node.kind === "NamedTypeDeclaration" ? new NamedTypeDeclarationAst(node) : void 0;
878
- }
879
- };
880
- //#endregion
881
- //#region src/syntax/green.ts
882
- function greenToken(kind, text) {
883
- return {
884
- type: "token",
885
- kind,
886
- text
887
- };
888
- }
889
- function greenNode(kind, children) {
890
- let textLength = 0;
891
- for (const child of children) textLength += child.type === "token" ? child.text.length : child.textLength;
892
- return {
893
- type: "node",
894
- kind,
895
- children,
896
- textLength
897
- };
898
- }
899
- //#endregion
900
- //#region src/syntax/green-builder.ts
901
- var GreenNodeBuilder = class {
902
- #stack = [];
903
- startNode(kind) {
904
- this.#stack.push({
905
- kind,
906
- children: []
907
- });
908
- }
909
- token(kind, text) {
910
- const current = this.#stack.at(-1);
911
- if (!current) throw new Error("GreenNodeBuilder: token() called with no open node");
912
- current.children.push(greenToken(kind, text));
913
- }
914
- finishNode() {
915
- const completed = this.#stack.pop();
916
- if (!completed) throw new Error("GreenNodeBuilder: finishNode() called with no open node");
917
- const node = greenNode(completed.kind, completed.children);
918
- const parent = this.#stack.at(-1);
919
- if (parent) parent.children.push(node);
920
- return node;
921
- }
922
- };
923
- //#endregion
924
- //#region src/parse.ts
925
- const TRIVIA_KINDS = new Set([
926
- "Whitespace",
927
- "Newline",
928
- "Comment"
929
- ]);
930
- /**
931
- * The fault-tolerant parser substrate the grammars drive. Trivia is flushed
932
- * into the enclosing open node, so every child node spans exactly its first
933
- * through last significant token.
934
- */
935
- var Cursor = class {
936
- #tokenizer;
937
- #sourceFile;
938
- #builder = new GreenNodeBuilder();
939
- #diagnostics = [];
940
- #offset = 0;
941
- #depth = 0;
942
- constructor(source) {
943
- this.#tokenizer = new Tokenizer(source);
944
- this.#sourceFile = new SourceFile(source);
945
- }
946
- get diagnostics() {
947
- return this.#diagnostics;
948
- }
949
- get sourceFile() {
950
- return this.#sourceFile;
951
- }
952
- peekKind(ahead = 0) {
953
- return this.peekToken(ahead).kind;
954
- }
955
- peekToken(ahead = 0) {
956
- let rawIndex = 0;
957
- let remaining = ahead;
958
- for (;;) {
959
- const token = this.#tokenizer.peek(rawIndex);
960
- if (token.kind === "Eof") return token;
961
- if (TRIVIA_KINDS.has(token.kind)) {
962
- rawIndex++;
963
- continue;
964
- }
965
- if (remaining === 0) return token;
966
- remaining--;
967
- rawIndex++;
968
- }
969
- }
970
- /** Span of the significant token `lookahead` positions ahead (`mark(0)` = the next). */
971
- mark(lookahead = 0) {
972
- let rawIndex = 0;
973
- let offset = this.#offset;
974
- let remaining = lookahead;
975
- for (;;) {
976
- const token = this.#tokenizer.peek(rawIndex);
977
- if (token.kind === "Eof") return {
978
- offset,
979
- length: token.text.length
980
- };
981
- if (!TRIVIA_KINDS.has(token.kind) && remaining === 0) return {
982
- offset,
983
- length: token.text.length
984
- };
985
- if (!TRIVIA_KINDS.has(token.kind)) remaining--;
986
- offset += token.text.length;
987
- rawIndex++;
988
- }
989
- }
990
- /**
991
- * Zero-width mark just past the last consumed significant token — anchors an
992
- * "expected here" diagnostic, e.g. the `{` missing after a declaration's name.
993
- */
994
- markAfterLastToken() {
995
- return {
996
- offset: this.#offset,
997
- length: 0
998
- };
999
- }
1000
- startNode(kind) {
1001
- if (this.#depth > 0) this.flushTrivia();
1002
- this.#builder.startNode(kind);
1003
- this.#depth++;
1004
- }
1005
- finishNode() {
1006
- this.#depth--;
1007
- return this.#builder.finishNode();
1008
- }
1009
- bump() {
1010
- this.flushTrivia();
1011
- const token = this.#tokenizer.peek();
1012
- if (token.kind === "Eof") return token;
1013
- this.#builder.token(token.kind, token.text);
1014
- this.#advance();
1015
- return token;
1016
- }
1017
- recoverToSyncPoint() {
1018
- for (;;) {
1019
- const token = this.#tokenizer.peek();
1020
- if (token.kind === "Eof" || token.kind === "Newline" || token.kind === "RBrace") return;
1021
- this.#builder.token(token.kind, token.text);
1022
- this.#advance();
1023
- }
1024
- }
1025
- flushTrivia() {
1026
- for (;;) {
1027
- const token = this.#tokenizer.peek();
1028
- if (!TRIVIA_KINDS.has(token.kind)) return;
1029
- this.#builder.token(token.kind, token.text);
1030
- this.#advance();
1031
- }
1032
- }
1033
- diagnostic(code, message, mark) {
1034
- const start = mark.offset;
1035
- const end = start + mark.length;
1036
- this.#diagnostics.push({
1037
- code,
1038
- message,
1039
- range: {
1040
- start: this.#sourceFile.positionAt(start),
1041
- end: this.#sourceFile.positionAt(end)
1042
- }
1043
- });
1044
- }
1045
- #advance() {
1046
- this.#offset += this.#tokenizer.next().text.length;
1047
- }
1048
- };
1049
- function parseIdentifier(cursor) {
1050
- cursor.startNode("Identifier");
1051
- cursor.bump();
1052
- cursor.finishNode();
1053
- }
1054
- /**
1055
- * Returns `undefined` when the next significant token does not start a
1056
- * recognised expression, leaving recovery to the caller.
1057
- */
1058
- function parseExpression(cursor) {
1059
- return parseStringLiteralExpr(cursor) ?? parseNumberLiteralExpr(cursor) ?? parseArrayLiteral(cursor) ?? parseObjectLiteralExpr(cursor) ?? parseFunctionCall(cursor) ?? parseBooleanLiteralExpr(cursor) ?? parseIdentifierExpr(cursor);
1060
- }
1061
- function parseStringLiteralExpr(cursor) {
1062
- if (cursor.peekKind() !== "StringLiteral") return void 0;
1063
- const stringMark = cursor.mark();
1064
- const text = cursor.peekToken().text;
1065
- cursor.startNode("StringLiteralExpr");
1066
- cursor.bump();
1067
- if (!isTerminatedStringLiteral(text)) cursor.diagnostic("PSL_UNTERMINATED_STRING", "Unterminated string literal", stringMark);
1068
- return cursor.finishNode();
1069
- }
1070
- function parseNumberLiteralExpr(cursor) {
1071
- if (cursor.peekKind() !== "NumberLiteral") return void 0;
1072
- cursor.startNode("NumberLiteralExpr");
1073
- cursor.bump();
1074
- return cursor.finishNode();
1075
- }
1076
- /**
1077
- * Parses a namespace-qualified name `[space ':']? Ident ('.' Ident)*`. The
1078
- * caller guarantees a leading `Ident`.
1079
- *
1080
- * Parsing the whole chain up front lets a position decide
1081
- * constructor-vs-reference by peeking exactly one token for `(`, with no scan of
1082
- * the dotted chain's length.
1083
- */
1084
- function parseQualifiedName(cursor) {
1085
- cursor.startNode("QualifiedName");
1086
- parseIdentifier(cursor);
1087
- parseQualifiedSegments(cursor, "Colon");
1088
- parseQualifiedSegments(cursor, "Dot");
1089
- cursor.finishNode();
1090
- }
1091
- /**
1092
- * A well-formed name carries at most one colon space and one dot namespace, so
1093
- * each separator past the first of its kind reports `PSL_INVALID_QUALIFIED_NAME`.
1094
- * The separator is consumed regardless, keeping the lossless round-trip intact.
1095
- */
1096
- function parseQualifiedSegments(cursor, separator) {
1097
- let seen = 0;
1098
- while (cursor.peekKind() === separator) {
1099
- seen++;
1100
- const separatorMark = cursor.mark();
1101
- cursor.bump();
1102
- if (seen > 1) cursor.diagnostic("PSL_INVALID_QUALIFIED_NAME", "Qualified name has too many segments", separatorMark);
1103
- if (cursor.peekKind() === "Ident") parseIdentifier(cursor);
1104
- else cursor.diagnostic("PSL_INVALID_QUALIFIED_NAME", "Qualified name is missing a name after the separator", cursor.mark());
1105
- }
1106
- }
1107
- function parseBooleanLiteralExpr(cursor) {
1108
- if (cursor.peekKind() !== "Ident") return void 0;
1109
- const text = cursor.peekToken().text;
1110
- if (text !== "true" && text !== "false") return void 0;
1111
- cursor.startNode("BooleanLiteralExpr");
1112
- cursor.bump();
1113
- return cursor.finishNode();
1114
- }
1115
- function parseIdentifierExpr(cursor) {
1116
- if (cursor.peekKind() !== "Ident") return void 0;
1117
- cursor.startNode("Identifier");
1118
- cursor.bump();
1119
- return cursor.finishNode();
1120
- }
1121
- function parseArrayLiteral(cursor) {
1122
- if (cursor.peekKind() !== "LBracket") return void 0;
1123
- cursor.startNode("ArrayLiteral");
1124
- cursor.bump();
1125
- while (cursor.peekKind() !== "RBracket" && cursor.peekKind() !== "Eof") {
1126
- if (!parseExpression(cursor)) break;
1127
- if (cursor.peekKind() === "Comma") cursor.bump();
1128
- else break;
1129
- }
1130
- if (cursor.peekKind() === "RBracket") cursor.bump();
1131
- return cursor.finishNode();
1132
- }
1133
- function parseObjectLiteralExpr(cursor) {
1134
- if (cursor.peekKind() !== "LBrace") return void 0;
1135
- const braceMark = cursor.mark();
1136
- cursor.startNode("ObjectLiteralExpr");
1137
- cursor.bump();
1138
- while (cursor.peekKind() !== "RBrace" && cursor.peekKind() !== "Eof") {
1139
- parseObjectField(cursor);
1140
- if (cursor.peekKind() === "Comma") cursor.bump();
1141
- else if (cursor.peekKind() === "Ident") cursor.diagnostic("PSL_INVALID_OBJECT_LITERAL", "Expected \",\" between object-literal fields", cursor.markAfterLastToken());
1142
- else break;
1143
- }
1144
- if (cursor.peekKind() === "RBrace") cursor.bump();
1145
- else cursor.diagnostic("PSL_INVALID_OBJECT_LITERAL", "Unterminated object literal", braceMark);
1146
- return cursor.finishNode();
1147
- }
1148
- function parseObjectField(cursor) {
1149
- cursor.startNode("ObjectField");
1150
- const keyMark = cursor.mark();
1151
- const keyText = cursor.peekToken().text;
1152
- if (cursor.peekKind() === "Ident") parseIdentifier(cursor);
1153
- else if (cursor.peekKind() === "StringLiteral") parseStringLiteralExpr(cursor);
1154
- if (cursor.peekKind() === "Colon") {
1155
- cursor.bump();
1156
- if (!parseExpression(cursor)) cursor.diagnostic("PSL_INVALID_OBJECT_LITERAL", "Expected a value after \":\"", cursor.mark());
1157
- } else {
1158
- cursor.diagnostic("PSL_INVALID_OBJECT_LITERAL", `Expected ":" after "${keyText}"`, keyMark);
1159
- if (!(cursor.peekKind() === "Ident" && cursor.peekKind(1) === "Colon")) parseExpression(cursor);
1160
- }
1161
- return cursor.finishNode();
1162
- }
1163
- /**
1164
- * Whether the next tokens open a call: a bare `Ident(` or a namespace-qualified
1165
- * `Ident.Ident(`. The lookahead is deliberately bounded so a bare dotted
1166
- * reference like `a.b` is not mistaken for a call, rather than scanning an
1167
- * unbounded dotted chain ahead to find the paren.
1168
- */
1169
- function isCallAhead(cursor) {
1170
- if (cursor.peekKind() !== "Ident") return false;
1171
- if (cursor.peekKind(1) === "LParen") return true;
1172
- return cursor.peekKind(1) === "Dot" && cursor.peekKind(2) === "Ident" && cursor.peekKind(3) === "LParen";
1173
- }
1174
- /**
1175
- * Parses a function/constructor call — bare `autoincrement()` or qualified
1176
- * `temporal.updatedAt()`. Returns `undefined` unless {@link isCallAhead}
1177
- * confirms a trailing `(`, so the `parseExpression` chain falls through to the
1178
- * boolean and bare-identifier forms.
1179
- */
1180
- function parseFunctionCall(cursor) {
1181
- if (!isCallAhead(cursor)) return void 0;
1182
- cursor.startNode("FunctionCall");
1183
- parseQualifiedName(cursor);
1184
- if (cursor.peekKind() === "LParen") parseParenArgs(cursor);
1185
- return cursor.finishNode();
1186
- }
1187
- /** Parses a parenthesised, comma-separated `AttributeArg` list into the currently open node. */
1188
- function parseParenArgs(cursor) {
1189
- cursor.bump();
1190
- while (cursor.peekKind() !== "RParen" && cursor.peekKind() !== "Eof") {
1191
- parseAttributeArg(cursor);
1192
- if (cursor.peekKind() === "Comma") cursor.bump();
1193
- else break;
1194
- }
1195
- if (cursor.peekKind() === "RParen") cursor.bump();
1196
- }
1197
- function parseAttributeArg(cursor) {
1198
- cursor.startNode("AttributeArg");
1199
- if (cursor.peekKind() === "Ident" && cursor.peekKind(1) === "Colon") {
1200
- parseIdentifier(cursor);
1201
- cursor.bump();
1202
- }
1203
- parseArgValue(cursor);
1204
- return cursor.finishNode();
1205
- }
1206
- function parseArgValue(cursor) {
1207
- parseExpression(cursor);
1208
- }
1209
- function parseAttributeArgList(cursor) {
1210
- cursor.startNode("AttributeArgList");
1211
- parseParenArgs(cursor);
1212
- return cursor.finishNode();
1213
- }
1214
- function parseAttribute(cursor) {
1215
- const isBlockAttribute = cursor.peekKind() === "DoubleAt";
1216
- const attributeMark = cursor.mark();
1217
- cursor.startNode(isBlockAttribute ? "ModelAttribute" : "FieldAttribute");
1218
- cursor.bump();
1219
- if (cursor.peekKind() === "Ident") parseQualifiedName(cursor);
1220
- else cursor.diagnostic("PSL_INVALID_ATTRIBUTE_SYNTAX", "Attribute name expected", attributeMark);
1221
- if (cursor.peekKind() === "LParen") parseAttributeArgList(cursor);
1222
- return cursor.finishNode();
1223
- }
1224
- /** A type annotation: `QualifiedName (argList)? ([])? (?)?`, e.g. `pgvector.Vector(1536)[]?`. */
1225
- function parseTypeAnnotation(cursor) {
1226
- cursor.startNode("TypeAnnotation");
1227
- if (cursor.peekKind() === "Ident") {
1228
- parseQualifiedName(cursor);
1229
- if (cursor.peekKind() === "LParen") parseAttributeArgList(cursor);
1230
- }
1231
- if (cursor.peekKind() === "LBracket") {
1232
- cursor.bump();
1233
- if (cursor.peekKind() === "RBracket") cursor.bump();
1234
- }
1235
- if (cursor.peekKind() === "Question") cursor.bump();
1236
- return cursor.finishNode();
1237
- }
1238
- /**
1239
- * Parses a full PSL document. Never throws — malformed input yields diagnostics
1240
- * and a recovered tree, not an exception.
1241
- */
1242
- function parse(source) {
1243
- const cursor = new Cursor(source);
1244
- const root = createSyntaxTree(parseDocument(cursor));
1245
- return {
1246
- document: DocumentAst.cast(root) ?? new DocumentAst(root),
1247
- diagnostics: cursor.diagnostics,
1248
- sourceFile: cursor.sourceFile
1249
- };
1250
- }
1251
- function parseDocument(cursor) {
1252
- cursor.startNode("Document");
1253
- while (cursor.peekKind() !== "Eof") parseDeclaration(cursor, false);
1254
- cursor.flushTrivia();
1255
- return cursor.finishNode();
1256
- }
1257
- const RESERVED_BLOCK_KEYWORDS = new Set([
1258
- "model",
1259
- "namespace",
1260
- "type",
1261
- "types"
1262
- ]);
1263
- function keywordIs(cursor, keyword) {
1264
- return cursor.peekKind() === "Ident" && cursor.peekToken().text === keyword;
1265
- }
1266
- /**
1267
- * Each alternative is a no-op on non-match, consuming nothing, so the
1268
- * forward-only cursor is never left half-consumed by a rejected alternative.
1269
- * Recovery runs via the `if (!node)` tail rather than as a `??` arm, because it
1270
- * appends raw tokens to the open parent instead of returning a child node.
1271
- */
1272
- function parseDeclaration(cursor, insideNamespace) {
1273
- const name = cursor.peekKind(1) === "Ident" ? cursor.peekToken(1).text : "";
1274
- if (insideNamespace && keywordIs(cursor, "namespace")) cursor.diagnostic("PSL_INVALID_NAMESPACE_BLOCK", `Recursive "namespace ${name}" block is not allowed; namespace blocks may not nest`, cursor.mark());
1275
- else if (insideNamespace && keywordIs(cursor, "types")) cursor.diagnostic("PSL_INVALID_NAMESPACE_BLOCK", "`types` blocks must be declared at the document top level, not inside a namespace block", cursor.mark());
1276
- else if (keywordIs(cursor, "namespace") && name === UNSPECIFIED_PSL_NAMESPACE_ID) cursor.diagnostic("PSL_INVALID_NAMESPACE_BLOCK", `Namespace name "${UNSPECIFIED_PSL_NAMESPACE_ID}" is reserved for the parser-synthesised bucket for top-level declarations`, cursor.mark(1));
1277
- if (!(parseModel(cursor) ?? parseNamespace(cursor) ?? parseCompositeType(cursor) ?? parseTypesBlock(cursor) ?? parseGenericBlock(cursor))) parseUnsupportedTopLevel(cursor);
1278
- }
1279
- /**
1280
- * Reports only the first missing piece — a missing name suppresses the
1281
- * missing-brace diagnostic. `nameRequired` is false only for the `types` block.
1282
- */
1283
- function parseBlock(cursor, kind, nameRequired, parseMember) {
1284
- const keyword = cursor.peekToken().text;
1285
- const keywordMark = cursor.mark();
1286
- cursor.startNode(kind);
1287
- cursor.bump();
1288
- const hasName = nameRequired && cursor.peekKind() === "Ident";
1289
- if (hasName) parseIdentifier(cursor);
1290
- if (nameRequired && !hasName) cursor.diagnostic("PSL_INVALID_DECLARATION", `Expected a name after "${keyword}"`, keywordMark);
1291
- else if (cursor.peekKind() !== "LBrace") cursor.diagnostic("PSL_INVALID_DECLARATION", `Expected "{" to open the "${keyword}" block`, cursor.markAfterLastToken());
1292
- if (cursor.peekKind() === "LBrace") parseBlockBody(cursor, parseMember);
1293
- else cursor.recoverToSyncPoint();
1294
- return cursor.finishNode();
1295
- }
1296
- function parseModel(cursor) {
1297
- if (!keywordIs(cursor, "model")) return void 0;
1298
- return parseBlock(cursor, "ModelDeclaration", true, parseModelMember);
1299
- }
1300
- /**
1301
- * Excluding the reserved keywords keeps a malformed reserved block (e.g. `model
1302
- * {` with no name) routed to its dedicated parser. The generic keyword set is
1303
- * open, so a bare identifier with no brace (e.g. `oops`) is read as an unfinished
1304
- * custom declaration rather than unsupported content.
1305
- */
1306
- function parseGenericBlock(cursor) {
1307
- if (cursor.peekKind() !== "Ident") return void 0;
1308
- const keyword = cursor.peekToken().text;
1309
- if (RESERVED_BLOCK_KEYWORDS.has(keyword)) return void 0;
1310
- const hasName = cursor.peekKind(1) === "Ident" && cursor.peekKind(2) === "LBrace";
1311
- cursor.startNode("GenericBlockDeclaration");
1312
- cursor.bump();
1313
- if (hasName) parseIdentifier(cursor);
1314
- if (cursor.peekKind() === "LBrace") parseBlockBody(cursor, parseKeyValueMember);
1315
- else {
1316
- cursor.diagnostic("PSL_INVALID_DECLARATION", `Expected "{" to open the "${keyword}" block`, cursor.markAfterLastToken());
1317
- cursor.recoverToSyncPoint();
1318
- }
1319
- return cursor.finishNode();
1320
- }
1321
- function parseNamespace(cursor) {
1322
- if (!keywordIs(cursor, "namespace")) return void 0;
1323
- return parseBlock(cursor, "Namespace", true, (inner) => parseDeclaration(inner, true));
1324
- }
1325
- function parseCompositeType(cursor) {
1326
- if (!keywordIs(cursor, "type")) return void 0;
1327
- return parseBlock(cursor, "CompositeTypeDeclaration", true, parseModelMember);
1328
- }
1329
- /** `types` (plural) is the no-name types block; the singular `type` is the composite type above. */
1330
- function parseTypesBlock(cursor) {
1331
- if (!keywordIs(cursor, "types")) return void 0;
1332
- return parseBlock(cursor, "TypesBlock", false, parseNamedTypeMember);
1333
- }
1334
- /** Every `parseMember` consumes at least one significant token, so the loop always terminates. */
1335
- function parseBlockBody(cursor, parseMember) {
1336
- const braceMark = cursor.mark();
1337
- cursor.bump();
1338
- for (;;) {
1339
- const kind = cursor.peekKind();
1340
- if (kind === "RBrace" || kind === "Eof") break;
1341
- parseMember(cursor);
1342
- }
1343
- if (cursor.peekKind() === "RBrace") cursor.bump();
1344
- else cursor.diagnostic("PSL_UNTERMINATED_BLOCK", "Unterminated block declaration", braceMark);
1345
- }
1346
- function parseUnsupportedTopLevel(cursor) {
1347
- const offending = cursor.peekToken().text;
1348
- const message = cursor.peekKind(1) === "LBrace" ? `Unsupported top-level block "${offending}"` : `Unsupported top-level declaration "${offending}"`;
1349
- cursor.diagnostic("PSL_UNSUPPORTED_TOP_LEVEL_BLOCK", message, cursor.mark());
1350
- cursor.bump();
1351
- cursor.recoverToSyncPoint();
1352
- }
1353
- /**
1354
- * Matches a leading `@@` block attribute, a no-op otherwise. Single-`@`
1355
- * attributes belong to fields and are parsed inside `parseField`.
1356
- */
1357
- function parseBlockAttribute(cursor) {
1358
- if (cursor.peekKind() !== "DoubleAt") return void 0;
1359
- return parseAttribute(cursor);
1360
- }
1361
- function parseModelMember(cursor) {
1362
- if (!(parseBlockAttribute(cursor) ?? parseField(cursor))) invalidMember(cursor, "PSL_INVALID_MODEL_MEMBER", `Invalid model member declaration "${cursor.peekToken().text}"`);
1363
- }
1364
- function parseNamedTypeMember(cursor) {
1365
- if (!parseNamedType(cursor)) invalidMember(cursor, "PSL_INVALID_TYPES_MEMBER", `Invalid types declaration "${cursor.peekToken().text}"`);
1366
- }
1367
- /**
1368
- * A generic-block member is either a `@@`-block attribute or a `key = value`
1369
- * entry. The block-attribute alternative is purely syntactic — it does not judge
1370
- * whether the attribute is valid for the block's kind.
1371
- */
1372
- function parseKeyValueMember(cursor) {
1373
- if (!(parseBlockAttribute(cursor) ?? parseKeyValue(cursor))) invalidMember(cursor, "PSL_INVALID_EXTENSION_BLOCK_MEMBER", "Invalid block entry");
1374
- }
1375
- function invalidMember(cursor, code, message) {
1376
- cursor.diagnostic(code, message, cursor.mark());
1377
- cursor.bump();
1378
- cursor.recoverToSyncPoint();
1379
- }
1380
- function parseField(cursor) {
1381
- if (cursor.peekKind() !== "Ident") return void 0;
1382
- cursor.startNode("FieldDeclaration");
1383
- const nameMark = cursor.mark();
1384
- const nameText = cursor.peekToken().text;
1385
- parseIdentifier(cursor);
1386
- if (cursor.peekKind() !== "Ident") cursor.diagnostic("PSL_INVALID_MODEL_MEMBER", `Expected a type after field "${nameText}"`, nameMark);
1387
- parseTypeAnnotation(cursor);
1388
- while (cursor.peekKind() === "At") parseAttribute(cursor);
1389
- return cursor.finishNode();
1390
- }
1391
- function parseNamedType(cursor) {
1392
- if (cursor.peekKind() !== "Ident") return void 0;
1393
- cursor.startNode("NamedTypeDeclaration");
1394
- const nameMark = cursor.mark();
1395
- const nameText = cursor.peekToken().text;
1396
- parseIdentifier(cursor);
1397
- if (cursor.peekKind() === "Equals") cursor.bump();
1398
- else cursor.diagnostic("PSL_INVALID_TYPES_MEMBER", `Expected "=" after "${nameText}"`, nameMark);
1399
- parseTypeAnnotation(cursor);
1400
- while (cursor.peekKind() === "At") parseAttribute(cursor);
1401
- return cursor.finishNode();
1402
- }
1403
- /**
1404
- * A generic-block entry is either `key = value` or a bare `key` (committing a
1405
- * `KeyValuePair` carrying only the key). A `key =` with no following expression
1406
- * is flagged.
1407
- */
1408
- function parseKeyValue(cursor) {
1409
- if (cursor.peekKind() !== "Ident") return void 0;
1410
- cursor.startNode("KeyValuePair");
1411
- parseIdentifier(cursor);
1412
- if (cursor.peekKind() === "Equals") {
1413
- cursor.bump();
1414
- if (!parseExpression(cursor)) cursor.diagnostic("PSL_INVALID_EXTENSION_BLOCK_MEMBER", "Expected a value after \"=\"", cursor.mark());
1415
- }
1416
- return cursor.finishNode();
1417
- }
1418
- //#endregion
1
+ import { A as findChildToken, C as ObjectFieldAst, D as QualifiedNameAst, E as castExpression, F as SourceFile, M as printSyntax, N as SyntaxNode, O as IdentifierAst, P as createSyntaxTree, S as NumberLiteralExprAst, T as StringLiteralExprAst, _ as ModelAttributeAst, a as CompositeTypeDeclarationAst, b as BooleanLiteralExprAst, c as GenericBlockDeclarationAst, d as NamedTypeDeclarationAst, f as NamespaceDeclarationAst, g as FieldAttributeAst, h as AttributeArgListAst, i as greenToken, j as findFirstChild, k as filterChildren, l as KeyValuePairAst, m as TypeAnnotationAst, n as GreenNodeBuilder, o as DocumentAst, p as TypesBlockAst, r as greenNode, s as FieldDeclarationAst, t as parse, u as ModelDeclarationAst, v as ArrayLiteralAst, w as ObjectLiteralExprAst, x as FunctionCallAst, y as AttributeArgAst } from "./parse-B_3gIEFd.mjs";
1419
2
  export { ArrayLiteralAst, AttributeArgAst, AttributeArgListAst, BooleanLiteralExprAst, CompositeTypeDeclarationAst, DocumentAst, FieldAttributeAst, FieldDeclarationAst, FunctionCallAst, GenericBlockDeclarationAst, GreenNodeBuilder, IdentifierAst, KeyValuePairAst, ModelAttributeAst, ModelDeclarationAst, NamedTypeDeclarationAst, NamespaceDeclarationAst, NumberLiteralExprAst, ObjectFieldAst, ObjectLiteralExprAst, QualifiedNameAst, SourceFile, StringLiteralExprAst, SyntaxNode, TypeAnnotationAst, TypesBlockAst, castExpression, createSyntaxTree, filterChildren, findChildToken, findFirstChild, greenNode, greenToken, parse, printSyntax };
1420
-
1421
- //# sourceMappingURL=syntax.mjs.map