@saasmakers/eslint 0.2.5 → 0.2.7

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