@cjser/jsdoc-type-pratt-parser 9.1.1-cjser.2

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/index.mjs ADDED
@@ -0,0 +1,3091 @@
1
+ //#region src/errors.ts
2
+ function tokenToString(token) {
3
+ if (token.text !== void 0 && token.text !== "") return `'${token.type}' with value '${token.text}'`;
4
+ else return `'${token.type}'`;
5
+ }
6
+ var NoParsletFoundError = class NoParsletFoundError extends Error {
7
+ token;
8
+ constructor(token) {
9
+ super(`No parslet found for token: ${tokenToString(token)}`);
10
+ this.token = token;
11
+ Object.setPrototypeOf(this, NoParsletFoundError.prototype);
12
+ }
13
+ getToken() {
14
+ return this.token;
15
+ }
16
+ };
17
+ var EarlyEndOfParseError = class EarlyEndOfParseError extends Error {
18
+ token;
19
+ constructor(token) {
20
+ super(`The parsing ended early. The next token was: ${tokenToString(token)}`);
21
+ this.token = token;
22
+ Object.setPrototypeOf(this, EarlyEndOfParseError.prototype);
23
+ }
24
+ getToken() {
25
+ return this.token;
26
+ }
27
+ };
28
+ var UnexpectedTypeError = class UnexpectedTypeError extends Error {
29
+ constructor(result, message) {
30
+ let error = `Unexpected type: '${result.type}'.`;
31
+ if (message !== void 0) error += ` Message: ${message}`;
32
+ super(error);
33
+ Object.setPrototypeOf(this, UnexpectedTypeError.prototype);
34
+ }
35
+ };
36
+ //#endregion
37
+ //#region src/lexer/Token.ts
38
+ const baseNameTokens = [
39
+ "module",
40
+ "keyof",
41
+ "event",
42
+ "external",
43
+ "readonly",
44
+ "is",
45
+ "typeof",
46
+ "in",
47
+ "null",
48
+ "undefined",
49
+ "function",
50
+ "asserts",
51
+ "infer",
52
+ "extends",
53
+ "import"
54
+ ];
55
+ const reservedWordsAsRootTSTypes = [
56
+ "false",
57
+ "null",
58
+ "true",
59
+ "void"
60
+ ];
61
+ [...reservedWordsAsRootTSTypes];
62
+ const reservedWords$1 = {
63
+ always: [
64
+ "break",
65
+ "case",
66
+ "catch",
67
+ "class",
68
+ "const",
69
+ "continue",
70
+ "debugger",
71
+ "default",
72
+ "delete",
73
+ "do",
74
+ "else",
75
+ "export",
76
+ "extends",
77
+ "false",
78
+ "finally",
79
+ "for",
80
+ "function",
81
+ "if",
82
+ "import",
83
+ "in",
84
+ "instanceof",
85
+ "new",
86
+ "null",
87
+ "return",
88
+ "super",
89
+ "switch",
90
+ "this",
91
+ "throw",
92
+ "true",
93
+ "try",
94
+ "typeof",
95
+ "var",
96
+ "void",
97
+ "while",
98
+ "with"
99
+ ],
100
+ strictMode: [
101
+ "let",
102
+ "static",
103
+ "yield"
104
+ ],
105
+ moduleOrAsyncFunctionBodies: ["await"]
106
+ };
107
+ const futureReservedWords = {
108
+ always: ["enum"],
109
+ strictMode: [
110
+ "implements",
111
+ "interface",
112
+ "package",
113
+ "private",
114
+ "protected",
115
+ "public"
116
+ ]
117
+ };
118
+ const strictModeNonIdentifiers = ["arguments", "eval"];
119
+ //#endregion
120
+ //#region src/assertTypes.ts
121
+ function assertResultIsNotReservedWord(parser, result) {
122
+ let text;
123
+ if (result.type === "JsdocTypeName") text = result.value;
124
+ else if (result.type === "JsdocTypeParenthesis") {
125
+ let res = result;
126
+ while (res.type === "JsdocTypeParenthesis") res = res.element;
127
+ if (res.type === "JsdocTypeName") text = res.value;
128
+ else return result;
129
+ } else return result;
130
+ if (reservedWords$1.always.includes(text) && !reservedWordsAsRootTSTypes.includes(text) && (text !== "this" || parser.classContext !== true)) throw new Error(`Unexpected reserved keyword "${text}"`);
131
+ if (futureReservedWords.always.includes(text)) throw new Error(`Unexpected future reserved keyword "${text}"`);
132
+ if (parser.module !== void 0 && parser.module || parser.strictMode !== void 0 && parser.strictMode) {
133
+ if (reservedWords$1.strictMode.includes(text)) throw new Error(`Unexpected reserved keyword "${text}" for strict mode`);
134
+ if (futureReservedWords.strictMode.includes(text)) throw new Error(`Unexpected future reserved keyword "${text}" for strict mode`);
135
+ if (strictModeNonIdentifiers.includes(text)) throw new Error(`The item "${text}" is not an identifier in strict mode`);
136
+ }
137
+ if (parser.module !== void 0 && parser.module || parser.asyncFunctionBody !== void 0 && parser.asyncFunctionBody) {
138
+ if (reservedWords$1.moduleOrAsyncFunctionBodies.includes(text)) throw new Error(`Unexpected reserved keyword "${text}" for modules or async function bodies`);
139
+ }
140
+ return result;
141
+ }
142
+ /**
143
+ * Throws an error if the provided result is not a {@link RootResult}
144
+ */
145
+ function assertRootResult(result) {
146
+ if (result === void 0) throw new Error("Unexpected undefined");
147
+ if (result.type === "JsdocTypeKeyValue" || result.type === "JsdocTypeParameterList" || result.type === "JsdocTypeProperty" || result.type === "JsdocTypeReadonlyProperty" || result.type === "JsdocTypeObjectField" || result.type === "JsdocTypeJsdocObjectField" || result.type === "JsdocTypeIndexSignature" || result.type === "JsdocTypeMappedType" || result.type === "JsdocTypeTypeParameter" || result.type === "JsdocTypeCallSignature" || result.type === "JsdocTypeConstructorSignature" || result.type === "JsdocTypeMethodSignature" || result.type === "JsdocTypeIndexedAccessIndex" || result.type === "JsdocTypeComputedProperty" || result.type === "JsdocTypeComputedMethod") throw new UnexpectedTypeError(result);
148
+ return result;
149
+ }
150
+ function assertPlainKeyValueOrRootResult(result) {
151
+ if (result.type === "JsdocTypeKeyValue") return assertPlainKeyValueResult(result);
152
+ return assertRootResult(result);
153
+ }
154
+ function assertPlainKeyValueOrNameResult(result) {
155
+ if (result.type === "JsdocTypeName") return result;
156
+ return assertPlainKeyValueResult(result);
157
+ }
158
+ function assertPlainKeyValueResult(result) {
159
+ if (result.type !== "JsdocTypeKeyValue") throw new UnexpectedTypeError(result);
160
+ return result;
161
+ }
162
+ function assertNumberOrVariadicNameResult(result) {
163
+ if (result.type === "JsdocTypeVariadic") {
164
+ if (result.element?.type === "JsdocTypeName") return result;
165
+ throw new UnexpectedTypeError(result);
166
+ }
167
+ if (result.type !== "JsdocTypeNumber" && result.type !== "JsdocTypeName") throw new UnexpectedTypeError(result);
168
+ return result;
169
+ }
170
+ function assertArrayOrTupleResult(result) {
171
+ if (result.type === "JsdocTypeTuple") return result;
172
+ if (result.type === "JsdocTypeGeneric" && result.meta.brackets === "square") return result;
173
+ throw new UnexpectedTypeError(result);
174
+ }
175
+ function isSquaredProperty(result) {
176
+ return result.type === "JsdocTypeIndexSignature" || result.type === "JsdocTypeMappedType";
177
+ }
178
+ //#endregion
179
+ //#region src/Parser.ts
180
+ var Parser = class {
181
+ grammar;
182
+ _lexer;
183
+ baseParser;
184
+ externalParsers;
185
+ module;
186
+ strictMode;
187
+ asyncFunctionBody;
188
+ classContext;
189
+ rangeStart;
190
+ range;
191
+ locStart;
192
+ loc;
193
+ constructor(grammar, lexer, baseParser, { module, strictMode, asyncFunctionBody, classContext, range = false, rangeStart = 0, loc = false, locStart = {
194
+ line: 1,
195
+ column: 0
196
+ }, externalParsers } = {}) {
197
+ this.grammar = grammar;
198
+ this._lexer = lexer;
199
+ this.baseParser = baseParser;
200
+ this.externalParsers = externalParsers;
201
+ this.module = module;
202
+ this.strictMode = strictMode;
203
+ this.asyncFunctionBody = asyncFunctionBody;
204
+ this.classContext = classContext;
205
+ this.rangeStart = rangeStart;
206
+ this.range = range;
207
+ this.locStart = locStart;
208
+ this.loc = loc;
209
+ }
210
+ get lexer() {
211
+ return this._lexer;
212
+ }
213
+ /**
214
+ * Parses a given string and throws an error if the parse ended before the end of the string.
215
+ */
216
+ parse() {
217
+ const result = this.parseType(0);
218
+ if (this.lexer.current.type !== "EOF") throw new EarlyEndOfParseError(this.lexer.current);
219
+ return result;
220
+ }
221
+ /**
222
+ * Parses with the current lexer and asserts that the result is a {@link RootResult}.
223
+ */
224
+ parseType(precedence) {
225
+ return assertRootResult(this.parseIntermediateType(precedence));
226
+ }
227
+ /**
228
+ * The main parsing function. First it tries to parse the current state in the prefix step, and then it continues
229
+ * to parse the state in the infix step.
230
+ */
231
+ parseIntermediateType(precedence) {
232
+ const result = this.tryParslets(null, precedence);
233
+ if (result === null) throw new NoParsletFoundError(this.lexer.current);
234
+ return this.parseInfixIntermediateType(result, precedence);
235
+ }
236
+ /**
237
+ * In the infix parsing step the parser continues to parse the current state with all parslets until none returns
238
+ * a result.
239
+ */
240
+ parseInfixIntermediateType(left, precedence) {
241
+ let result = this.tryParslets(left, precedence);
242
+ while (result !== null) {
243
+ left = result;
244
+ result = this.tryParslets(left, precedence);
245
+ }
246
+ return left;
247
+ }
248
+ /**
249
+ * Tries to parse the current state with all parslets in the grammar and returns the first non null result.
250
+ */
251
+ tryParslets(left, precedence) {
252
+ for (const parslet of this.grammar) {
253
+ const rangeStart = this.rangeStart;
254
+ const locStartLine = this.locStart.line;
255
+ const locStartColumn = this.locStart.column;
256
+ const result = parslet(this, precedence, left);
257
+ if (result !== null) {
258
+ if (this.range) result.range = [rangeStart, this.rangeStart];
259
+ if (this.loc) result.loc = {
260
+ end: {
261
+ line: this.locStart.line,
262
+ column: this.locStart.column
263
+ },
264
+ start: {
265
+ line: locStartLine,
266
+ column: locStartColumn
267
+ }
268
+ };
269
+ return result;
270
+ }
271
+ }
272
+ return null;
273
+ }
274
+ /**
275
+ * If the given type equals the current type of the {@link Lexer} advance the lexer. Return true if the lexer was
276
+ * advanced.
277
+ */
278
+ consume(types) {
279
+ if (!Array.isArray(types)) types = [types];
280
+ if (types.includes(this.lexer.current.type)) {
281
+ if (this.range)
282
+ /* c8 ignore next -- Default is for TS */
283
+ this.rangeStart += this.lexer.current?.reduced ?? 0;
284
+ if (this.loc) {
285
+ /* c8 ignore next 4 -- Defaults are for TS */
286
+ this.locStart.line += this.lexer.current?.line ?? 0;
287
+ this.locStart.column = (this.lexer.current?.line ?? 0) > 0 ? this.lexer.current?.column ?? 0 : this.locStart.column + (this.lexer.current?.column ?? 0);
288
+ }
289
+ this._lexer = this.lexer.advance();
290
+ return true;
291
+ } else return false;
292
+ }
293
+ acceptLexerState(parser) {
294
+ this._lexer = parser.lexer;
295
+ }
296
+ };
297
+ //#endregion
298
+ //#region src/parslets/isQuestionMarkUnknownType.ts
299
+ function isQuestionMarkUnknownType(next) {
300
+ return next === "}" || next === "EOF" || next === "|" || next === "," || next === ")" || next === ">";
301
+ }
302
+ //#endregion
303
+ //#region src/parslets/NullableParslets.ts
304
+ const nullableParslet = (parser, precedence, left) => {
305
+ const type = parser.lexer.current.type;
306
+ const next = parser.lexer.next.type;
307
+ const inferSuffix = left?.type === "JsdocTypeInfer";
308
+ if (!(left === null && type === "?" && !isQuestionMarkUnknownType(next) || left !== null && !inferSuffix && type === "?" && 12 > precedence)) return null;
309
+ parser.consume("?");
310
+ if (left === null) return {
311
+ type: "JsdocTypeNullable",
312
+ element: parser.parseType(12),
313
+ meta: { position: "prefix" }
314
+ };
315
+ else return {
316
+ type: "JsdocTypeNullable",
317
+ element: assertRootResult(left),
318
+ meta: { position: "suffix" }
319
+ };
320
+ };
321
+ //#endregion
322
+ //#region src/parslets/Parslet.ts
323
+ function composeParslet(options) {
324
+ const parslet = (parser, curPrecedence, left) => {
325
+ const type = parser.lexer.current.type;
326
+ const next = parser.lexer.next.type;
327
+ if (left === null) {
328
+ if ("parsePrefix" in options) {
329
+ if (options.accept(type, next)) return options.parsePrefix(parser);
330
+ }
331
+ } else if ("parseInfix" in options) {
332
+ if (options.precedence > curPrecedence && options.accept(type, next)) return options.parseInfix(parser, left);
333
+ }
334
+ return null;
335
+ };
336
+ Object.defineProperty(parslet, "name", { value: options.name });
337
+ return parslet;
338
+ }
339
+ //#endregion
340
+ //#region src/parslets/OptionalParslet.ts
341
+ const optionalParslet = composeParslet({
342
+ name: "optionalParslet",
343
+ accept: (type) => type === "=",
344
+ precedence: 11,
345
+ parsePrefix: (parser) => {
346
+ parser.consume("=");
347
+ return {
348
+ type: "JsdocTypeOptional",
349
+ element: parser.parseType(11),
350
+ meta: { position: "prefix" }
351
+ };
352
+ },
353
+ parseInfix: (parser, left) => {
354
+ parser.consume("=");
355
+ return {
356
+ type: "JsdocTypeOptional",
357
+ element: assertRootResult(left),
358
+ meta: { position: "suffix" }
359
+ };
360
+ }
361
+ });
362
+ //#endregion
363
+ //#region src/parslets/NumberParslet.ts
364
+ const numberParslet = composeParslet({
365
+ name: "numberParslet",
366
+ accept: (type) => type === "Number",
367
+ parsePrefix: (parser) => {
368
+ const text = parser.lexer.current.text;
369
+ parser.consume("Number");
370
+ if (text.endsWith("n")) {
371
+ const bigintText = text.slice(0, -1);
372
+ return {
373
+ type: "JsdocTypeBigInt",
374
+ value: BigInt(bigintText).toString()
375
+ };
376
+ }
377
+ return {
378
+ type: "JsdocTypeNumber",
379
+ value: parseFloat(text)
380
+ };
381
+ }
382
+ });
383
+ //#endregion
384
+ //#region src/parslets/ParenthesisParslet.ts
385
+ const parenthesisParslet = composeParslet({
386
+ name: "parenthesisParslet",
387
+ accept: (type) => type === "(",
388
+ parsePrefix: (parser) => {
389
+ parser.consume("(");
390
+ if (parser.consume(")")) return {
391
+ type: "JsdocTypeParameterList",
392
+ elements: []
393
+ };
394
+ const result = parser.parseIntermediateType(0);
395
+ if (!parser.consume(")")) throw new Error("Unterminated parenthesis");
396
+ if (result.type === "JsdocTypeParameterList") return result;
397
+ else if (result.type === "JsdocTypeKeyValue") return {
398
+ type: "JsdocTypeParameterList",
399
+ elements: [result]
400
+ };
401
+ return {
402
+ type: "JsdocTypeParenthesis",
403
+ element: assertRootResult(result)
404
+ };
405
+ }
406
+ });
407
+ //#endregion
408
+ //#region src/parslets/SpecialTypesParslet.ts
409
+ const specialTypesParslet = composeParslet({
410
+ name: "specialTypesParslet",
411
+ accept: (type, next) => type === "?" && isQuestionMarkUnknownType(next) || type === "null" || type === "undefined" || type === "*",
412
+ parsePrefix: (parser) => {
413
+ if (parser.consume("null")) return { type: "JsdocTypeNull" };
414
+ if (parser.consume("undefined")) return { type: "JsdocTypeUndefined" };
415
+ if (parser.consume("*")) return { type: "JsdocTypeAny" };
416
+ if (parser.consume("?")) return { type: "JsdocTypeUnknown" };
417
+ throw new Error(`Unacceptable token: ${parser.lexer.current.text}`);
418
+ }
419
+ });
420
+ //#endregion
421
+ //#region src/parslets/NotNullableParslet.ts
422
+ const notNullableParslet = composeParslet({
423
+ name: "notNullableParslet",
424
+ accept: (type) => type === "!",
425
+ precedence: 12,
426
+ parsePrefix: (parser) => {
427
+ parser.consume("!");
428
+ return {
429
+ type: "JsdocTypeNotNullable",
430
+ element: parser.parseType(12),
431
+ meta: { position: "prefix" }
432
+ };
433
+ },
434
+ parseInfix: (parser, left) => {
435
+ parser.consume("!");
436
+ return {
437
+ type: "JsdocTypeNotNullable",
438
+ element: assertRootResult(left),
439
+ meta: { position: "suffix" }
440
+ };
441
+ }
442
+ });
443
+ //#endregion
444
+ //#region src/parslets/ParameterListParslet.ts
445
+ function createParameterListParslet({ allowTrailingComma }) {
446
+ return composeParslet({
447
+ name: "parameterListParslet",
448
+ accept: (type) => type === ",",
449
+ precedence: 1,
450
+ parseInfix: (parser, left) => {
451
+ const elements = [assertPlainKeyValueOrRootResult(left)];
452
+ parser.consume(",");
453
+ do
454
+ try {
455
+ const next = parser.parseIntermediateType(1);
456
+ elements.push(assertPlainKeyValueOrRootResult(next));
457
+ } catch (e) {
458
+ if (allowTrailingComma && e instanceof NoParsletFoundError) break;
459
+ else throw e;
460
+ }
461
+ while (parser.consume(","));
462
+ if (elements.length > 0 && elements.slice(0, -1).some((e) => e.type === "JsdocTypeVariadic")) throw new Error("Only the last parameter may be a rest parameter");
463
+ return {
464
+ type: "JsdocTypeParameterList",
465
+ elements
466
+ };
467
+ }
468
+ });
469
+ }
470
+ //#endregion
471
+ //#region src/parslets/GenericParslet.ts
472
+ const genericParslet = composeParslet({
473
+ name: "genericParslet",
474
+ accept: (type, next) => type === "<" || type === "." && next === "<",
475
+ precedence: 17,
476
+ parseInfix: (parser, left) => {
477
+ const dot = parser.consume(".");
478
+ parser.consume("<");
479
+ const elements = [];
480
+ do
481
+ if (parser.consume("infer")) {
482
+ const name = parser.parseIntermediateType(12);
483
+ if (name.type !== "JsdocTypeName") throw new UnexpectedTypeError(name, "A typescript infer always has to have a name.");
484
+ elements.push({
485
+ type: "JsdocTypeInfer",
486
+ element: name
487
+ });
488
+ } else elements.push(parser.parseType(1));
489
+ while (parser.consume(","));
490
+ if (!parser.consume(">")) throw new Error("Unterminated generic parameter list");
491
+ return {
492
+ type: "JsdocTypeGeneric",
493
+ left: assertRootResult(left),
494
+ elements,
495
+ meta: {
496
+ brackets: "angle",
497
+ dot
498
+ }
499
+ };
500
+ }
501
+ });
502
+ //#endregion
503
+ //#region src/parslets/UnionParslets.ts
504
+ const unionParslet = composeParslet({
505
+ name: "unionParslet",
506
+ accept: (type) => type === "|",
507
+ precedence: 5,
508
+ parseInfix: (parser, left) => {
509
+ parser.consume("|");
510
+ const elements = [];
511
+ do
512
+ elements.push(parser.parseType(5));
513
+ while (parser.consume("|"));
514
+ return {
515
+ type: "JsdocTypeUnion",
516
+ elements: [assertResultIsNotReservedWord(parser, assertRootResult(left)), ...elements.map((element) => assertResultIsNotReservedWord(parser, element))]
517
+ };
518
+ }
519
+ });
520
+ //#endregion
521
+ //#region src/grammars/baseGrammar.ts
522
+ const baseGrammar = [
523
+ nullableParslet,
524
+ optionalParslet,
525
+ numberParslet,
526
+ parenthesisParslet,
527
+ specialTypesParslet,
528
+ notNullableParslet,
529
+ createParameterListParslet({ allowTrailingComma: true }),
530
+ genericParslet,
531
+ unionParslet,
532
+ optionalParslet
533
+ ];
534
+ //#endregion
535
+ //#region src/parslets/NamePathParslet.ts
536
+ function createNamePathParslet({ allowSquareBracketsOnAnyType, allowJsdocNamePaths, pathGrammar }) {
537
+ return function namePathParslet(parser, precedence, left) {
538
+ if (left === null || precedence >= 18) return null;
539
+ const type = parser.lexer.current.type;
540
+ const next = parser.lexer.next.type;
541
+ if (!(type === "." && next !== "<" || type === "[" && (allowSquareBracketsOnAnyType || left.type === "JsdocTypeName") || allowJsdocNamePaths && (type === "~" || type === "#"))) return null;
542
+ let pathType;
543
+ let brackets = false;
544
+ if (parser.consume(".")) pathType = "property";
545
+ else if (parser.consume("[")) {
546
+ pathType = "property-brackets";
547
+ brackets = true;
548
+ } else if (parser.consume("~")) pathType = "inner";
549
+ else {
550
+ parser.consume("#");
551
+ pathType = "instance";
552
+ }
553
+ const pathParser = brackets && allowSquareBracketsOnAnyType ? parser : pathGrammar !== null ? new Parser(pathGrammar, parser.lexer, parser) : parser;
554
+ const parsed = pathParser.parseType(brackets && allowSquareBracketsOnAnyType ? 0 : 18);
555
+ parser.acceptLexerState(pathParser);
556
+ let right;
557
+ switch (parsed.type) {
558
+ case "JsdocTypeName":
559
+ right = {
560
+ type: "JsdocTypeProperty",
561
+ value: parsed.value,
562
+ meta: { quote: void 0 }
563
+ };
564
+ break;
565
+ case "JsdocTypeNumber":
566
+ right = {
567
+ type: "JsdocTypeProperty",
568
+ value: parsed.value.toString(10),
569
+ meta: { quote: void 0 }
570
+ };
571
+ break;
572
+ case "JsdocTypeBigInt": throw new UnexpectedTypeError(parsed, "Expecting 'JsdocTypeName', 'JsdocTypeNumber', 'JsdocStringValue' or 'JsdocTypeSpecialNamePath'");
573
+ case "JsdocTypeStringValue":
574
+ right = {
575
+ type: "JsdocTypeProperty",
576
+ value: parsed.value,
577
+ meta: { quote: parsed.meta.quote }
578
+ };
579
+ break;
580
+ case "JsdocTypeSpecialNamePath":
581
+ if (parsed.specialType === "event") right = parsed;
582
+ else throw new UnexpectedTypeError(parsed, "Type 'JsdocTypeSpecialNamePath' is only allowed with specialType 'event'");
583
+ break;
584
+ default:
585
+ if (!brackets || !allowSquareBracketsOnAnyType) throw new UnexpectedTypeError(parsed, "Expecting 'JsdocTypeName', 'JsdocTypeNumber', 'JsdocStringValue' or 'JsdocTypeSpecialNamePath'");
586
+ right = {
587
+ type: "JsdocTypeIndexedAccessIndex",
588
+ right: parsed
589
+ };
590
+ }
591
+ if (brackets && !parser.consume("]")) {
592
+ const token = parser.lexer.current;
593
+ throw new Error(`Unterminated square brackets. Next token is '${token.type}' with text '${token.text}'`);
594
+ }
595
+ return {
596
+ type: "JsdocTypeNamePath",
597
+ left: assertRootResult(left),
598
+ right,
599
+ pathType
600
+ };
601
+ };
602
+ }
603
+ //#endregion
604
+ //#region src/parslets/NameParslet.ts
605
+ function createNameParslet({ allowedAdditionalTokens }) {
606
+ return composeParslet({
607
+ name: "nameParslet",
608
+ accept: (type) => type === "Identifier" || type === "this" || type === "new" || allowedAdditionalTokens.includes(type),
609
+ parsePrefix: (parser) => {
610
+ const { type, text } = parser.lexer.current;
611
+ parser.consume(type);
612
+ return {
613
+ type: "JsdocTypeName",
614
+ value: text
615
+ };
616
+ }
617
+ });
618
+ }
619
+ //#endregion
620
+ //#region src/parslets/StringValueParslet.ts
621
+ const stringValueParslet = composeParslet({
622
+ name: "stringValueParslet",
623
+ accept: (type) => type === "StringValue",
624
+ parsePrefix: (parser) => {
625
+ const text = parser.lexer.current.text;
626
+ parser.consume("StringValue");
627
+ return {
628
+ type: "JsdocTypeStringValue",
629
+ value: text.slice(1, -1),
630
+ meta: { quote: text.startsWith("'") ? "single" : "double" }
631
+ };
632
+ }
633
+ });
634
+ //#endregion
635
+ //#region src/parslets/SpecialNamePathParslet.ts
636
+ function createSpecialNamePathParslet({ pathGrammar, allowedTypes }) {
637
+ return composeParslet({
638
+ name: "specialNamePathParslet",
639
+ accept: (type) => allowedTypes.includes(type),
640
+ parsePrefix: (parser) => {
641
+ const type = parser.lexer.current.type;
642
+ parser.consume(type);
643
+ if (!parser.consume(":")) return {
644
+ type: "JsdocTypeName",
645
+ value: type
646
+ };
647
+ let result;
648
+ let token = parser.lexer.current;
649
+ if (parser.consume("StringValue")) result = {
650
+ type: "JsdocTypeSpecialNamePath",
651
+ value: token.text.slice(1, -1),
652
+ specialType: type,
653
+ meta: { quote: token.text.startsWith("'") ? "single" : "double" }
654
+ };
655
+ else {
656
+ let value = "";
657
+ const allowed = [
658
+ "Identifier",
659
+ "@",
660
+ "/"
661
+ ];
662
+ while (allowed.some((type) => parser.consume(type))) {
663
+ value += token.text;
664
+ token = parser.lexer.current;
665
+ }
666
+ result = {
667
+ type: "JsdocTypeSpecialNamePath",
668
+ value,
669
+ specialType: type,
670
+ meta: { quote: void 0 }
671
+ };
672
+ }
673
+ const moduleParser = new Parser(pathGrammar, parser.lexer, parser);
674
+ const moduleResult = moduleParser.parseInfixIntermediateType(result, 0);
675
+ parser.acceptLexerState(moduleParser);
676
+ return assertRootResult(moduleResult);
677
+ }
678
+ });
679
+ }
680
+ //#endregion
681
+ //#region src/grammars/pathGrammar.ts
682
+ const basePathGrammar = [
683
+ createNameParslet({ allowedAdditionalTokens: ["external", "module"] }),
684
+ stringValueParslet,
685
+ numberParslet,
686
+ createNamePathParslet({
687
+ allowSquareBracketsOnAnyType: false,
688
+ allowJsdocNamePaths: true,
689
+ pathGrammar: null
690
+ })
691
+ ];
692
+ const pathGrammar = [
693
+ ...basePathGrammar,
694
+ createSpecialNamePathParslet({
695
+ allowedTypes: ["event"],
696
+ pathGrammar: basePathGrammar
697
+ }),
698
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens })
699
+ ];
700
+ //#endregion
701
+ //#region src/parslets/FunctionParslet.ts
702
+ function getParameters(value) {
703
+ let parameters;
704
+ if (value.type === "JsdocTypeParameterList") parameters = value.elements;
705
+ else if (value.type === "JsdocTypeParenthesis") parameters = [value.element];
706
+ else throw new UnexpectedTypeError(value);
707
+ return parameters.map((p) => assertPlainKeyValueOrRootResult(p));
708
+ }
709
+ function getUnnamedParameters(value) {
710
+ const parameters = getParameters(value);
711
+ if (parameters.some((p) => p.type === "JsdocTypeKeyValue")) throw new Error("No parameter should be named");
712
+ return parameters;
713
+ }
714
+ function createFunctionParslet({ allowNamedParameters, allowNoReturnType, allowWithoutParenthesis, allowNewAsFunctionKeyword }) {
715
+ return composeParslet({
716
+ name: "functionParslet",
717
+ accept: (type, next) => type === "function" || allowNewAsFunctionKeyword && type === "new" && next === "(",
718
+ parsePrefix: (parser) => {
719
+ const newKeyword = parser.consume("new");
720
+ parser.consume("function");
721
+ const hasParenthesis = parser.lexer.current.type === "(";
722
+ if (!hasParenthesis) {
723
+ if (!allowWithoutParenthesis) throw new Error("function is missing parameter list");
724
+ return {
725
+ type: "JsdocTypeName",
726
+ value: "function"
727
+ };
728
+ }
729
+ let result = {
730
+ type: "JsdocTypeFunction",
731
+ parameters: [],
732
+ arrow: false,
733
+ constructor: newKeyword,
734
+ parenthesis: hasParenthesis
735
+ };
736
+ const value = parser.parseIntermediateType(14);
737
+ if (allowNamedParameters === void 0) result.parameters = getUnnamedParameters(value);
738
+ else if (newKeyword && value.type === "JsdocTypeFunction" && value.arrow) {
739
+ result = value;
740
+ result.constructor = true;
741
+ return result;
742
+ } else {
743
+ result.parameters = getParameters(value);
744
+ for (const p of result.parameters) if (p.type === "JsdocTypeKeyValue" && !allowNamedParameters.includes(p.key)) throw new Error(`only allowed named parameters are ${allowNamedParameters.join(", ")} but got ${p.type}`);
745
+ }
746
+ if (parser.consume(":")) result.returnType = parser.parseType(7);
747
+ else if (!allowNoReturnType) throw new Error("function is missing return type");
748
+ return result;
749
+ }
750
+ });
751
+ }
752
+ //#endregion
753
+ //#region src/parslets/VariadicParslet.ts
754
+ function createVariadicParslet({ allowPostfix, allowEnclosingBrackets }) {
755
+ return composeParslet({
756
+ name: "variadicParslet",
757
+ accept: (type) => type === "...",
758
+ precedence: 7,
759
+ parsePrefix: (parser) => {
760
+ parser.consume("...");
761
+ const brackets = allowEnclosingBrackets && parser.consume("[");
762
+ try {
763
+ const element = parser.parseType(7);
764
+ if (brackets && !parser.consume("]")) throw new Error("Unterminated variadic type. Missing ']'");
765
+ return {
766
+ type: "JsdocTypeVariadic",
767
+ element: assertRootResult(element),
768
+ meta: {
769
+ position: "prefix",
770
+ squareBrackets: brackets
771
+ }
772
+ };
773
+ } catch (e) {
774
+ if (e instanceof NoParsletFoundError) {
775
+ if (brackets) throw new Error("Empty square brackets for variadic are not allowed.", { cause: e });
776
+ return {
777
+ type: "JsdocTypeVariadic",
778
+ meta: {
779
+ position: void 0,
780
+ squareBrackets: false
781
+ }
782
+ };
783
+ } else throw e;
784
+ }
785
+ },
786
+ parseInfix: allowPostfix ? (parser, left) => {
787
+ parser.consume("...");
788
+ return {
789
+ type: "JsdocTypeVariadic",
790
+ element: assertRootResult(left),
791
+ meta: {
792
+ position: "suffix",
793
+ squareBrackets: false
794
+ }
795
+ };
796
+ } : void 0
797
+ });
798
+ }
799
+ //#endregion
800
+ //#region src/parslets/SymbolParslet.ts
801
+ const symbolParslet = composeParslet({
802
+ name: "symbolParslet",
803
+ accept: (type) => type === "(",
804
+ precedence: 10,
805
+ parseInfix: (parser, left) => {
806
+ if (left.type !== "JsdocTypeName") throw new Error("Symbol expects a name on the left side. (Reacting on '(')");
807
+ parser.consume("(");
808
+ const result = {
809
+ type: "JsdocTypeSymbol",
810
+ value: left.value
811
+ };
812
+ if (!parser.consume(")")) {
813
+ result.element = assertNumberOrVariadicNameResult(parser.parseIntermediateType(10));
814
+ if (!parser.consume(")")) throw new Error("Symbol does not end after value");
815
+ }
816
+ return result;
817
+ }
818
+ });
819
+ //#endregion
820
+ //#region src/parslets/ArrayBracketsParslet.ts
821
+ const arrayBracketsParslet = composeParslet({
822
+ name: "arrayBracketsParslet",
823
+ precedence: 16,
824
+ accept: (type, next) => type === "[" && next === "]",
825
+ parseInfix: (parser, left) => {
826
+ parser.consume("[");
827
+ parser.consume("]");
828
+ return {
829
+ type: "JsdocTypeGeneric",
830
+ left: {
831
+ type: "JsdocTypeName",
832
+ value: "Array"
833
+ },
834
+ elements: [assertRootResult(left)],
835
+ meta: {
836
+ brackets: "square",
837
+ dot: false
838
+ }
839
+ };
840
+ }
841
+ });
842
+ //#endregion
843
+ //#region src/parslets/ObjectParslet.ts
844
+ function createObjectParslet({ signatureGrammar, objectFieldGrammar, allowKeyTypes }) {
845
+ return composeParslet({
846
+ name: "objectParslet",
847
+ accept: (type) => type === "{",
848
+ parsePrefix: (parser) => {
849
+ parser.consume("{");
850
+ const result = {
851
+ type: "JsdocTypeObject",
852
+ meta: { separator: "comma" },
853
+ elements: []
854
+ };
855
+ if (!parser.consume("}")) {
856
+ let separator;
857
+ const fieldParser = new Parser(objectFieldGrammar, parser.lexer, parser, parser.externalParsers?.computedPropertyParser !== void 0 ? { externalParsers: { computedPropertyParser: parser.externalParsers.computedPropertyParser } } : void 0);
858
+ while (true) {
859
+ fieldParser.acceptLexerState(parser);
860
+ let field = fieldParser.parseIntermediateType(2);
861
+ parser.acceptLexerState(fieldParser);
862
+ if (field === void 0 && allowKeyTypes) field = parser.parseIntermediateType(2);
863
+ let optional = false;
864
+ if (field.type === "JsdocTypeNullable") {
865
+ optional = true;
866
+ field = field.element;
867
+ }
868
+ if (field.type === "JsdocTypeNumber" || field.type === "JsdocTypeName" || field.type === "JsdocTypeStringValue") {
869
+ let quote;
870
+ if (field.type === "JsdocTypeStringValue") quote = field.meta.quote;
871
+ result.elements.push({
872
+ type: "JsdocTypeObjectField",
873
+ key: field.value.toString(),
874
+ right: void 0,
875
+ optional,
876
+ readonly: false,
877
+ meta: { quote }
878
+ });
879
+ } else if (signatureGrammar !== void 0 && (field.type === "JsdocTypeCallSignature" || field.type === "JsdocTypeConstructorSignature" || field.type === "JsdocTypeMethodSignature")) {
880
+ const signatureParser = new Parser([...signatureGrammar, ...parser.grammar.flatMap((grammar) => {
881
+ if (grammar.name === "keyValueParslet") return [];
882
+ return [grammar];
883
+ })], parser.lexer, parser);
884
+ signatureParser.acceptLexerState(parser);
885
+ const params = signatureParser.parseIntermediateType(2);
886
+ parser.acceptLexerState(signatureParser);
887
+ field.parameters = getParameters(params);
888
+ const returnType = parser.parseType(2);
889
+ field.returnType = returnType;
890
+ result.elements.push(field);
891
+ } else if (field.type === "JsdocTypeObjectField" || field.type === "JsdocTypeJsdocObjectField") result.elements.push(field);
892
+ else if (field.type === "JsdocTypeReadonlyProperty" && field.element.type === "JsdocTypeObjectField") {
893
+ if (typeof field.element.key === "object" && field.element.key.type === "JsdocTypeComputedMethod") throw new Error("Computed method may not be readonly");
894
+ field.element.readonly = true;
895
+ result.elements.push(field.element);
896
+ } else throw new UnexpectedTypeError(field);
897
+ if (parser.lexer.current.startOfLine) {
898
+ separator ??= "linebreak";
899
+ parser.consume(",") || parser.consume(";");
900
+ } else if (parser.consume(",")) if (parser.lexer.current.startOfLine) separator = "comma-and-linebreak";
901
+ else separator = "comma";
902
+ else if (parser.consume(";")) if (parser.lexer.current.startOfLine) separator = "semicolon-and-linebreak";
903
+ else separator = "semicolon";
904
+ else break;
905
+ if (parser.lexer.current.type === "}") break;
906
+ }
907
+ result.meta.separator = separator ?? "comma";
908
+ if ((separator ?? "").endsWith("linebreak")) result.meta.propertyIndent = " ";
909
+ if (!parser.consume("}")) throw new Error("Unterminated record type. Missing '}'");
910
+ }
911
+ return result;
912
+ }
913
+ });
914
+ }
915
+ //#endregion
916
+ //#region src/parslets/ObjectFieldParslet.ts
917
+ function createObjectFieldParslet({ allowSquaredProperties, allowKeyTypes, allowReadonly, allowOptional }) {
918
+ return composeParslet({
919
+ name: "objectFieldParslet",
920
+ precedence: 3,
921
+ accept: (type) => type === ":",
922
+ parseInfix: (parser, left) => {
923
+ let optional = false;
924
+ let readonlyProperty = false;
925
+ if (allowOptional && left.type === "JsdocTypeNullable") {
926
+ optional = true;
927
+ left = left.element;
928
+ }
929
+ if (allowReadonly && left.type === "JsdocTypeReadonlyProperty") {
930
+ readonlyProperty = true;
931
+ left = left.element;
932
+ }
933
+ if (left.type === "JsdocTypeBigInt") throw new UnexpectedTypeError(left);
934
+ /* c8 ignore next 2 -- Always has base parser? */
935
+ const parentParser = parser.baseParser ?? parser;
936
+ parentParser.acceptLexerState(parser);
937
+ if (left.type === "JsdocTypeNumber" || left.type === "JsdocTypeName" || left.type === "JsdocTypeStringValue" || isSquaredProperty(left)) {
938
+ /* c8 ignore next 3 -- Guard */
939
+ if (isSquaredProperty(left) && !allowSquaredProperties) throw new UnexpectedTypeError(left);
940
+ parentParser.consume(":");
941
+ let quote;
942
+ if (left.type === "JsdocTypeStringValue") quote = left.meta.quote;
943
+ const right = parentParser.parseType(3);
944
+ parser.acceptLexerState(parentParser);
945
+ return {
946
+ type: "JsdocTypeObjectField",
947
+ /* c8 ignore next -- Guard; not needed anymore? */
948
+ key: isSquaredProperty(left) ? left : left.value.toString(),
949
+ right,
950
+ optional,
951
+ readonly: readonlyProperty,
952
+ meta: { quote }
953
+ };
954
+ } else {
955
+ if (!allowKeyTypes) throw new UnexpectedTypeError(left);
956
+ parentParser.consume(":");
957
+ const right = parentParser.parseType(3);
958
+ parser.acceptLexerState(parentParser);
959
+ return {
960
+ type: "JsdocTypeJsdocObjectField",
961
+ left: assertRootResult(left),
962
+ right
963
+ };
964
+ }
965
+ }
966
+ });
967
+ }
968
+ //#endregion
969
+ //#region src/parslets/KeyValueParslet.ts
970
+ function createKeyValueParslet({ allowOptional, allowVariadic, acceptParameterList }) {
971
+ return composeParslet({
972
+ name: "keyValueParslet",
973
+ precedence: 3,
974
+ accept: (type) => type === ":",
975
+ parseInfix: (parser, left) => {
976
+ let optional = false;
977
+ let variadic = false;
978
+ if (allowOptional && left.type === "JsdocTypeNullable") {
979
+ optional = true;
980
+ left = left.element;
981
+ }
982
+ if (allowVariadic && left.type === "JsdocTypeVariadic" && left.element !== void 0) {
983
+ variadic = true;
984
+ left = left.element;
985
+ }
986
+ if (left.type !== "JsdocTypeName") {
987
+ if (acceptParameterList !== void 0 && left.type === "JsdocTypeParameterList") {
988
+ parser.consume(":");
989
+ return left;
990
+ }
991
+ throw new UnexpectedTypeError(left);
992
+ }
993
+ parser.consume(":");
994
+ const right = parser.parseType(3);
995
+ return {
996
+ type: "JsdocTypeKeyValue",
997
+ key: left.value,
998
+ right,
999
+ optional,
1000
+ variadic
1001
+ };
1002
+ }
1003
+ });
1004
+ }
1005
+ //#endregion
1006
+ //#region src/grammars/jsdocGrammar.ts
1007
+ const jsdocBaseGrammar = [
1008
+ ...baseGrammar,
1009
+ createFunctionParslet({
1010
+ allowWithoutParenthesis: true,
1011
+ allowNamedParameters: ["this", "new"],
1012
+ allowNoReturnType: true,
1013
+ allowNewAsFunctionKeyword: false
1014
+ }),
1015
+ stringValueParslet,
1016
+ createSpecialNamePathParslet({
1017
+ allowedTypes: [
1018
+ "module",
1019
+ "external",
1020
+ "event"
1021
+ ],
1022
+ pathGrammar
1023
+ }),
1024
+ createVariadicParslet({
1025
+ allowEnclosingBrackets: true,
1026
+ allowPostfix: true
1027
+ }),
1028
+ createNameParslet({ allowedAdditionalTokens: ["keyof"] }),
1029
+ symbolParslet,
1030
+ arrayBracketsParslet,
1031
+ createNamePathParslet({
1032
+ allowSquareBracketsOnAnyType: false,
1033
+ allowJsdocNamePaths: true,
1034
+ pathGrammar
1035
+ })
1036
+ ];
1037
+ const jsdocGrammar = [
1038
+ ...jsdocBaseGrammar,
1039
+ createObjectParslet({
1040
+ objectFieldGrammar: [
1041
+ createNameParslet({ allowedAdditionalTokens: [
1042
+ "typeof",
1043
+ "module",
1044
+ "in"
1045
+ ] }),
1046
+ createObjectFieldParslet({
1047
+ allowSquaredProperties: false,
1048
+ allowKeyTypes: true,
1049
+ allowOptional: false,
1050
+ allowReadonly: false
1051
+ }),
1052
+ ...jsdocBaseGrammar
1053
+ ],
1054
+ allowKeyTypes: true
1055
+ }),
1056
+ createKeyValueParslet({
1057
+ allowOptional: true,
1058
+ allowVariadic: true
1059
+ })
1060
+ ];
1061
+ const jsdocNameGrammar = [
1062
+ genericParslet,
1063
+ arrayBracketsParslet,
1064
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens })
1065
+ ];
1066
+ const jsdocNamePathGrammar = [
1067
+ genericParslet,
1068
+ arrayBracketsParslet,
1069
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens }),
1070
+ createNamePathParslet({
1071
+ allowSquareBracketsOnAnyType: false,
1072
+ allowJsdocNamePaths: true,
1073
+ pathGrammar
1074
+ })
1075
+ ];
1076
+ const jsdocNamePathSpecialGrammar = [createSpecialNamePathParslet({
1077
+ allowedTypes: [
1078
+ "module",
1079
+ "external",
1080
+ "event"
1081
+ ],
1082
+ pathGrammar
1083
+ }), ...jsdocNamePathGrammar];
1084
+ //#endregion
1085
+ //#region src/parslets/TypeOfParslet.ts
1086
+ const typeOfParslet = composeParslet({
1087
+ name: "typeOfParslet",
1088
+ accept: (type) => type === "typeof",
1089
+ parsePrefix: (parser) => {
1090
+ parser.consume("typeof");
1091
+ return {
1092
+ type: "JsdocTypeTypeof",
1093
+ element: parser.parseType(13)
1094
+ };
1095
+ }
1096
+ });
1097
+ //#endregion
1098
+ //#region src/grammars/closureGrammar.ts
1099
+ const objectFieldGrammar$1 = [
1100
+ createNameParslet({ allowedAdditionalTokens: [
1101
+ "typeof",
1102
+ "module",
1103
+ "keyof",
1104
+ "event",
1105
+ "external",
1106
+ "in"
1107
+ ] }),
1108
+ nullableParslet,
1109
+ optionalParslet,
1110
+ stringValueParslet,
1111
+ numberParslet,
1112
+ createObjectFieldParslet({
1113
+ allowSquaredProperties: false,
1114
+ allowKeyTypes: false,
1115
+ allowOptional: false,
1116
+ allowReadonly: false
1117
+ })
1118
+ ];
1119
+ const closureGrammar = [
1120
+ ...baseGrammar,
1121
+ createObjectParslet({
1122
+ allowKeyTypes: false,
1123
+ objectFieldGrammar: objectFieldGrammar$1
1124
+ }),
1125
+ createNameParslet({ allowedAdditionalTokens: [
1126
+ "event",
1127
+ "external",
1128
+ "in"
1129
+ ] }),
1130
+ typeOfParslet,
1131
+ createFunctionParslet({
1132
+ allowWithoutParenthesis: false,
1133
+ allowNamedParameters: ["this", "new"],
1134
+ allowNoReturnType: true,
1135
+ allowNewAsFunctionKeyword: false
1136
+ }),
1137
+ createVariadicParslet({
1138
+ allowEnclosingBrackets: false,
1139
+ allowPostfix: false
1140
+ }),
1141
+ createNameParslet({ allowedAdditionalTokens: ["keyof"] }),
1142
+ createSpecialNamePathParslet({
1143
+ allowedTypes: ["module"],
1144
+ pathGrammar
1145
+ }),
1146
+ createNamePathParslet({
1147
+ allowSquareBracketsOnAnyType: false,
1148
+ allowJsdocNamePaths: true,
1149
+ pathGrammar
1150
+ }),
1151
+ createKeyValueParslet({
1152
+ allowOptional: false,
1153
+ allowVariadic: false
1154
+ }),
1155
+ symbolParslet
1156
+ ];
1157
+ const closureNameGrammar = [
1158
+ genericParslet,
1159
+ arrayBracketsParslet,
1160
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens })
1161
+ ];
1162
+ const closureNamePathGrammar = [
1163
+ genericParslet,
1164
+ arrayBracketsParslet,
1165
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens }),
1166
+ createNamePathParslet({
1167
+ allowSquareBracketsOnAnyType: false,
1168
+ allowJsdocNamePaths: true,
1169
+ pathGrammar
1170
+ })
1171
+ ];
1172
+ const closureNamePathSpecialGrammar = [createSpecialNamePathParslet({
1173
+ allowedTypes: ["module"],
1174
+ pathGrammar
1175
+ }), ...closureNamePathGrammar];
1176
+ //#endregion
1177
+ //#region src/parslets/assertsParslet.ts
1178
+ const assertsParslet = composeParslet({
1179
+ name: "assertsParslet",
1180
+ accept: (type) => type === "asserts",
1181
+ parsePrefix: (parser) => {
1182
+ parser.consume("asserts");
1183
+ const left = parser.parseIntermediateType(10);
1184
+ if (left.type !== "JsdocTypeName") throw new UnexpectedTypeError(left, "A typescript asserts always has to have a name.");
1185
+ if (!parser.consume("is")) return {
1186
+ type: "JsdocTypeAssertsPlain",
1187
+ element: left
1188
+ };
1189
+ return {
1190
+ type: "JsdocTypeAsserts",
1191
+ left,
1192
+ right: assertRootResult(parser.parseIntermediateType(8))
1193
+ };
1194
+ }
1195
+ });
1196
+ //#endregion
1197
+ //#region src/parslets/FunctionPropertyParslet.ts
1198
+ const functionPropertyParslet = composeParslet({
1199
+ name: "functionPropertyParslet",
1200
+ accept: (type, next) => type === "new" && (next === "(" || next === "<") || type === "Identifier" && (next === "(" || next === "<") || type === "StringValue" && (next === "(" || next === "<") || type === "(" || type === "<",
1201
+ parsePrefix: (parser) => {
1202
+ let result;
1203
+ const returnType = {
1204
+ type: "JsdocTypeName",
1205
+ value: "void"
1206
+ };
1207
+ if (parser.consume("new")) result = {
1208
+ type: "JsdocTypeConstructorSignature",
1209
+ parameters: [],
1210
+ returnType
1211
+ };
1212
+ else {
1213
+ const text = parser.lexer.current.text;
1214
+ if (parser.consume("Identifier")) result = {
1215
+ type: "JsdocTypeMethodSignature",
1216
+ name: text,
1217
+ meta: { quote: void 0 },
1218
+ parameters: [],
1219
+ returnType
1220
+ };
1221
+ else {
1222
+ const text = parser.lexer.current.text;
1223
+ if (parser.consume("StringValue")) result = {
1224
+ type: "JsdocTypeMethodSignature",
1225
+ name: text.slice(1, -1),
1226
+ meta: { quote: text.startsWith("\"") ? "double" : "single" },
1227
+ parameters: [],
1228
+ returnType
1229
+ };
1230
+ else result = {
1231
+ type: "JsdocTypeCallSignature",
1232
+ parameters: [],
1233
+ returnType
1234
+ };
1235
+ }
1236
+ }
1237
+ const typeParameters = [];
1238
+ if (parser.consume("<")) {
1239
+ do {
1240
+ let defaultValue = void 0;
1241
+ let name = parser.parseIntermediateType(10);
1242
+ if (name.type === "JsdocTypeOptional") {
1243
+ name = name.element;
1244
+ defaultValue = parser.parseType(10);
1245
+ }
1246
+ if (name.type !== "JsdocTypeName") throw new UnexpectedTypeError(name);
1247
+ let constraint = void 0;
1248
+ if (parser.consume("extends")) {
1249
+ constraint = parser.parseType(10);
1250
+ if (constraint.type === "JsdocTypeOptional") {
1251
+ constraint = constraint.element;
1252
+ defaultValue = parser.parseType(10);
1253
+ }
1254
+ }
1255
+ const typeParameter = {
1256
+ type: "JsdocTypeTypeParameter",
1257
+ name
1258
+ };
1259
+ if (constraint !== void 0) typeParameter.constraint = constraint;
1260
+ if (defaultValue !== void 0) typeParameter.defaultValue = defaultValue;
1261
+ typeParameters.push(typeParameter);
1262
+ if (parser.consume(">")) break;
1263
+ } while (parser.consume(","));
1264
+ result.typeParameters = typeParameters;
1265
+ }
1266
+ /* c8 ignore next 3 -- Unreachable */
1267
+ if (!(parser.lexer.current.type === "(")) throw new Error("function property is missing parameter list");
1268
+ return result;
1269
+ }
1270
+ });
1271
+ //#endregion
1272
+ //#region src/parslets/TupleParslet.ts
1273
+ function createTupleParslet({ allowQuestionMark }) {
1274
+ return composeParslet({
1275
+ name: "tupleParslet",
1276
+ accept: (type) => type === "[",
1277
+ parsePrefix: (parser) => {
1278
+ parser.consume("[");
1279
+ const result = {
1280
+ type: "JsdocTypeTuple",
1281
+ elements: []
1282
+ };
1283
+ if (parser.consume("]")) return result;
1284
+ const typeList = parser.parseIntermediateType(0);
1285
+ if (typeList.type === "JsdocTypeParameterList") if (typeList.elements[0].type === "JsdocTypeKeyValue") result.elements = typeList.elements.map(assertPlainKeyValueResult);
1286
+ else result.elements = typeList.elements.map(assertRootResult);
1287
+ else if (typeList.type === "JsdocTypeKeyValue") result.elements = [assertPlainKeyValueResult(typeList)];
1288
+ else result.elements = [assertRootResult(typeList)];
1289
+ if (!parser.consume("]")) throw new Error("Unterminated '['");
1290
+ if (!allowQuestionMark && result.elements.some((e) => e.type === "JsdocTypeUnknown")) throw new Error("Question mark in tuple not allowed");
1291
+ return result;
1292
+ }
1293
+ });
1294
+ }
1295
+ //#endregion
1296
+ //#region src/parslets/KeyOfParslet.ts
1297
+ const keyOfParslet = composeParslet({
1298
+ name: "keyOfParslet",
1299
+ accept: (type) => type === "keyof",
1300
+ parsePrefix: (parser) => {
1301
+ parser.consume("keyof");
1302
+ return {
1303
+ type: "JsdocTypeKeyof",
1304
+ element: assertRootResult(parser.parseType(13))
1305
+ };
1306
+ }
1307
+ });
1308
+ //#endregion
1309
+ //#region src/parslets/InferParslet.ts
1310
+ const inferParslet = composeParslet({
1311
+ name: "inferParslet",
1312
+ accept: (type) => type === "infer",
1313
+ parsePrefix: (parser) => {
1314
+ parser.consume("infer");
1315
+ const element = parser.parseIntermediateType(12);
1316
+ if (element.type !== "JsdocTypeName") throw new UnexpectedTypeError(element, "A typescript infer always has to have a name.");
1317
+ return {
1318
+ type: "JsdocTypeInfer",
1319
+ element
1320
+ };
1321
+ }
1322
+ });
1323
+ //#endregion
1324
+ //#region src/parslets/ImportParslet.ts
1325
+ const importParslet = composeParslet({
1326
+ name: "importParslet",
1327
+ accept: (type) => type === "import",
1328
+ parsePrefix: (parser) => {
1329
+ parser.consume("import");
1330
+ if (!parser.consume("(")) throw new Error("Missing parenthesis after import keyword");
1331
+ const path = parser.parseType(7);
1332
+ if (path.type !== "JsdocTypeStringValue") throw new Error("Only string values are allowed as paths for imports");
1333
+ if (!parser.consume(")")) throw new Error("Missing closing parenthesis after import keyword");
1334
+ return {
1335
+ type: "JsdocTypeImport",
1336
+ element: path
1337
+ };
1338
+ }
1339
+ });
1340
+ //#endregion
1341
+ //#region src/parslets/ReadonlyPropertyParslet.ts
1342
+ const readonlyPropertyParslet = composeParslet({
1343
+ name: "readonlyPropertyParslet",
1344
+ accept: (type, next) => type === "readonly" && next !== ":" && next !== "?",
1345
+ parsePrefix: (parser) => {
1346
+ parser.consume("readonly");
1347
+ return {
1348
+ type: "JsdocTypeReadonlyProperty",
1349
+ element: parser.parseIntermediateType(3)
1350
+ };
1351
+ }
1352
+ });
1353
+ //#endregion
1354
+ //#region src/parslets/ArrowFunctionParslet.ts
1355
+ const arrowFunctionParslet = composeParslet({
1356
+ name: "arrowFunctionParslet",
1357
+ precedence: 15,
1358
+ accept: (type) => type === "=>",
1359
+ parseInfix: (parser, left) => {
1360
+ parser.consume("=>");
1361
+ return {
1362
+ type: "JsdocTypeFunction",
1363
+ parameters: getParameters(left).map(assertPlainKeyValueOrNameResult),
1364
+ arrow: true,
1365
+ constructor: false,
1366
+ parenthesis: true,
1367
+ returnType: parser.parseType(2)
1368
+ };
1369
+ }
1370
+ });
1371
+ //#endregion
1372
+ //#region src/parslets/GenericArrowFunctionParslet.ts
1373
+ const genericArrowFunctionParslet = composeParslet({
1374
+ name: "genericArrowFunctionParslet",
1375
+ accept: (type) => type === "<",
1376
+ parsePrefix: (parser) => {
1377
+ const typeParameters = [];
1378
+ parser.consume("<");
1379
+ do {
1380
+ let defaultValue = void 0;
1381
+ let name = parser.parseIntermediateType(10);
1382
+ if (name.type === "JsdocTypeOptional") {
1383
+ name = name.element;
1384
+ defaultValue = parser.parseType(10);
1385
+ }
1386
+ if (name.type !== "JsdocTypeName") throw new UnexpectedTypeError(name);
1387
+ let constraint = void 0;
1388
+ if (parser.consume("extends")) {
1389
+ constraint = parser.parseType(10);
1390
+ if (constraint.type === "JsdocTypeOptional") {
1391
+ constraint = constraint.element;
1392
+ defaultValue = parser.parseType(10);
1393
+ }
1394
+ }
1395
+ const typeParameter = {
1396
+ type: "JsdocTypeTypeParameter",
1397
+ name
1398
+ };
1399
+ if (constraint !== void 0) typeParameter.constraint = constraint;
1400
+ if (defaultValue !== void 0) typeParameter.defaultValue = defaultValue;
1401
+ typeParameters.push(typeParameter);
1402
+ if (parser.consume(">")) break;
1403
+ } while (parser.consume(","));
1404
+ const functionBase = parser.parseIntermediateType(10);
1405
+ functionBase.typeParameters = typeParameters;
1406
+ return functionBase;
1407
+ }
1408
+ });
1409
+ //#endregion
1410
+ //#region src/parslets/IntersectionParslet.ts
1411
+ const intersectionParslet = composeParslet({
1412
+ name: "intersectionParslet",
1413
+ accept: (type) => type === "&",
1414
+ precedence: 6,
1415
+ parseInfix: (parser, left) => {
1416
+ parser.consume("&");
1417
+ const elements = [];
1418
+ do
1419
+ elements.push(parser.parseType(6));
1420
+ while (parser.consume("&"));
1421
+ return {
1422
+ type: "JsdocTypeIntersection",
1423
+ elements: [assertResultIsNotReservedWord(parser, assertRootResult(left)), ...elements.map((element) => assertResultIsNotReservedWord(parser, element))]
1424
+ };
1425
+ }
1426
+ });
1427
+ //#endregion
1428
+ //#region src/parslets/predicateParslet.ts
1429
+ const predicateParslet = composeParslet({
1430
+ name: "predicateParslet",
1431
+ precedence: 8,
1432
+ accept: (type) => type === "is",
1433
+ parseInfix: (parser, left) => {
1434
+ if (left.type !== "JsdocTypeName") throw new UnexpectedTypeError(left, "A typescript predicate always has to have a name on the left side.");
1435
+ parser.consume("is");
1436
+ return {
1437
+ type: "JsdocTypePredicate",
1438
+ left,
1439
+ right: assertRootResult(parser.parseIntermediateType(8))
1440
+ };
1441
+ }
1442
+ });
1443
+ //#endregion
1444
+ //#region src/lexer/Lexer.ts
1445
+ const breakingWhitespaceRegex = /^\s*\n\s*/v;
1446
+ var Lexer = class Lexer {
1447
+ text = "";
1448
+ lexerRules;
1449
+ current;
1450
+ next;
1451
+ previous;
1452
+ static create(lexerRules, text) {
1453
+ const current = this.read(lexerRules, text);
1454
+ text = current.text;
1455
+ const next = this.read(lexerRules, text);
1456
+ text = next.text;
1457
+ return new Lexer(lexerRules, text, void 0, current.token, next.token);
1458
+ }
1459
+ constructor(lexerRules, text, previous, current, next) {
1460
+ this.lexerRules = lexerRules;
1461
+ this.text = text;
1462
+ this.previous = previous;
1463
+ this.current = current;
1464
+ this.next = next;
1465
+ }
1466
+ static read(lexerRules, text, startOfLine = false) {
1467
+ startOfLine ||= breakingWhitespaceRegex.test(text);
1468
+ const start = text.length;
1469
+ const initialWhitespace = /^\s+/v.exec(text)?.[0] ?? "";
1470
+ text = text.trimStart();
1471
+ const trimmed = start - text.length;
1472
+ for (const rule of lexerRules) {
1473
+ const partial = rule(text);
1474
+ if (partial !== null) {
1475
+ const initialLines = initialWhitespace.split("\n");
1476
+ const currentLines = partial.text.split("\n");
1477
+ const token = {
1478
+ ...partial,
1479
+ startOfLine,
1480
+ reduced: trimmed + partial.text.length,
1481
+ line: initialLines.length + currentLines.length - 2,
1482
+ column: currentLines.length === 1 ? (initialLines.at(-1)?.length ?? 0) + (currentLines.at(-1)?.length ?? 0) : currentLines.at(-1)?.length ?? 0
1483
+ };
1484
+ text = text.slice(token.text.length);
1485
+ return {
1486
+ text,
1487
+ token
1488
+ };
1489
+ }
1490
+ }
1491
+ throw new Error(`Unexpected Token ${text}`);
1492
+ }
1493
+ remaining() {
1494
+ return this.next.text + this.text;
1495
+ }
1496
+ advance() {
1497
+ const next = Lexer.read(this.lexerRules, this.text);
1498
+ return new Lexer(this.lexerRules, next.text, this.current, this.next, next.token);
1499
+ }
1500
+ };
1501
+ //#endregion
1502
+ //#region src/parslets/ObjectSquaredPropertyParslet.ts
1503
+ const objectSquaredPropertyParslet = composeParslet({
1504
+ name: "objectSquarePropertyParslet",
1505
+ accept: (type) => type === "[",
1506
+ parsePrefix: (parser) => {
1507
+ if (parser.baseParser === void 0) throw new Error("Only allowed inside object grammar");
1508
+ parser.consume("[");
1509
+ let innerBracketType;
1510
+ if (parser.externalParsers?.computedPropertyParser === void 0) try {
1511
+ innerBracketType = parser.parseIntermediateType(2);
1512
+ } catch (err) {
1513
+ throw new Error("Error parsing value inside square bracketed property.", { cause: err });
1514
+ }
1515
+ let result;
1516
+ if (innerBracketType?.type === "JsdocTypeObjectField" && typeof innerBracketType.key === "string" && !innerBracketType.optional && !innerBracketType.readonly && innerBracketType.right !== void 0) {
1517
+ const key = innerBracketType.key;
1518
+ if (!parser.consume("]")) throw new Error("Unterminated square brackets");
1519
+ if (!parser.consume(":")) throw new Error("Incomplete index signature");
1520
+ const parentParser = parser.baseParser;
1521
+ parentParser.acceptLexerState(parser);
1522
+ innerBracketType.key = {
1523
+ type: "JsdocTypeIndexSignature",
1524
+ key,
1525
+ right: innerBracketType.right
1526
+ };
1527
+ innerBracketType.optional = false;
1528
+ innerBracketType.meta.quote = void 0;
1529
+ result = innerBracketType;
1530
+ const right = parentParser.parseType(4);
1531
+ result.right = right;
1532
+ parser.acceptLexerState(parentParser);
1533
+ } else if (innerBracketType?.type === "JsdocTypeName" && parser.consume("in")) {
1534
+ const parentParser = parser.baseParser;
1535
+ parentParser.acceptLexerState(parser);
1536
+ const mappedTypeRight = parentParser.parseType(4);
1537
+ if (!parentParser.consume("]")) throw new Error("Unterminated square brackets");
1538
+ const optional = parentParser.consume("?");
1539
+ if (!parentParser.consume(":")) throw new Error("Incomplete mapped type clause: missing colon");
1540
+ const right = parentParser.parseType(4);
1541
+ result = {
1542
+ type: "JsdocTypeObjectField",
1543
+ optional,
1544
+ readonly: false,
1545
+ meta: { quote: void 0 },
1546
+ key: {
1547
+ type: "JsdocTypeMappedType",
1548
+ key: innerBracketType.value,
1549
+ right: mappedTypeRight
1550
+ },
1551
+ right
1552
+ };
1553
+ parser.acceptLexerState(parentParser);
1554
+ } else {
1555
+ if (parser.externalParsers?.computedPropertyParser !== void 0) {
1556
+ let remaining = parser.lexer.current.text + parser.lexer.remaining();
1557
+ let checkingText = remaining;
1558
+ while (checkingText !== "") {
1559
+ try {
1560
+ innerBracketType = parser.externalParsers.computedPropertyParser(checkingText);
1561
+ break;
1562
+ } catch (err) {}
1563
+ checkingText = checkingText.slice(0, -1);
1564
+ }
1565
+ remaining = remaining.slice(checkingText.length);
1566
+ const remainingTextParser = new Parser(parser.grammar, Lexer.create(parser.lexer.lexerRules, remaining), parser.baseParser, { externalParsers: { computedPropertyParser: parser.externalParsers.computedPropertyParser } });
1567
+ parser.acceptLexerState(remainingTextParser);
1568
+ }
1569
+ if (!parser.consume("]")) throw new Error("Unterminated square brackets");
1570
+ let optional = parser.consume("?");
1571
+ const typeParameters = [];
1572
+ if (parser.consume("<")) do {
1573
+ let defaultValue = void 0;
1574
+ let name = parser.parseIntermediateType(10);
1575
+ if (name.type === "JsdocTypeOptional") {
1576
+ name = name.element;
1577
+ defaultValue = parser.parseType(10);
1578
+ }
1579
+ if (name.type !== "JsdocTypeName") throw new UnexpectedTypeError(name);
1580
+ let constraint = void 0;
1581
+ if (parser.consume("extends")) {
1582
+ constraint = parser.parseType(10);
1583
+ if (constraint.type === "JsdocTypeOptional") {
1584
+ constraint = constraint.element;
1585
+ defaultValue = parser.parseType(10);
1586
+ }
1587
+ }
1588
+ const typeParameter = {
1589
+ type: "JsdocTypeTypeParameter",
1590
+ name
1591
+ };
1592
+ if (constraint !== void 0) typeParameter.constraint = constraint;
1593
+ if (defaultValue !== void 0) typeParameter.defaultValue = defaultValue;
1594
+ typeParameters.push(typeParameter);
1595
+ if (parser.consume(">")) break;
1596
+ } while (parser.consume(","));
1597
+ let type;
1598
+ let key;
1599
+ const checkMiddle = () => {
1600
+ if (!optional) optional = parser.consume("?");
1601
+ };
1602
+ let right;
1603
+ if (parser.lexer.current.type === "(") {
1604
+ const signatureParser = new Parser([createKeyValueParslet({
1605
+ allowVariadic: true,
1606
+ allowOptional: true,
1607
+ acceptParameterList: true
1608
+ }), ...parser.baseParser.grammar.flatMap((grammar) => {
1609
+ if (grammar.name === "keyValueParslet") return [];
1610
+ return [grammar];
1611
+ })], parser.lexer, parser);
1612
+ signatureParser.acceptLexerState(parser);
1613
+ const params = signatureParser.parseIntermediateType(2);
1614
+ parser.acceptLexerState(signatureParser);
1615
+ const parameters = getParameters(params);
1616
+ type = "JsdocTypeComputedMethod";
1617
+ checkMiddle();
1618
+ parser.consume(":");
1619
+ const nextValue = parser.parseType(4);
1620
+ key = {
1621
+ type,
1622
+ optional,
1623
+ value: innerBracketType,
1624
+ parameters,
1625
+ returnType: nextValue
1626
+ };
1627
+ if (typeParameters.length > 0) key.typeParameters = typeParameters;
1628
+ } else {
1629
+ type = "JsdocTypeComputedProperty";
1630
+ checkMiddle();
1631
+ if (!parser.consume(":")) throw new Error("Incomplete computed property: missing colon");
1632
+ right = parser.parseType(4);
1633
+ key = {
1634
+ type,
1635
+ value: innerBracketType
1636
+ };
1637
+ }
1638
+ result = {
1639
+ type: "JsdocTypeObjectField",
1640
+ optional: type === "JsdocTypeComputedMethod" ? false : optional,
1641
+ readonly: false,
1642
+ meta: { quote: void 0 },
1643
+ key,
1644
+ right
1645
+ };
1646
+ }
1647
+ return result;
1648
+ }
1649
+ });
1650
+ //#endregion
1651
+ //#region src/parslets/ReadonlyArrayParslet.ts
1652
+ const readonlyArrayParslet = composeParslet({
1653
+ name: "readonlyArrayParslet",
1654
+ accept: (type) => type === "readonly",
1655
+ parsePrefix: (parser) => {
1656
+ parser.consume("readonly");
1657
+ return {
1658
+ type: "JsdocTypeReadonlyArray",
1659
+ element: assertArrayOrTupleResult(parser.parseIntermediateType(0))
1660
+ };
1661
+ }
1662
+ });
1663
+ //#endregion
1664
+ //#region src/parslets/ConditionalParslet.ts
1665
+ const conditionalParslet = composeParslet({
1666
+ name: "conditionalParslet",
1667
+ precedence: 8,
1668
+ accept: (type) => type === "extends",
1669
+ parseInfix: (parser, left) => {
1670
+ parser.consume("extends");
1671
+ const extendsType = assertRootResult(parser.parseType(13));
1672
+ parser.consume("?");
1673
+ const trueType = parser.parseType(8);
1674
+ parser.consume(":");
1675
+ return {
1676
+ type: "JsdocTypeConditional",
1677
+ checksType: assertRootResult(left),
1678
+ extendsType,
1679
+ trueType,
1680
+ falseType: parser.parseType(8)
1681
+ };
1682
+ }
1683
+ });
1684
+ //#endregion
1685
+ //#region src/lexer/LexerRules.ts
1686
+ function makePunctuationRule(type) {
1687
+ return (text) => {
1688
+ if (text.startsWith(type)) return {
1689
+ type,
1690
+ text: type
1691
+ };
1692
+ else return null;
1693
+ };
1694
+ }
1695
+ function getQuoted(text) {
1696
+ let position = 0;
1697
+ let char = void 0;
1698
+ const mark = text[0];
1699
+ let escaped = false;
1700
+ if (mark !== "'" && mark !== "\"") return null;
1701
+ while (position < text.length) {
1702
+ position++;
1703
+ char = text[position];
1704
+ if (!escaped && char === mark) {
1705
+ position++;
1706
+ break;
1707
+ }
1708
+ escaped = !escaped && char === "\\";
1709
+ }
1710
+ if (char !== mark) throw new Error("Unterminated String");
1711
+ return text.slice(0, position);
1712
+ }
1713
+ /**
1714
+ * Gets a full template literal (enclosed in backticks)
1715
+ */
1716
+ function getTemplateLiteral(text) {
1717
+ let position = 0;
1718
+ let char = void 0;
1719
+ const mark = text[0];
1720
+ let escaped = false;
1721
+ if (mark !== "`") return null;
1722
+ while (position < text.length) {
1723
+ position++;
1724
+ char = text[position];
1725
+ if (!escaped && char === mark) {
1726
+ position++;
1727
+ break;
1728
+ }
1729
+ escaped = !escaped && char === "\\";
1730
+ }
1731
+ if (char !== mark) throw new Error("Unterminated template literal");
1732
+ return text.slice(0, position);
1733
+ }
1734
+ /**
1735
+ * Gets the next literal (non-interpolation) portion of a text
1736
+ */
1737
+ function getTemplateLiteralLiteral(text) {
1738
+ let position = 0;
1739
+ const start = text[0];
1740
+ let escaped = false;
1741
+ if (start === "`" || start === "$" && text[1] === "{") return null;
1742
+ while (position < text.length) {
1743
+ position++;
1744
+ const char = text[position];
1745
+ if (!escaped && (char === "`" || char === "$" && text[position + 1] === "{")) break;
1746
+ escaped = !escaped && char === "\\";
1747
+ }
1748
+ return text.slice(0, position);
1749
+ }
1750
+ const identifierStartRegex = /[$_\p{ID_Start}]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/v;
1751
+ const identifierContinueRegex = /[$\p{ID_Continue}\u200C\u200D]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/v;
1752
+ const identifierContinueRegexLoose = /[$\-\p{ID_Continue}\u200C\u200D]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/v;
1753
+ function makeGetIdentifier(identifierContinueRegex) {
1754
+ return function(text) {
1755
+ let char = text[0];
1756
+ if (!identifierStartRegex.test(char)) return null;
1757
+ let position = 1;
1758
+ do {
1759
+ char = text[position];
1760
+ if (!identifierContinueRegex.test(char)) break;
1761
+ position++;
1762
+ } while (position < text.length);
1763
+ return text.slice(0, position);
1764
+ };
1765
+ }
1766
+ const bigintRegex = /^(?:-?\d+n)/v;
1767
+ const numberRegex = /^(?:-?(?:(?:\d*\.\d+|\d+)(?:[Ee][+\-]?\d+)?))/v;
1768
+ const looseNumberRegex = /^(?:NaN|-?(?:(?:\d*\.\d+|\d+)(?:[Ee][+\-]?\d+)?|Infinity))/v;
1769
+ function getGetNumber(numberRegex) {
1770
+ return function getNumber(text) {
1771
+ return numberRegex.exec(text)?.[0] ?? null;
1772
+ };
1773
+ }
1774
+ const looseIdentifierRule = (text) => {
1775
+ const value = makeGetIdentifier(identifierContinueRegexLoose)(text);
1776
+ if (value === null) return null;
1777
+ return {
1778
+ type: "Identifier",
1779
+ text: value
1780
+ };
1781
+ };
1782
+ const identifierRule = (text) => {
1783
+ const value = makeGetIdentifier(identifierContinueRegex)(text);
1784
+ if (value === null) return null;
1785
+ return {
1786
+ type: "Identifier",
1787
+ text: value
1788
+ };
1789
+ };
1790
+ function makeKeyWordRule(type) {
1791
+ return (text) => {
1792
+ if (!text.startsWith(type)) return null;
1793
+ const prepends = text[type.length];
1794
+ if (prepends !== void 0 && identifierContinueRegex.test(prepends)) return null;
1795
+ return {
1796
+ type,
1797
+ text: type
1798
+ };
1799
+ };
1800
+ }
1801
+ const stringValueRule = (text) => {
1802
+ const value = getQuoted(text);
1803
+ if (value === null) return null;
1804
+ return {
1805
+ type: "StringValue",
1806
+ text: value
1807
+ };
1808
+ };
1809
+ const templateLiteralRule = (text) => {
1810
+ const value = getTemplateLiteral(text);
1811
+ if (value === null) return null;
1812
+ return {
1813
+ type: "TemplateLiteral",
1814
+ text: value
1815
+ };
1816
+ };
1817
+ const eofRule = (text) => {
1818
+ if (text.length > 0) return null;
1819
+ return {
1820
+ type: "EOF",
1821
+ text: ""
1822
+ };
1823
+ };
1824
+ const numberRule = (text) => {
1825
+ const bigintValue = bigintRegex.exec(text)?.[0];
1826
+ if (bigintValue !== void 0) return {
1827
+ type: "Number",
1828
+ text: bigintValue
1829
+ };
1830
+ const value = getGetNumber(numberRegex)(text);
1831
+ if (value === null) return null;
1832
+ return {
1833
+ type: "Number",
1834
+ text: value
1835
+ };
1836
+ };
1837
+ const looseNumberRule = (text) => {
1838
+ const bigintValue = bigintRegex.exec(text)?.[0];
1839
+ if (bigintValue !== void 0) return {
1840
+ type: "Number",
1841
+ text: bigintValue
1842
+ };
1843
+ const value = getGetNumber(looseNumberRegex)(text);
1844
+ if (value === null) return null;
1845
+ return {
1846
+ type: "Number",
1847
+ text: value
1848
+ };
1849
+ };
1850
+ /**
1851
+ * Will be processed highest precedence first
1852
+ */
1853
+ const rules = [
1854
+ eofRule,
1855
+ makePunctuationRule("=>"),
1856
+ makePunctuationRule("("),
1857
+ makePunctuationRule(")"),
1858
+ makePunctuationRule("{"),
1859
+ makePunctuationRule("}"),
1860
+ makePunctuationRule("["),
1861
+ makePunctuationRule("]"),
1862
+ makePunctuationRule("|"),
1863
+ makePunctuationRule("&"),
1864
+ makePunctuationRule("<"),
1865
+ makePunctuationRule(">"),
1866
+ makePunctuationRule(","),
1867
+ makePunctuationRule(";"),
1868
+ makePunctuationRule("*"),
1869
+ makePunctuationRule("?"),
1870
+ makePunctuationRule("!"),
1871
+ makePunctuationRule("="),
1872
+ makePunctuationRule(":"),
1873
+ makePunctuationRule("..."),
1874
+ makePunctuationRule("."),
1875
+ makePunctuationRule("#"),
1876
+ makePunctuationRule("~"),
1877
+ makePunctuationRule("/"),
1878
+ makePunctuationRule("@"),
1879
+ makeKeyWordRule("undefined"),
1880
+ makeKeyWordRule("null"),
1881
+ makeKeyWordRule("function"),
1882
+ makeKeyWordRule("this"),
1883
+ makeKeyWordRule("new"),
1884
+ makeKeyWordRule("module"),
1885
+ makeKeyWordRule("event"),
1886
+ makeKeyWordRule("extends"),
1887
+ makeKeyWordRule("external"),
1888
+ makeKeyWordRule("infer"),
1889
+ makeKeyWordRule("typeof"),
1890
+ makeKeyWordRule("keyof"),
1891
+ makeKeyWordRule("readonly"),
1892
+ makeKeyWordRule("import"),
1893
+ makeKeyWordRule("is"),
1894
+ makeKeyWordRule("in"),
1895
+ makeKeyWordRule("asserts"),
1896
+ numberRule,
1897
+ identifierRule,
1898
+ stringValueRule,
1899
+ templateLiteralRule
1900
+ ];
1901
+ const looseRules = rules.toSpliced(-4, 2, looseNumberRule, looseIdentifierRule);
1902
+ //#endregion
1903
+ //#region src/parslets/TemplateLiteralParslet.ts
1904
+ const templateLiteralParslet = composeParslet({
1905
+ name: "templateLiteralParslet",
1906
+ accept: (type) => type === "TemplateLiteral",
1907
+ parsePrefix: (parser) => {
1908
+ const text = parser.lexer.current.text;
1909
+ parser.consume("TemplateLiteral");
1910
+ const literals = [];
1911
+ const interpolations = [];
1912
+ let currentText = text.slice(1, -1);
1913
+ const advanceLiteral = () => {
1914
+ const literal = getTemplateLiteralLiteral(currentText) ?? "";
1915
+ literals.push(literal.replace(/\\`/gv, "`"));
1916
+ currentText = currentText.slice(literal.length);
1917
+ };
1918
+ advanceLiteral();
1919
+ while (true) {
1920
+ if (currentText.startsWith("${")) {
1921
+ currentText = currentText.slice(2);
1922
+ let templateParser;
1923
+ let interpolationType;
1924
+ let snipped = currentText;
1925
+ let remnant = "";
1926
+ while (true) try {
1927
+ templateParser = new Parser(parser.grammar, Lexer.create(parser.lexer.lexerRules, snipped));
1928
+ interpolationType = templateParser.parseType(0);
1929
+ break;
1930
+ } catch (err) {
1931
+ remnant = snipped.slice(-1) + remnant;
1932
+ snipped = snipped.slice(0, -1);
1933
+ }
1934
+ interpolations.push(interpolationType);
1935
+ if (templateParser.lexer.current.text !== "}") throw new Error("unterminated interpolation");
1936
+ currentText = templateParser.lexer.remaining() + remnant;
1937
+ } else break;
1938
+ advanceLiteral();
1939
+ }
1940
+ return {
1941
+ type: "JsdocTypeTemplateLiteral",
1942
+ literals,
1943
+ interpolations
1944
+ };
1945
+ }
1946
+ });
1947
+ //#endregion
1948
+ //#region src/parslets/UniqueSymbolParslet.ts
1949
+ const uniqueSymbolParslet = (parser, _precedence, left) => {
1950
+ if (left !== null) return null;
1951
+ if (parser.lexer.current.type !== "Identifier" || parser.lexer.current.text !== "unique" || parser.lexer.next.type !== "Identifier" || parser.lexer.next.text !== "symbol") return null;
1952
+ parser.consume("Identifier");
1953
+ parser.consume("Identifier");
1954
+ return { type: "JsdocTypeUniqueSymbol" };
1955
+ };
1956
+ //#endregion
1957
+ //#region src/grammars/typescriptGrammar.ts
1958
+ const objectFieldGrammar = [
1959
+ functionPropertyParslet,
1960
+ readonlyPropertyParslet,
1961
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens }),
1962
+ nullableParslet,
1963
+ optionalParslet,
1964
+ stringValueParslet,
1965
+ numberParslet,
1966
+ createObjectFieldParslet({
1967
+ allowSquaredProperties: true,
1968
+ allowKeyTypes: false,
1969
+ allowOptional: true,
1970
+ allowReadonly: true
1971
+ }),
1972
+ objectSquaredPropertyParslet
1973
+ ];
1974
+ const typescriptGrammar = [
1975
+ ...baseGrammar,
1976
+ createObjectParslet({
1977
+ allowKeyTypes: false,
1978
+ objectFieldGrammar,
1979
+ signatureGrammar: [createKeyValueParslet({
1980
+ allowVariadic: true,
1981
+ allowOptional: true,
1982
+ acceptParameterList: true
1983
+ })]
1984
+ }),
1985
+ readonlyArrayParslet,
1986
+ typeOfParslet,
1987
+ keyOfParslet,
1988
+ inferParslet,
1989
+ importParslet,
1990
+ stringValueParslet,
1991
+ createFunctionParslet({
1992
+ allowWithoutParenthesis: true,
1993
+ allowNoReturnType: true,
1994
+ allowNamedParameters: [
1995
+ "this",
1996
+ "new",
1997
+ "args"
1998
+ ],
1999
+ allowNewAsFunctionKeyword: true
2000
+ }),
2001
+ createTupleParslet({ allowQuestionMark: false }),
2002
+ createVariadicParslet({
2003
+ allowEnclosingBrackets: false,
2004
+ allowPostfix: false
2005
+ }),
2006
+ assertsParslet,
2007
+ conditionalParslet,
2008
+ uniqueSymbolParslet,
2009
+ createNameParslet({ allowedAdditionalTokens: [
2010
+ "event",
2011
+ "external",
2012
+ "in"
2013
+ ] }),
2014
+ createSpecialNamePathParslet({
2015
+ allowedTypes: ["module"],
2016
+ pathGrammar
2017
+ }),
2018
+ arrayBracketsParslet,
2019
+ arrowFunctionParslet,
2020
+ genericArrowFunctionParslet,
2021
+ createNamePathParslet({
2022
+ allowSquareBracketsOnAnyType: true,
2023
+ allowJsdocNamePaths: false,
2024
+ pathGrammar
2025
+ }),
2026
+ intersectionParslet,
2027
+ predicateParslet,
2028
+ templateLiteralParslet,
2029
+ createKeyValueParslet({
2030
+ allowVariadic: true,
2031
+ allowOptional: true
2032
+ })
2033
+ ];
2034
+ const typescriptNameGrammar = [
2035
+ genericParslet,
2036
+ arrayBracketsParslet,
2037
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens })
2038
+ ];
2039
+ const typescriptNamePathGrammar = [
2040
+ genericParslet,
2041
+ arrayBracketsParslet,
2042
+ createNameParslet({ allowedAdditionalTokens: baseNameTokens }),
2043
+ createNamePathParslet({
2044
+ allowSquareBracketsOnAnyType: true,
2045
+ allowJsdocNamePaths: true,
2046
+ pathGrammar
2047
+ })
2048
+ ];
2049
+ const typescriptNamePathSpecialGrammar = [createSpecialNamePathParslet({
2050
+ allowedTypes: ["module"],
2051
+ pathGrammar
2052
+ }), ...typescriptNamePathGrammar];
2053
+ //#endregion
2054
+ //#region src/parse.ts
2055
+ /**
2056
+ * This function parses the given expression in the given mode and produces a {@link RootResult}.
2057
+ * @param expression
2058
+ * @param mode
2059
+ */
2060
+ function parse(expression, mode, { range = false, rangeStart, loc = false, locStart = {
2061
+ column: 0,
2062
+ line: 1
2063
+ }, module = true, strictMode = true, asyncFunctionBody = true, classContext = false, computedPropertyParser } = {}) {
2064
+ let parser;
2065
+ switch (mode) {
2066
+ case "closure":
2067
+ parser = new Parser(closureGrammar, Lexer.create(looseRules, expression), void 0, {
2068
+ module,
2069
+ strictMode,
2070
+ asyncFunctionBody,
2071
+ classContext,
2072
+ range,
2073
+ rangeStart,
2074
+ loc,
2075
+ locStart
2076
+ });
2077
+ break;
2078
+ case "jsdoc":
2079
+ parser = new Parser(jsdocGrammar, Lexer.create(looseRules, expression), void 0, {
2080
+ module,
2081
+ strictMode,
2082
+ asyncFunctionBody,
2083
+ classContext,
2084
+ range,
2085
+ rangeStart,
2086
+ loc,
2087
+ locStart
2088
+ });
2089
+ break;
2090
+ case "typescript":
2091
+ parser = new Parser(typescriptGrammar, Lexer.create(rules, expression), void 0, {
2092
+ module,
2093
+ strictMode,
2094
+ asyncFunctionBody,
2095
+ classContext,
2096
+ range,
2097
+ rangeStart,
2098
+ loc,
2099
+ locStart,
2100
+ externalParsers: { computedPropertyParser }
2101
+ });
2102
+ break;
2103
+ }
2104
+ const result = parser.parse();
2105
+ return assertResultIsNotReservedWord(parser, result);
2106
+ }
2107
+ /**
2108
+ * This function tries to parse the given expression in multiple modes and returns the first successful
2109
+ * {@link RootResult}. By default it tries `'typescript'`, `'closure'` and `'jsdoc'` in this order. If
2110
+ * no mode was successful it throws the error that was produced by the last parsing attempt.
2111
+ * @param expression
2112
+ * @param modes
2113
+ */
2114
+ function tryParse(expression, modes = [
2115
+ "typescript",
2116
+ "closure",
2117
+ "jsdoc"
2118
+ ], { module = true, strictMode = true, asyncFunctionBody = true, classContext = false, range, rangeStart, loc = false, locStart = {
2119
+ column: 0,
2120
+ line: 1
2121
+ } } = {}) {
2122
+ let error;
2123
+ for (const mode of modes) try {
2124
+ return parse(expression, mode, {
2125
+ module,
2126
+ strictMode,
2127
+ asyncFunctionBody,
2128
+ classContext,
2129
+ range,
2130
+ rangeStart,
2131
+ loc,
2132
+ locStart
2133
+ });
2134
+ } catch (e) {
2135
+ error = e;
2136
+ }
2137
+ throw error;
2138
+ }
2139
+ /**
2140
+ * This function parses the given expression in the given mode and produces a name path.
2141
+ * @param expression
2142
+ * @param mode
2143
+ */
2144
+ function parseNamePath(expression, mode, { includeSpecial = false } = {}) {
2145
+ switch (mode) {
2146
+ case "closure": return new Parser(includeSpecial ? closureNamePathSpecialGrammar : closureNamePathGrammar, Lexer.create(looseRules, expression)).parse();
2147
+ case "jsdoc": return new Parser(includeSpecial ? jsdocNamePathSpecialGrammar : jsdocNamePathGrammar, Lexer.create(looseRules, expression)).parse();
2148
+ case "typescript": return new Parser(includeSpecial ? typescriptNamePathSpecialGrammar : typescriptNamePathGrammar, Lexer.create(rules, expression)).parse();
2149
+ }
2150
+ }
2151
+ /**
2152
+ * This function parses the given expression in the given mode and produces a name.
2153
+ * @param expression
2154
+ * @param mode
2155
+ */
2156
+ function parseName(expression, mode) {
2157
+ switch (mode) {
2158
+ case "closure": return new Parser(closureNameGrammar, Lexer.create(looseRules, expression)).parse();
2159
+ case "jsdoc": return new Parser(jsdocNameGrammar, Lexer.create(looseRules, expression)).parse();
2160
+ case "typescript": return new Parser(typescriptNameGrammar, Lexer.create(rules, expression)).parse();
2161
+ }
2162
+ }
2163
+ //#endregion
2164
+ //#region src/transforms/transform.ts
2165
+ function transform(rules, parseResult) {
2166
+ const rule = rules[parseResult.type];
2167
+ if (rule === void 0) throw new Error(`In this set of transform rules exists no rule for type ${parseResult.type}.`);
2168
+ return rule(parseResult, (aParseResult) => transform(rules, aParseResult));
2169
+ }
2170
+ function notAvailableTransform(parseResult) {
2171
+ throw new Error("This transform is not available. Are you trying the correct parsing mode?");
2172
+ }
2173
+ function extractSpecialParams(source) {
2174
+ const result = { params: [] };
2175
+ for (const param of source.parameters) if (param.type === "JsdocTypeKeyValue") if (param.key === "this") result.this = param.right;
2176
+ else if (param.key === "new") result.new = param.right;
2177
+ else result.params.push(param);
2178
+ else result.params.push(param);
2179
+ return result;
2180
+ }
2181
+ //#endregion
2182
+ //#region src/transforms/stringify.ts
2183
+ function applyPosition(position, target, value) {
2184
+ return position === "prefix" ? value + target : target + value;
2185
+ }
2186
+ function quote(value, quote) {
2187
+ switch (quote) {
2188
+ case "double": return `"${value}"`;
2189
+ case "single": return `'${value}'`;
2190
+ case void 0: return value;
2191
+ }
2192
+ }
2193
+ function stringifyRules({ computedPropertyStringifier } = {}) {
2194
+ return {
2195
+ JsdocTypeParenthesis: (result, transform) => `(${result.element !== void 0 ? transform(result.element) : ""})`,
2196
+ JsdocTypeKeyof: (result, transform) => `keyof ${transform(result.element)}`,
2197
+ JsdocTypeFunction: (result, transform) => {
2198
+ if (!result.arrow) {
2199
+ let stringified = result.constructor ? "new" : "function";
2200
+ if (!result.parenthesis) return stringified;
2201
+ stringified += `(${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})`;
2202
+ if (result.returnType !== void 0) stringified += `${result.meta?.preReturnMarkerSpacing ?? ""}:${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`;
2203
+ return stringified;
2204
+ } else {
2205
+ if (result.returnType === void 0) throw new Error("Arrow function needs a return type.");
2206
+ let stringified = `${result.typeParameters !== void 0 ? `<${result.typeParameters.map(transform).join(`,${result.meta?.typeParameterSpacing ?? " "}`)}>${result.meta?.postGenericSpacing ?? ""}` : ""}(${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})${result.meta?.preReturnMarkerSpacing ?? " "}=>${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`;
2207
+ if (result.constructor) stringified = `new ${stringified}`;
2208
+ return stringified;
2209
+ }
2210
+ },
2211
+ JsdocTypeName: (result) => result.value,
2212
+ JsdocTypeInfer: (result, transform) => `infer ${transform(result.element)}`,
2213
+ JsdocTypeUniqueSymbol: () => "unique symbol",
2214
+ JsdocTypeTuple: (result, transform) => `[${result.elements.map(transform).join(`,${result.meta?.elementSpacing ?? " "}`)}]`,
2215
+ JsdocTypeVariadic: (result, transform) => result.meta.position === void 0 ? "..." : applyPosition(result.meta.position, transform(result.element), "..."),
2216
+ JsdocTypeNamePath: (result, transform) => {
2217
+ const left = transform(result.left);
2218
+ const right = transform(result.right);
2219
+ switch (result.pathType) {
2220
+ case "inner": return `${left}~${right}`;
2221
+ case "instance": return `${left}#${right}`;
2222
+ case "property": return `${left}.${right}`;
2223
+ case "property-brackets": return `${left}[${right}]`;
2224
+ }
2225
+ },
2226
+ JsdocTypeStringValue: (result) => quote(result.value, result.meta.quote),
2227
+ JsdocTypeAny: () => "*",
2228
+ JsdocTypeGeneric: (result, transform) => {
2229
+ if (result.meta.brackets === "square") {
2230
+ const element = result.elements[0];
2231
+ const transformed = transform(element);
2232
+ if (element.type === "JsdocTypeUnion" || element.type === "JsdocTypeIntersection") return `(${transformed})[]`;
2233
+ else return `${transformed}[]`;
2234
+ } else return `${transform(result.left)}${result.meta.dot ? "." : ""}<${result.elements.map(transform).join(`,${result.meta.elementSpacing ?? " "}`)}>`;
2235
+ },
2236
+ JsdocTypeImport: (result, transform) => `import(${transform(result.element)})`,
2237
+ JsdocTypeObjectField: (result, transform) => {
2238
+ let text = "";
2239
+ if (result.readonly) text += "readonly ";
2240
+ let optionalBeforeParentheses = false;
2241
+ if (typeof result.key === "string") text += quote(result.key, result.meta.quote);
2242
+ else {
2243
+ if (result.key.type === "JsdocTypeComputedMethod") optionalBeforeParentheses = true;
2244
+ text += transform(result.key);
2245
+ }
2246
+ text += result.meta.postKeySpacing ?? "";
2247
+ if (!optionalBeforeParentheses && result.optional) {
2248
+ text += "?";
2249
+ text += result.meta.postOptionalSpacing ?? "";
2250
+ }
2251
+ if (result.right === void 0) return text;
2252
+ else return `${text}:${result.meta.postColonSpacing ?? " "}${transform(result.right)}`;
2253
+ },
2254
+ JsdocTypeJsdocObjectField: (result, transform) => `${transform(result.left)}: ${transform(result.right)}`,
2255
+ JsdocTypeKeyValue: (result, transform) => {
2256
+ let text = result.key;
2257
+ if (result.optional) text += `${result.meta?.postKeySpacing ?? ""}?${result.meta?.postOptionalSpacing ?? ""}`;
2258
+ else if (result.variadic) text = `...${result.meta?.postVariadicSpacing ?? ""}${text}`;
2259
+ else if (result.right !== void 0) text += result.meta?.postKeySpacing ?? "";
2260
+ if (result.right === void 0) return text;
2261
+ else return `${text}:${result.meta?.postColonSpacing ?? " "}${transform(result.right)}`;
2262
+ },
2263
+ JsdocTypeSpecialNamePath: (result) => `${result.specialType}:${quote(result.value, result.meta.quote)}`,
2264
+ JsdocTypeNotNullable: (result, transform) => applyPosition(result.meta.position, transform(result.element), "!"),
2265
+ JsdocTypeNull: () => "null",
2266
+ JsdocTypeNullable: (result, transform) => applyPosition(result.meta.position, transform(result.element), "?"),
2267
+ JsdocTypeNumber: (result) => result.value.toString(),
2268
+ JsdocTypeBigInt: (result) => `${result.value}n`,
2269
+ JsdocTypeObject: (result, transform) => {
2270
+ /* c8 ignore next -- Guard */
2271
+ const lbType = (result.meta.separator ?? "").endsWith("linebreak");
2272
+ const lbEnding = result.meta.separator === "comma-and-linebreak" ? ",\n" : result.meta.separator === "semicolon-and-linebreak" ? ";\n" : result.meta.separator === "linebreak" ? "\n" : "";
2273
+ const separatorForSingleObjectField = result.meta.separatorForSingleObjectField ?? false;
2274
+ const trailingPunctuation = result.meta.trailingPunctuation ?? false;
2275
+ const bracketSpacing = result.meta.bracketSpacing ?? "";
2276
+ return `{${(lbType && (separatorForSingleObjectField || result.elements.length > 1) ? `\n${result.meta.propertyIndent ?? ""}` : bracketSpacing) + result.elements.map(transform).join(result.meta.separator === "comma" ? ", " : lbType ? lbEnding + (result.meta.propertyIndent ?? "") : "; ") + (separatorForSingleObjectField && result.elements.length === 1 ? result.meta.separator === "comma" ? "," : lbType ? lbEnding : ";" : trailingPunctuation && result.meta.separator !== void 0 ? result.meta.separator.startsWith("comma") ? "," : result.meta.separator.startsWith("semicolon") ? ";" : "" : "") + (lbType && result.elements.length > 1 ? "\n" : bracketSpacing)}}`;
2277
+ },
2278
+ JsdocTypeOptional: (result, transform) => applyPosition(result.meta.position, transform(result.element), "="),
2279
+ JsdocTypeSymbol: (result, transform) => `${result.value}(${result.element !== void 0 ? transform(result.element) : ""})`,
2280
+ JsdocTypeTypeof: (result, transform) => `typeof ${transform(result.element)}`,
2281
+ JsdocTypeUndefined: () => "undefined",
2282
+ JsdocTypeUnion: (result, transform) => result.elements.map(transform).join(result.meta?.spacing === void 0 ? " | " : `${result.meta.spacing}|${result.meta.spacing}`),
2283
+ JsdocTypeUnknown: () => "?",
2284
+ JsdocTypeIntersection: (result, transform) => result.elements.map(transform).join(" & "),
2285
+ JsdocTypeProperty: (result) => quote(result.value, result.meta.quote),
2286
+ JsdocTypePredicate: (result, transform) => `${transform(result.left)} is ${transform(result.right)}`,
2287
+ JsdocTypeIndexSignature: (result, transform) => `[${result.key}: ${transform(result.right)}]`,
2288
+ JsdocTypeMappedType: (result, transform) => `[${result.key} in ${transform(result.right)}]`,
2289
+ JsdocTypeAsserts: (result, transform) => `asserts ${transform(result.left)} is ${transform(result.right)}`,
2290
+ JsdocTypeReadonlyArray: (result, transform) => `readonly ${transform(result.element)}`,
2291
+ JsdocTypeAssertsPlain: (result, transform) => `asserts ${transform(result.element)}`,
2292
+ JsdocTypeConditional: (result, transform) => `${transform(result.checksType)} extends ${transform(result.extendsType)} ? ${transform(result.trueType)} : ${transform(result.falseType)}`,
2293
+ JsdocTypeTypeParameter: (result, transform) => `${transform(result.name)}${result.constraint !== void 0 ? ` extends ${transform(result.constraint)}` : ""}${result.defaultValue !== void 0 ? `${result.meta?.defaultValueSpacing ?? " "}=${result.meta?.defaultValueSpacing ?? " "}${transform(result.defaultValue)}` : ""}`,
2294
+ JsdocTypeCallSignature: (result, transform) => `${result.typeParameters !== void 0 ? `<${result.typeParameters.map(transform).join(`,${result.meta?.typeParameterSpacing ?? " "}`)}>${result.meta?.postGenericSpacing ?? ""}` : ""}(${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})${result.meta?.preReturnMarkerSpacing ?? ""}:${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`,
2295
+ JsdocTypeConstructorSignature: (result, transform) => `new${result.meta?.postNewSpacing ?? " "}${result.typeParameters !== void 0 ? `<${result.typeParameters.map(transform).join(`,${result.meta?.typeParameterSpacing ?? " "}`)}>${result.meta?.postGenericSpacing ?? ""}` : ""}(${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})${result.meta?.preReturnMarkerSpacing ?? ""}:${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`,
2296
+ JsdocTypeMethodSignature: (result, transform) => {
2297
+ const quote = result.meta.quote === "double" ? "\"" : result.meta.quote === "single" ? "'" : "";
2298
+ return `${quote}${result.name}${quote}${result.meta.postMethodNameSpacing ?? ""}${result.typeParameters !== void 0 ? `<${result.typeParameters.map(transform).join(`,${result.meta.typeParameterSpacing ?? " "}`)}>${result.meta.postGenericSpacing ?? ""}` : ""}(${result.parameters.map(transform).join(`,${result.meta.parameterSpacing ?? " "}`)})${result.meta.preReturnMarkerSpacing ?? ""}:${result.meta.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`;
2299
+ },
2300
+ JsdocTypeIndexedAccessIndex: (result, transform) => transform(result.right),
2301
+ JsdocTypeTemplateLiteral: (result, transform) => `\`${result.literals.slice(0, -1).map((literal, idx) => `${literal.replace(/`/gv, "\\`")}\${${transform(result.interpolations[idx])}}`).join("") + result.literals.slice(-1)[0].replace(/`/gv, "\\`")}\``,
2302
+ JsdocTypeComputedProperty: (result, transform) => {
2303
+ if (result.value.type.startsWith("JsdocType")) return `[${transform(result.value)}]`;
2304
+ else {
2305
+ if (computedPropertyStringifier === void 0) throw new Error("Must have a computed property stringifier");
2306
+ return `[${computedPropertyStringifier(result.value).replace(/;$/v, "")}]`;
2307
+ }
2308
+ },
2309
+ JsdocTypeComputedMethod: (result, transform) => {
2310
+ if (result.value.type.startsWith("JsdocType")) return `[${transform(result.value)}]${result.optional ? "?" : ""}${result.typeParameters !== void 0 ? `<${result.typeParameters.map(transform).join(`,${result.meta?.typeParameterSpacing ?? " "}`)}>${result.meta?.postGenericSpacing ?? ""}` : ""}(${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})${result.meta?.preReturnMarkerSpacing ?? ""}:${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`;
2311
+ else {
2312
+ if (computedPropertyStringifier === void 0) throw new Error("Must have a computed property stringifier");
2313
+ return `[${computedPropertyStringifier(result.value).replace(/;$/v, "")}](${result.parameters.map(transform).join(`,${result.meta?.parameterSpacing ?? " "}`)})${result.meta?.preReturnMarkerSpacing ?? ""}:${result.meta?.postReturnMarkerSpacing ?? " "}${transform(result.returnType)}`;
2314
+ }
2315
+ }
2316
+ };
2317
+ }
2318
+ const storedStringifyRules = stringifyRules();
2319
+ function stringify(result, stringificationRules = storedStringifyRules) {
2320
+ if (typeof stringificationRules === "function") stringificationRules = stringifyRules({ computedPropertyStringifier: stringificationRules });
2321
+ return transform(stringificationRules, result);
2322
+ }
2323
+ //#endregion
2324
+ //#region src/transforms/catharsisTransform.ts
2325
+ const reservedWords = [
2326
+ "null",
2327
+ "true",
2328
+ "false",
2329
+ "break",
2330
+ "case",
2331
+ "catch",
2332
+ "class",
2333
+ "const",
2334
+ "continue",
2335
+ "debugger",
2336
+ "default",
2337
+ "delete",
2338
+ "do",
2339
+ "else",
2340
+ "export",
2341
+ "extends",
2342
+ "finally",
2343
+ "for",
2344
+ "function",
2345
+ "if",
2346
+ "import",
2347
+ "in",
2348
+ "instanceof",
2349
+ "new",
2350
+ "return",
2351
+ "super",
2352
+ "switch",
2353
+ "this",
2354
+ "throw",
2355
+ "try",
2356
+ "typeof",
2357
+ "var",
2358
+ "void",
2359
+ "while",
2360
+ "with",
2361
+ "yield"
2362
+ ];
2363
+ function makeName(value) {
2364
+ const result = {
2365
+ type: "NameExpression",
2366
+ name: value
2367
+ };
2368
+ if (reservedWords.includes(value)) result.reservedWord = true;
2369
+ return result;
2370
+ }
2371
+ const catharsisTransformRules = {
2372
+ JsdocTypeOptional: (result, transform) => {
2373
+ const transformed = transform(result.element);
2374
+ transformed.optional = true;
2375
+ return transformed;
2376
+ },
2377
+ JsdocTypeNullable: (result, transform) => {
2378
+ const transformed = transform(result.element);
2379
+ transformed.nullable = true;
2380
+ return transformed;
2381
+ },
2382
+ JsdocTypeNotNullable: (result, transform) => {
2383
+ const transformed = transform(result.element);
2384
+ transformed.nullable = false;
2385
+ return transformed;
2386
+ },
2387
+ JsdocTypeVariadic: (result, transform) => {
2388
+ if (result.element === void 0) throw new Error("dots without value are not allowed in catharsis mode");
2389
+ const transformed = transform(result.element);
2390
+ transformed.repeatable = true;
2391
+ return transformed;
2392
+ },
2393
+ JsdocTypeAny: () => ({ type: "AllLiteral" }),
2394
+ JsdocTypeNull: () => ({ type: "NullLiteral" }),
2395
+ JsdocTypeStringValue: (result) => makeName(quote(result.value, result.meta.quote)),
2396
+ JsdocTypeUndefined: () => ({ type: "UndefinedLiteral" }),
2397
+ JsdocTypeUnknown: () => ({ type: "UnknownLiteral" }),
2398
+ JsdocTypeFunction: (result, transform) => {
2399
+ const params = extractSpecialParams(result);
2400
+ const transformed = {
2401
+ type: "FunctionType",
2402
+ params: params.params.map(transform)
2403
+ };
2404
+ if (params.this !== void 0) transformed.this = transform(params.this);
2405
+ if (params.new !== void 0) transformed.new = transform(params.new);
2406
+ if (result.returnType !== void 0) transformed.result = transform(result.returnType);
2407
+ return transformed;
2408
+ },
2409
+ JsdocTypeGeneric: (result, transform) => ({
2410
+ type: "TypeApplication",
2411
+ applications: result.elements.map((o) => transform(o)),
2412
+ expression: transform(result.left)
2413
+ }),
2414
+ JsdocTypeSpecialNamePath: (result) => makeName(`${result.specialType}:${quote(result.value, result.meta.quote)}`),
2415
+ JsdocTypeName: (result) => {
2416
+ if (result.value !== "function") return makeName(result.value);
2417
+ else return {
2418
+ type: "FunctionType",
2419
+ params: []
2420
+ };
2421
+ },
2422
+ JsdocTypeNumber: (result) => makeName(result.value.toString()),
2423
+ JsdocTypeBigInt: (result) => makeName(`${result.value}n`),
2424
+ JsdocTypeObject: (result, transform) => {
2425
+ const transformed = {
2426
+ type: "RecordType",
2427
+ fields: []
2428
+ };
2429
+ for (const field of result.elements) if (field.type !== "JsdocTypeObjectField" && field.type !== "JsdocTypeJsdocObjectField") transformed.fields.push({
2430
+ type: "FieldType",
2431
+ key: transform(field),
2432
+ value: void 0
2433
+ });
2434
+ else transformed.fields.push(transform(field));
2435
+ return transformed;
2436
+ },
2437
+ JsdocTypeObjectField: (result, transform) => {
2438
+ if (typeof result.key !== "string") throw new Error("Index signatures and mapped types are not supported");
2439
+ return {
2440
+ type: "FieldType",
2441
+ key: makeName(quote(result.key, result.meta.quote)),
2442
+ value: result.right === void 0 ? void 0 : transform(result.right)
2443
+ };
2444
+ },
2445
+ JsdocTypeJsdocObjectField: (result, transform) => ({
2446
+ type: "FieldType",
2447
+ key: transform(result.left),
2448
+ value: transform(result.right)
2449
+ }),
2450
+ JsdocTypeUnion: (result, transform) => ({
2451
+ type: "TypeUnion",
2452
+ elements: result.elements.map((e) => transform(e))
2453
+ }),
2454
+ JsdocTypeKeyValue: (result, transform) => ({
2455
+ type: "FieldType",
2456
+ key: makeName(result.key),
2457
+ value: result.right === void 0 ? void 0 : transform(result.right)
2458
+ }),
2459
+ JsdocTypeNamePath: (result, transform) => {
2460
+ const leftResult = transform(result.left);
2461
+ let rightValue;
2462
+ if (result.right.type === "JsdocTypeIndexedAccessIndex") throw new TypeError("JsdocTypeIndexedAccessIndex is not supported in catharsis");
2463
+ if (result.right.type === "JsdocTypeSpecialNamePath") rightValue = transform(result.right).name;
2464
+ else rightValue = quote(result.right.value, result.right.meta.quote);
2465
+ const joiner = result.pathType === "inner" ? "~" : result.pathType === "instance" ? "#" : ".";
2466
+ return makeName(`${leftResult.name}${joiner}${rightValue}`);
2467
+ },
2468
+ JsdocTypeSymbol: (result) => {
2469
+ let value = "";
2470
+ let element = result.element;
2471
+ let trailingDots = false;
2472
+ if (element?.type === "JsdocTypeVariadic") {
2473
+ if (element.meta.position === "prefix") value = "...";
2474
+ else trailingDots = true;
2475
+ element = element.element;
2476
+ }
2477
+ if (element?.type === "JsdocTypeName") value += element.value;
2478
+ else if (element?.type === "JsdocTypeNumber") value += element.value.toString();
2479
+ if (trailingDots) value += "...";
2480
+ return makeName(`${result.value}(${value})`);
2481
+ },
2482
+ JsdocTypeParenthesis: (result, transform) => transform(assertRootResult(result.element)),
2483
+ JsdocTypeMappedType: notAvailableTransform,
2484
+ JsdocTypeIndexSignature: notAvailableTransform,
2485
+ JsdocTypeInfer: notAvailableTransform,
2486
+ JsdocTypeUniqueSymbol: notAvailableTransform,
2487
+ JsdocTypeImport: notAvailableTransform,
2488
+ JsdocTypeKeyof: notAvailableTransform,
2489
+ JsdocTypeTuple: notAvailableTransform,
2490
+ JsdocTypeTypeof: notAvailableTransform,
2491
+ JsdocTypeIntersection: notAvailableTransform,
2492
+ JsdocTypeProperty: notAvailableTransform,
2493
+ JsdocTypePredicate: notAvailableTransform,
2494
+ JsdocTypeAsserts: notAvailableTransform,
2495
+ JsdocTypeReadonlyArray: notAvailableTransform,
2496
+ JsdocTypeAssertsPlain: notAvailableTransform,
2497
+ JsdocTypeConditional: notAvailableTransform,
2498
+ JsdocTypeTypeParameter: notAvailableTransform,
2499
+ JsdocTypeCallSignature: notAvailableTransform,
2500
+ JsdocTypeConstructorSignature: notAvailableTransform,
2501
+ JsdocTypeMethodSignature: notAvailableTransform,
2502
+ JsdocTypeIndexedAccessIndex: notAvailableTransform,
2503
+ JsdocTypeTemplateLiteral: notAvailableTransform,
2504
+ JsdocTypeComputedProperty: notAvailableTransform,
2505
+ JsdocTypeComputedMethod: notAvailableTransform
2506
+ };
2507
+ function catharsisTransform(result) {
2508
+ return transform(catharsisTransformRules, result);
2509
+ }
2510
+ //#endregion
2511
+ //#region src/transforms/jtpTransform.ts
2512
+ function getQuoteStyle(quote) {
2513
+ switch (quote) {
2514
+ case void 0: return "none";
2515
+ case "single": return "single";
2516
+ case "double": return "double";
2517
+ }
2518
+ }
2519
+ function getMemberType(type) {
2520
+ switch (type) {
2521
+ case "inner": return "INNER_MEMBER";
2522
+ case "instance": return "INSTANCE_MEMBER";
2523
+ case "property": return "MEMBER";
2524
+ case "property-brackets": return "MEMBER";
2525
+ }
2526
+ }
2527
+ function nestResults(type, results) {
2528
+ if (results.length === 2) return {
2529
+ type,
2530
+ left: results[0],
2531
+ right: results[1]
2532
+ };
2533
+ else return {
2534
+ type,
2535
+ left: results[0],
2536
+ right: nestResults(type, results.slice(1))
2537
+ };
2538
+ }
2539
+ const jtpRules = {
2540
+ JsdocTypeOptional: (result, transform) => ({
2541
+ type: "OPTIONAL",
2542
+ value: transform(result.element),
2543
+ meta: { syntax: result.meta.position === "prefix" ? "PREFIX_EQUAL_SIGN" : "SUFFIX_EQUALS_SIGN" }
2544
+ }),
2545
+ JsdocTypeNullable: (result, transform) => ({
2546
+ type: "NULLABLE",
2547
+ value: transform(result.element),
2548
+ meta: { syntax: result.meta.position === "prefix" ? "PREFIX_QUESTION_MARK" : "SUFFIX_QUESTION_MARK" }
2549
+ }),
2550
+ JsdocTypeNotNullable: (result, transform) => ({
2551
+ type: "NOT_NULLABLE",
2552
+ value: transform(result.element),
2553
+ meta: { syntax: result.meta.position === "prefix" ? "PREFIX_BANG" : "SUFFIX_BANG" }
2554
+ }),
2555
+ JsdocTypeVariadic: (result, transform) => {
2556
+ const transformed = {
2557
+ type: "VARIADIC",
2558
+ meta: { syntax: result.meta.position === "prefix" ? "PREFIX_DOTS" : result.meta.position === "suffix" ? "SUFFIX_DOTS" : "ONLY_DOTS" }
2559
+ };
2560
+ if (result.element !== void 0) transformed.value = transform(result.element);
2561
+ return transformed;
2562
+ },
2563
+ JsdocTypeName: (result) => ({
2564
+ type: "NAME",
2565
+ name: result.value
2566
+ }),
2567
+ JsdocTypeTypeof: (result, transform) => ({
2568
+ type: "TYPE_QUERY",
2569
+ name: transform(result.element)
2570
+ }),
2571
+ JsdocTypeTuple: (result, transform) => ({
2572
+ type: "TUPLE",
2573
+ entries: result.elements.map(transform)
2574
+ }),
2575
+ JsdocTypeKeyof: (result, transform) => ({
2576
+ type: "KEY_QUERY",
2577
+ value: transform(result.element)
2578
+ }),
2579
+ JsdocTypeImport: (result) => ({
2580
+ type: "IMPORT",
2581
+ path: {
2582
+ type: "STRING_VALUE",
2583
+ quoteStyle: getQuoteStyle(result.element.meta.quote),
2584
+ string: result.element.value
2585
+ }
2586
+ }),
2587
+ JsdocTypeUndefined: () => ({
2588
+ type: "NAME",
2589
+ name: "undefined"
2590
+ }),
2591
+ JsdocTypeAny: () => ({ type: "ANY" }),
2592
+ JsdocTypeFunction: (result, transform) => {
2593
+ const specialParams = extractSpecialParams(result);
2594
+ const transformed = {
2595
+ type: result.arrow ? "ARROW" : "FUNCTION",
2596
+ params: specialParams.params.map((param) => {
2597
+ if (param.type === "JsdocTypeKeyValue") {
2598
+ if (param.right === void 0) throw new Error("Function parameter without ':' is not expected to be 'KEY_VALUE'");
2599
+ return {
2600
+ type: "NAMED_PARAMETER",
2601
+ name: param.key,
2602
+ typeName: transform(param.right)
2603
+ };
2604
+ } else return transform(param);
2605
+ }),
2606
+ new: null,
2607
+ returns: null
2608
+ };
2609
+ if (specialParams.this !== void 0) transformed.this = transform(specialParams.this);
2610
+ else if (!result.arrow) transformed.this = null;
2611
+ if (specialParams.new !== void 0) transformed.new = transform(specialParams.new);
2612
+ if (result.returnType !== void 0) transformed.returns = transform(result.returnType);
2613
+ return transformed;
2614
+ },
2615
+ JsdocTypeGeneric: (result, transform) => {
2616
+ const transformed = {
2617
+ type: "GENERIC",
2618
+ subject: transform(result.left),
2619
+ objects: result.elements.map(transform),
2620
+ meta: { syntax: result.meta.brackets === "square" ? "SQUARE_BRACKET" : result.meta.dot ? "ANGLE_BRACKET_WITH_DOT" : "ANGLE_BRACKET" }
2621
+ };
2622
+ if (result.meta.brackets === "square" && result.elements[0].type === "JsdocTypeFunction" && !result.elements[0].parenthesis) transformed.objects[0] = {
2623
+ type: "NAME",
2624
+ name: "function"
2625
+ };
2626
+ return transformed;
2627
+ },
2628
+ JsdocTypeObjectField: (result, transform) => {
2629
+ if (typeof result.key !== "string") throw new Error("Index signatures and mapped types are not supported");
2630
+ if (result.right === void 0) return {
2631
+ type: "RECORD_ENTRY",
2632
+ key: result.key,
2633
+ quoteStyle: getQuoteStyle(result.meta.quote),
2634
+ value: null,
2635
+ readonly: false
2636
+ };
2637
+ let right = transform(result.right);
2638
+ if (result.optional) right = {
2639
+ type: "OPTIONAL",
2640
+ value: right,
2641
+ meta: { syntax: "SUFFIX_KEY_QUESTION_MARK" }
2642
+ };
2643
+ return {
2644
+ type: "RECORD_ENTRY",
2645
+ key: result.key,
2646
+ quoteStyle: getQuoteStyle(result.meta.quote),
2647
+ value: right,
2648
+ readonly: false
2649
+ };
2650
+ },
2651
+ JsdocTypeJsdocObjectField: () => {
2652
+ throw new Error("Keys may not be typed in jsdoctypeparser.");
2653
+ },
2654
+ JsdocTypeKeyValue: (result, transform) => {
2655
+ if (result.right === void 0) return {
2656
+ type: "RECORD_ENTRY",
2657
+ key: result.key,
2658
+ quoteStyle: "none",
2659
+ value: null,
2660
+ readonly: false
2661
+ };
2662
+ let right = transform(result.right);
2663
+ if (result.optional) right = {
2664
+ type: "OPTIONAL",
2665
+ value: right,
2666
+ meta: { syntax: "SUFFIX_KEY_QUESTION_MARK" }
2667
+ };
2668
+ return {
2669
+ type: "RECORD_ENTRY",
2670
+ key: result.key,
2671
+ quoteStyle: "none",
2672
+ value: right,
2673
+ readonly: false
2674
+ };
2675
+ },
2676
+ JsdocTypeObject: (result, transform) => {
2677
+ const entries = [];
2678
+ for (const field of result.elements) if (field.type === "JsdocTypeObjectField" || field.type === "JsdocTypeJsdocObjectField") entries.push(transform(field));
2679
+ return {
2680
+ type: "RECORD",
2681
+ entries
2682
+ };
2683
+ },
2684
+ JsdocTypeSpecialNamePath: (result) => {
2685
+ if (result.specialType !== "module") throw new Error(`jsdoctypeparser does not support type ${result.specialType} at this point.`);
2686
+ return {
2687
+ type: "MODULE",
2688
+ value: {
2689
+ type: "FILE_PATH",
2690
+ quoteStyle: getQuoteStyle(result.meta.quote),
2691
+ path: result.value
2692
+ }
2693
+ };
2694
+ },
2695
+ JsdocTypeNamePath: (result, transform) => {
2696
+ let hasEventPrefix = false;
2697
+ let name;
2698
+ let quoteStyle;
2699
+ if (result.right.type === "JsdocTypeIndexedAccessIndex") throw new TypeError("JsdocTypeIndexedAccessIndex not allowed in jtp");
2700
+ if (result.right.type === "JsdocTypeSpecialNamePath" && result.right.specialType === "event") {
2701
+ hasEventPrefix = true;
2702
+ name = result.right.value;
2703
+ quoteStyle = getQuoteStyle(result.right.meta.quote);
2704
+ } else {
2705
+ name = result.right.value;
2706
+ quoteStyle = getQuoteStyle(result.right.meta.quote);
2707
+ }
2708
+ const transformed = {
2709
+ type: getMemberType(result.pathType),
2710
+ owner: transform(result.left),
2711
+ name,
2712
+ quoteStyle,
2713
+ hasEventPrefix
2714
+ };
2715
+ if (transformed.owner.type === "MODULE") {
2716
+ const tModule = transformed.owner;
2717
+ transformed.owner = transformed.owner.value;
2718
+ tModule.value = transformed;
2719
+ return tModule;
2720
+ } else return transformed;
2721
+ },
2722
+ JsdocTypeUnion: (result, transform) => nestResults("UNION", result.elements.map(transform)),
2723
+ JsdocTypeParenthesis: (result, transform) => ({
2724
+ type: "PARENTHESIS",
2725
+ value: transform(assertRootResult(result.element))
2726
+ }),
2727
+ JsdocTypeNull: () => ({
2728
+ type: "NAME",
2729
+ name: "null"
2730
+ }),
2731
+ JsdocTypeUnknown: () => ({ type: "UNKNOWN" }),
2732
+ JsdocTypeStringValue: (result) => ({
2733
+ type: "STRING_VALUE",
2734
+ quoteStyle: getQuoteStyle(result.meta.quote),
2735
+ string: result.value
2736
+ }),
2737
+ JsdocTypeIntersection: (result, transform) => nestResults("INTERSECTION", result.elements.map(transform)),
2738
+ JsdocTypeNumber: (result) => ({
2739
+ type: "NUMBER_VALUE",
2740
+ number: result.value.toString()
2741
+ }),
2742
+ JsdocTypeBigInt: (result) => ({
2743
+ type: "NUMBER_VALUE",
2744
+ number: `${result.value}n`
2745
+ }),
2746
+ JsdocTypeSymbol: notAvailableTransform,
2747
+ JsdocTypeProperty: notAvailableTransform,
2748
+ JsdocTypePredicate: notAvailableTransform,
2749
+ JsdocTypeMappedType: notAvailableTransform,
2750
+ JsdocTypeIndexSignature: notAvailableTransform,
2751
+ JsdocTypeInfer: notAvailableTransform,
2752
+ JsdocTypeUniqueSymbol: notAvailableTransform,
2753
+ JsdocTypeAsserts: notAvailableTransform,
2754
+ JsdocTypeReadonlyArray: notAvailableTransform,
2755
+ JsdocTypeAssertsPlain: notAvailableTransform,
2756
+ JsdocTypeConditional: notAvailableTransform,
2757
+ JsdocTypeTypeParameter: notAvailableTransform,
2758
+ JsdocTypeCallSignature: notAvailableTransform,
2759
+ JsdocTypeConstructorSignature: notAvailableTransform,
2760
+ JsdocTypeMethodSignature: notAvailableTransform,
2761
+ JsdocTypeIndexedAccessIndex: notAvailableTransform,
2762
+ JsdocTypeTemplateLiteral: notAvailableTransform,
2763
+ JsdocTypeComputedProperty: notAvailableTransform,
2764
+ JsdocTypeComputedMethod: notAvailableTransform
2765
+ };
2766
+ function jtpTransform(result) {
2767
+ return transform(jtpRules, result);
2768
+ }
2769
+ //#endregion
2770
+ //#region src/transforms/identityTransformRules.ts
2771
+ function identityTransformRules() {
2772
+ return {
2773
+ JsdocTypeIntersection: (result, transform) => ({
2774
+ type: "JsdocTypeIntersection",
2775
+ elements: result.elements.map(transform)
2776
+ }),
2777
+ JsdocTypeGeneric: (result, transform) => ({
2778
+ type: "JsdocTypeGeneric",
2779
+ left: transform(result.left),
2780
+ elements: result.elements.map(transform),
2781
+ meta: {
2782
+ dot: result.meta.dot,
2783
+ brackets: result.meta.brackets
2784
+ }
2785
+ }),
2786
+ JsdocTypeNullable: (result) => result,
2787
+ JsdocTypeUnion: (result, transform) => ({
2788
+ type: "JsdocTypeUnion",
2789
+ elements: result.elements.map(transform)
2790
+ }),
2791
+ JsdocTypeUnknown: (result) => result,
2792
+ JsdocTypeUndefined: (result) => result,
2793
+ JsdocTypeTypeof: (result, transform) => ({
2794
+ type: "JsdocTypeTypeof",
2795
+ element: transform(result.element)
2796
+ }),
2797
+ JsdocTypeSymbol: (result, transform) => {
2798
+ const transformed = {
2799
+ type: "JsdocTypeSymbol",
2800
+ value: result.value
2801
+ };
2802
+ if (result.element !== void 0) transformed.element = transform(result.element);
2803
+ return transformed;
2804
+ },
2805
+ JsdocTypeOptional: (result, transform) => ({
2806
+ type: "JsdocTypeOptional",
2807
+ element: transform(result.element),
2808
+ meta: { position: result.meta.position }
2809
+ }),
2810
+ JsdocTypeObject: (result, transform) => ({
2811
+ type: "JsdocTypeObject",
2812
+ meta: { separator: "comma" },
2813
+ elements: result.elements.map(transform)
2814
+ }),
2815
+ JsdocTypeNumber: (result) => result,
2816
+ JsdocTypeBigInt: (result) => result,
2817
+ JsdocTypeNull: (result) => result,
2818
+ JsdocTypeNotNullable: (result, transform) => ({
2819
+ type: "JsdocTypeNotNullable",
2820
+ element: transform(result.element),
2821
+ meta: { position: result.meta.position }
2822
+ }),
2823
+ JsdocTypeSpecialNamePath: (result) => result,
2824
+ JsdocTypeObjectField: (result, transform) => ({
2825
+ type: "JsdocTypeObjectField",
2826
+ key: result.key,
2827
+ right: result.right === void 0 ? void 0 : transform(result.right),
2828
+ optional: result.optional,
2829
+ readonly: result.readonly,
2830
+ meta: result.meta
2831
+ }),
2832
+ JsdocTypeJsdocObjectField: (result, transform) => ({
2833
+ type: "JsdocTypeJsdocObjectField",
2834
+ left: transform(result.left),
2835
+ right: transform(result.right)
2836
+ }),
2837
+ JsdocTypeKeyValue: (result, transform) => ({
2838
+ type: "JsdocTypeKeyValue",
2839
+ key: result.key,
2840
+ right: result.right === void 0 ? void 0 : transform(result.right),
2841
+ optional: result.optional,
2842
+ variadic: result.variadic
2843
+ }),
2844
+ JsdocTypeImport: (result, transform) => ({
2845
+ type: "JsdocTypeImport",
2846
+ element: transform(result.element)
2847
+ }),
2848
+ JsdocTypeAny: (result) => result,
2849
+ JsdocTypeStringValue: (result) => result,
2850
+ JsdocTypeNamePath: (result) => result,
2851
+ JsdocTypeVariadic: (result, transform) => {
2852
+ const transformed = {
2853
+ type: "JsdocTypeVariadic",
2854
+ meta: {
2855
+ position: result.meta.position,
2856
+ squareBrackets: result.meta.squareBrackets
2857
+ }
2858
+ };
2859
+ if (result.element !== void 0) transformed.element = transform(result.element);
2860
+ return transformed;
2861
+ },
2862
+ JsdocTypeTuple: (result, transform) => ({
2863
+ type: "JsdocTypeTuple",
2864
+ elements: result.elements.map(transform)
2865
+ }),
2866
+ JsdocTypeName: (result) => result,
2867
+ JsdocTypeInfer: (result, transform) => ({
2868
+ type: "JsdocTypeInfer",
2869
+ element: transform(result.element)
2870
+ }),
2871
+ JsdocTypeUniqueSymbol: (result) => result,
2872
+ JsdocTypeFunction: (result, transform) => {
2873
+ const transformed = {
2874
+ type: "JsdocTypeFunction",
2875
+ arrow: result.arrow,
2876
+ parameters: result.parameters.map(transform),
2877
+ constructor: result.constructor,
2878
+ parenthesis: result.parenthesis
2879
+ };
2880
+ if (result.returnType !== void 0) transformed.returnType = transform(result.returnType);
2881
+ return transformed;
2882
+ },
2883
+ JsdocTypeKeyof: (result, transform) => ({
2884
+ type: "JsdocTypeKeyof",
2885
+ element: transform(result.element)
2886
+ }),
2887
+ JsdocTypeParenthesis: (result, transform) => ({
2888
+ type: "JsdocTypeParenthesis",
2889
+ element: transform(result.element)
2890
+ }),
2891
+ JsdocTypeProperty: (result) => result,
2892
+ JsdocTypePredicate: (result, transform) => ({
2893
+ type: "JsdocTypePredicate",
2894
+ left: transform(result.left),
2895
+ right: transform(result.right)
2896
+ }),
2897
+ JsdocTypeIndexSignature: (result, transform) => ({
2898
+ type: "JsdocTypeIndexSignature",
2899
+ key: result.key,
2900
+ right: transform(result.right)
2901
+ }),
2902
+ JsdocTypeMappedType: (result, transform) => ({
2903
+ type: "JsdocTypeMappedType",
2904
+ key: result.key,
2905
+ right: transform(result.right)
2906
+ }),
2907
+ JsdocTypeAsserts: (result, transform) => ({
2908
+ type: "JsdocTypeAsserts",
2909
+ left: transform(result.left),
2910
+ right: transform(result.right)
2911
+ }),
2912
+ JsdocTypeReadonlyArray: (result, transform) => ({
2913
+ type: "JsdocTypeReadonlyArray",
2914
+ element: transform(result.element)
2915
+ }),
2916
+ JsdocTypeAssertsPlain: (result, transform) => ({
2917
+ type: "JsdocTypeAssertsPlain",
2918
+ element: transform(result.element)
2919
+ }),
2920
+ JsdocTypeConditional: (result, transform) => ({
2921
+ type: "JsdocTypeConditional",
2922
+ checksType: transform(result.checksType),
2923
+ extendsType: transform(result.extendsType),
2924
+ trueType: transform(result.trueType),
2925
+ falseType: transform(result.falseType)
2926
+ }),
2927
+ JsdocTypeTypeParameter: (result, transform) => ({
2928
+ type: "JsdocTypeTypeParameter",
2929
+ name: transform(result.name),
2930
+ constraint: result.constraint !== void 0 ? transform(result.constraint) : void 0,
2931
+ defaultValue: result.defaultValue !== void 0 ? transform(result.defaultValue) : void 0
2932
+ }),
2933
+ JsdocTypeCallSignature: (result, transform) => ({
2934
+ type: "JsdocTypeCallSignature",
2935
+ parameters: result.parameters.map(transform),
2936
+ returnType: transform(result.returnType)
2937
+ }),
2938
+ JsdocTypeConstructorSignature: (result, transform) => ({
2939
+ type: "JsdocTypeConstructorSignature",
2940
+ parameters: result.parameters.map(transform),
2941
+ returnType: transform(result.returnType)
2942
+ }),
2943
+ JsdocTypeMethodSignature: (result, transform) => ({
2944
+ type: "JsdocTypeMethodSignature",
2945
+ name: result.name,
2946
+ parameters: result.parameters.map(transform),
2947
+ returnType: transform(result.returnType),
2948
+ meta: result.meta
2949
+ }),
2950
+ JsdocTypeIndexedAccessIndex: (result, transform) => ({
2951
+ type: "JsdocTypeIndexedAccessIndex",
2952
+ right: transform(result.right)
2953
+ }),
2954
+ JsdocTypeTemplateLiteral: (result, transform) => ({
2955
+ type: "JsdocTypeTemplateLiteral",
2956
+ literals: result.literals,
2957
+ interpolations: result.interpolations.map(transform)
2958
+ }),
2959
+ JsdocTypeComputedProperty: (result, transform) => {
2960
+ if (result.value.type.startsWith("JsdocType")) return {
2961
+ type: "JsdocTypeComputedProperty",
2962
+ value: transform(result.value)
2963
+ };
2964
+ else return {
2965
+ type: "JsdocTypeComputedProperty",
2966
+ value: structuredClone(result.value)
2967
+ };
2968
+ },
2969
+ JsdocTypeComputedMethod: (result, transform) => {
2970
+ if (result.value.type.startsWith("JsdocType")) return {
2971
+ type: "JsdocTypeComputedMethod",
2972
+ value: transform(result.value),
2973
+ optional: result.optional,
2974
+ parameters: result.parameters.map(transform),
2975
+ returnType: transform(result.returnType)
2976
+ };
2977
+ else return {
2978
+ type: "JsdocTypeComputedMethod",
2979
+ value: structuredClone(result.value),
2980
+ optional: result.optional,
2981
+ parameters: result.parameters.map(transform),
2982
+ returnType: transform(result.returnType)
2983
+ };
2984
+ }
2985
+ };
2986
+ }
2987
+ //#endregion
2988
+ //#region src/visitorKeys.ts
2989
+ const visitorKeys = {
2990
+ JsdocTypeAny: [],
2991
+ JsdocTypeBigInt: [],
2992
+ JsdocTypeFunction: [
2993
+ "typeParameters",
2994
+ "parameters",
2995
+ "returnType"
2996
+ ],
2997
+ JsdocTypeGeneric: ["left", "elements"],
2998
+ JsdocTypeImport: ["element"],
2999
+ JsdocTypeIndexSignature: ["right"],
3000
+ JsdocTypeIntersection: ["elements"],
3001
+ JsdocTypeKeyof: ["element"],
3002
+ JsdocTypeKeyValue: ["right"],
3003
+ JsdocTypeMappedType: ["right"],
3004
+ JsdocTypeName: [],
3005
+ JsdocTypeInfer: ["element"],
3006
+ JsdocTypeUniqueSymbol: [],
3007
+ JsdocTypeNamePath: ["left", "right"],
3008
+ JsdocTypeNotNullable: ["element"],
3009
+ JsdocTypeNull: [],
3010
+ JsdocTypeNullable: ["element"],
3011
+ JsdocTypeNumber: [],
3012
+ JsdocTypeObject: ["elements"],
3013
+ JsdocTypeObjectField: ["key", "right"],
3014
+ JsdocTypeJsdocObjectField: ["left", "right"],
3015
+ JsdocTypeOptional: ["element"],
3016
+ JsdocTypeParenthesis: ["element"],
3017
+ JsdocTypeSpecialNamePath: [],
3018
+ JsdocTypeStringValue: [],
3019
+ JsdocTypeSymbol: ["element"],
3020
+ JsdocTypeTuple: ["elements"],
3021
+ JsdocTypeTypeof: ["element"],
3022
+ JsdocTypeUndefined: [],
3023
+ JsdocTypeUnion: ["elements"],
3024
+ JsdocTypeUnknown: [],
3025
+ JsdocTypeVariadic: ["element"],
3026
+ JsdocTypeProperty: [],
3027
+ JsdocTypePredicate: ["left", "right"],
3028
+ JsdocTypeAsserts: ["left", "right"],
3029
+ JsdocTypeReadonlyArray: ["element"],
3030
+ JsdocTypeAssertsPlain: ["element"],
3031
+ JsdocTypeConditional: [
3032
+ "checksType",
3033
+ "extendsType",
3034
+ "trueType",
3035
+ "falseType"
3036
+ ],
3037
+ JsdocTypeTypeParameter: [
3038
+ "name",
3039
+ "constraint",
3040
+ "defaultValue"
3041
+ ],
3042
+ JsdocTypeCallSignature: [
3043
+ "typeParameters",
3044
+ "parameters",
3045
+ "returnType"
3046
+ ],
3047
+ JsdocTypeConstructorSignature: [
3048
+ "typeParameters",
3049
+ "parameters",
3050
+ "returnType"
3051
+ ],
3052
+ JsdocTypeMethodSignature: [
3053
+ "typeParameters",
3054
+ "parameters",
3055
+ "returnType"
3056
+ ],
3057
+ JsdocTypeIndexedAccessIndex: ["right"],
3058
+ JsdocTypeTemplateLiteral: ["interpolations"],
3059
+ JsdocTypeComputedProperty: ["value"],
3060
+ JsdocTypeComputedMethod: [
3061
+ "value",
3062
+ "typeParameters",
3063
+ "parameters",
3064
+ "returnType"
3065
+ ]
3066
+ };
3067
+ //#endregion
3068
+ //#region src/traverse.ts
3069
+ function _traverse(node, parentNode, property, index, onEnter, onLeave) {
3070
+ onEnter?.(node, parentNode, property, index);
3071
+ const keysToVisit = visitorKeys[node.type];
3072
+ for (const key of keysToVisit) {
3073
+ const value = node[key];
3074
+ if (value !== void 0) {
3075
+ if (Array.isArray(value)) for (const [index, element] of value.entries()) _traverse(element, node, key, index, onEnter, onLeave);
3076
+ else if (value !== null && typeof value === "object" && "type" in value) _traverse(value, node, key, void 0, onEnter, onLeave);
3077
+ }
3078
+ }
3079
+ onLeave?.(node, parentNode, property, index);
3080
+ }
3081
+ /**
3082
+ * A function to traverse an AST. It traverses it depth first.
3083
+ * @param node the node to start traversing at.
3084
+ * @param onEnter node visitor function that will be called on entering the node. This corresponds to preorder traversing.
3085
+ * @param onLeave node visitor function that will be called on leaving the node. This corresponds to postorder traversing.
3086
+ */
3087
+ function traverse(node, onEnter, onLeave) {
3088
+ _traverse(node, void 0, void 0, void 0, onEnter, onLeave);
3089
+ }
3090
+ //#endregion
3091
+ export { catharsisTransform, identityTransformRules, jtpTransform, parse, parseName, parseNamePath, stringify, stringifyRules, transform, traverse, tryParse, visitorKeys };