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