@dcf-micro/eslint-config 5.0.0

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 (46) hide show
  1. package/dist/chunks/eslint-plugin-prettier.mjs +1716 -0
  2. package/dist/chunks/index.mjs +1341 -0
  3. package/dist/chunks/index10.mjs +39595 -0
  4. package/dist/chunks/index11.mjs +24 -0
  5. package/dist/chunks/index12.mjs +75273 -0
  6. package/dist/chunks/index13.mjs +55129 -0
  7. package/dist/chunks/index14.mjs +24 -0
  8. package/dist/chunks/index15.mjs +1441 -0
  9. package/dist/chunks/index2.mjs +31864 -0
  10. package/dist/chunks/index3.mjs +8154 -0
  11. package/dist/chunks/index4.mjs +24 -0
  12. package/dist/chunks/index5.mjs +44093 -0
  13. package/dist/chunks/index6.mjs +10371 -0
  14. package/dist/chunks/index7.mjs +21890 -0
  15. package/dist/chunks/index8.mjs +14424 -0
  16. package/dist/chunks/index9.mjs +194 -0
  17. package/dist/chunks/jiti.mjs +320 -0
  18. package/dist/index.d.mts +3897 -0
  19. package/dist/index.d.ts +3897 -0
  20. package/dist/index.mjs +4 -0
  21. package/dist/shared/eslint-config.BDBLGvXj.mjs +5282 -0
  22. package/dist/shared/eslint-config.BEdqg1el.mjs +12256 -0
  23. package/dist/shared/eslint-config.BKmXKm8B.mjs +5533 -0
  24. package/dist/shared/eslint-config.BjUMgISS.mjs +9012 -0
  25. package/dist/shared/eslint-config.Bk-3rH6Y.mjs +1355 -0
  26. package/dist/shared/eslint-config.BytuZ0Ec.mjs +20 -0
  27. package/dist/shared/eslint-config.C1V0I4Np.mjs +16900 -0
  28. package/dist/shared/eslint-config.CGxZQKHV.mjs +2091 -0
  29. package/dist/shared/eslint-config.COweQ1RR.mjs +5 -0
  30. package/dist/shared/eslint-config.CSnk9Q4w.mjs +9339 -0
  31. package/dist/shared/eslint-config.CWvTq0mr.mjs +2914 -0
  32. package/dist/shared/eslint-config.Ca4PTK8E.mjs +646 -0
  33. package/dist/shared/eslint-config.CmPTszkJ.mjs +3583 -0
  34. package/dist/shared/eslint-config.CqEANaNA.mjs +139622 -0
  35. package/dist/shared/eslint-config.CsePEcYJ.mjs +71 -0
  36. package/dist/shared/eslint-config.Cw6mETSZ.mjs +2580 -0
  37. package/dist/shared/eslint-config.DTVnsecK.mjs +1751 -0
  38. package/dist/shared/eslint-config.DWoU09EE.mjs +6958 -0
  39. package/dist/shared/eslint-config.DZvqTQUU.mjs +3818 -0
  40. package/dist/shared/eslint-config.Dhg7lT0g.mjs +1807 -0
  41. package/dist/shared/eslint-config.Du5y5qmf.mjs +200673 -0
  42. package/dist/shared/eslint-config.FKVuBSa4.mjs +394 -0
  43. package/dist/shared/eslint-config.I8d-HnmI.mjs +2654 -0
  44. package/dist/shared/eslint-config.YntqsQY1.mjs +40 -0
  45. package/dist/shared/eslint-config.uGTBNMD0.mjs +687 -0
  46. package/package.json +56 -0
@@ -0,0 +1,2580 @@
1
+ var dist$1 = {exports: {}};
2
+
3
+ var dist = dist$1.exports;
4
+
5
+ var hasRequiredDist;
6
+
7
+ function requireDist () {
8
+ if (hasRequiredDist) return dist$1.exports;
9
+ hasRequiredDist = 1;
10
+ (function (module, exports) {
11
+ (function (global, factory) {
12
+ factory(exports) ;
13
+ })(dist, (function (exports) {
14
+ function tokenToString(token) {
15
+ if (token.text !== undefined && token.text !== '') {
16
+ return `'${token.type}' with value '${token.text}'`;
17
+ }
18
+ else {
19
+ return `'${token.type}'`;
20
+ }
21
+ }
22
+ class NoParsletFoundError extends Error {
23
+ constructor(token) {
24
+ super(`No parslet found for token: ${tokenToString(token)}`);
25
+ this.token = token;
26
+ Object.setPrototypeOf(this, NoParsletFoundError.prototype);
27
+ }
28
+ getToken() {
29
+ return this.token;
30
+ }
31
+ }
32
+ class EarlyEndOfParseError extends Error {
33
+ constructor(token) {
34
+ super(`The parsing ended early. The next token was: ${tokenToString(token)}`);
35
+ this.token = token;
36
+ Object.setPrototypeOf(this, EarlyEndOfParseError.prototype);
37
+ }
38
+ getToken() {
39
+ return this.token;
40
+ }
41
+ }
42
+ class UnexpectedTypeError extends Error {
43
+ constructor(result, message) {
44
+ let error = `Unexpected type: '${result.type}'.`;
45
+ if (message !== undefined) {
46
+ error += ` Message: ${message}`;
47
+ }
48
+ super(error);
49
+ Object.setPrototypeOf(this, UnexpectedTypeError.prototype);
50
+ }
51
+ }
52
+ // export class UnexpectedTokenError extends Error {
53
+ // private expected: Token
54
+ // private found: Token
55
+ //
56
+ // constructor (expected: Token, found: Token) {
57
+ // super(`The parsing ended early. The next token was: ${tokenToString(token)}`)
58
+ //
59
+ // this.token = token
60
+ //
61
+ // Object.setPrototypeOf(this, EarlyEndOfParseError.prototype)
62
+ // }
63
+ //
64
+ // getToken() {
65
+ // return this.token
66
+ // }
67
+ // }
68
+
69
+ function makePunctuationRule(type) {
70
+ return text => {
71
+ if (text.startsWith(type)) {
72
+ return { type, text: type };
73
+ }
74
+ else {
75
+ return null;
76
+ }
77
+ };
78
+ }
79
+ function getQuoted(text) {
80
+ let position = 0;
81
+ let char;
82
+ const mark = text[0];
83
+ let escaped = false;
84
+ if (mark !== '\'' && mark !== '"') {
85
+ return null;
86
+ }
87
+ while (position < text.length) {
88
+ position++;
89
+ char = text[position];
90
+ if (!escaped && char === mark) {
91
+ position++;
92
+ break;
93
+ }
94
+ escaped = !escaped && char === '\\';
95
+ }
96
+ if (char !== mark) {
97
+ throw new Error('Unterminated String');
98
+ }
99
+ return text.slice(0, position);
100
+ }
101
+ const identifierStartRegex = /[$_\p{ID_Start}]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/u;
102
+ // A hyphen is not technically allowed, but to keep it liberal for now,
103
+ // adding it here
104
+ const identifierContinueRegex = /[$\-\p{ID_Continue}\u200C\u200D]|\\u\p{Hex_Digit}{4}|\\u\{0*(?:\p{Hex_Digit}{1,5}|10\p{Hex_Digit}{4})\}/u;
105
+ function getIdentifier(text) {
106
+ let char = text[0];
107
+ if (!identifierStartRegex.test(char)) {
108
+ return null;
109
+ }
110
+ let position = 1;
111
+ do {
112
+ char = text[position];
113
+ if (!identifierContinueRegex.test(char)) {
114
+ break;
115
+ }
116
+ position++;
117
+ } while (position < text.length);
118
+ return text.slice(0, position);
119
+ }
120
+ // we are a bit more liberal than TypeScript here and allow `NaN`, `Infinity` and `-Infinity`
121
+ const numberRegex = /^(NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity))/;
122
+ function getNumber(text) {
123
+ var _a, _b;
124
+ return (_b = (_a = numberRegex.exec(text)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : null;
125
+ }
126
+ const identifierRule = text => {
127
+ const value = getIdentifier(text);
128
+ if (value == null) {
129
+ return null;
130
+ }
131
+ return {
132
+ type: 'Identifier',
133
+ text: value
134
+ };
135
+ };
136
+ function makeKeyWordRule(type) {
137
+ return text => {
138
+ if (!text.startsWith(type)) {
139
+ return null;
140
+ }
141
+ const prepends = text[type.length];
142
+ if (prepends !== undefined && identifierContinueRegex.test(prepends)) {
143
+ return null;
144
+ }
145
+ return {
146
+ type,
147
+ text: type
148
+ };
149
+ };
150
+ }
151
+ const stringValueRule = text => {
152
+ const value = getQuoted(text);
153
+ if (value == null) {
154
+ return null;
155
+ }
156
+ return {
157
+ type: 'StringValue',
158
+ text: value
159
+ };
160
+ };
161
+ const eofRule = text => {
162
+ if (text.length > 0) {
163
+ return null;
164
+ }
165
+ return {
166
+ type: 'EOF',
167
+ text: ''
168
+ };
169
+ };
170
+ const numberRule = text => {
171
+ const value = getNumber(text);
172
+ if (value === null) {
173
+ return null;
174
+ }
175
+ return {
176
+ type: 'Number',
177
+ text: value
178
+ };
179
+ };
180
+ const rules = [
181
+ eofRule,
182
+ makePunctuationRule('=>'),
183
+ makePunctuationRule('('),
184
+ makePunctuationRule(')'),
185
+ makePunctuationRule('{'),
186
+ makePunctuationRule('}'),
187
+ makePunctuationRule('['),
188
+ makePunctuationRule(']'),
189
+ makePunctuationRule('|'),
190
+ makePunctuationRule('&'),
191
+ makePunctuationRule('<'),
192
+ makePunctuationRule('>'),
193
+ makePunctuationRule(','),
194
+ makePunctuationRule(';'),
195
+ makePunctuationRule('*'),
196
+ makePunctuationRule('?'),
197
+ makePunctuationRule('!'),
198
+ makePunctuationRule('='),
199
+ makePunctuationRule(':'),
200
+ makePunctuationRule('...'),
201
+ makePunctuationRule('.'),
202
+ makePunctuationRule('#'),
203
+ makePunctuationRule('~'),
204
+ makePunctuationRule('/'),
205
+ makePunctuationRule('@'),
206
+ makeKeyWordRule('undefined'),
207
+ makeKeyWordRule('null'),
208
+ makeKeyWordRule('function'),
209
+ makeKeyWordRule('this'),
210
+ makeKeyWordRule('new'),
211
+ makeKeyWordRule('module'),
212
+ makeKeyWordRule('event'),
213
+ makeKeyWordRule('external'),
214
+ makeKeyWordRule('typeof'),
215
+ makeKeyWordRule('keyof'),
216
+ makeKeyWordRule('readonly'),
217
+ makeKeyWordRule('import'),
218
+ makeKeyWordRule('is'),
219
+ makeKeyWordRule('in'),
220
+ makeKeyWordRule('asserts'),
221
+ numberRule,
222
+ identifierRule,
223
+ stringValueRule
224
+ ];
225
+ const breakingWhitespaceRegex = /^\s*\n\s*/;
226
+ class Lexer {
227
+ static create(text) {
228
+ const current = this.read(text);
229
+ text = current.text;
230
+ const next = this.read(text);
231
+ text = next.text;
232
+ return new Lexer(text, undefined, current.token, next.token);
233
+ }
234
+ constructor(text, previous, current, next) {
235
+ this.text = '';
236
+ this.text = text;
237
+ this.previous = previous;
238
+ this.current = current;
239
+ this.next = next;
240
+ }
241
+ static read(text, startOfLine = false) {
242
+ startOfLine = startOfLine || breakingWhitespaceRegex.test(text);
243
+ text = text.trim();
244
+ for (const rule of rules) {
245
+ const partial = rule(text);
246
+ if (partial !== null) {
247
+ const token = Object.assign(Object.assign({}, partial), { startOfLine });
248
+ text = text.slice(token.text.length);
249
+ return { text, token };
250
+ }
251
+ }
252
+ throw new Error('Unexpected Token ' + text);
253
+ }
254
+ advance() {
255
+ const next = Lexer.read(this.text);
256
+ return new Lexer(next.text, this.current, this.next, next.token);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Throws an error if the provided result is not a {@link RootResult}
262
+ */
263
+ function assertRootResult(result) {
264
+ if (result === undefined) {
265
+ throw new Error('Unexpected undefined');
266
+ }
267
+ if (result.type === 'JsdocTypeKeyValue' || result.type === 'JsdocTypeParameterList' ||
268
+ result.type === 'JsdocTypeProperty' || result.type === 'JsdocTypeReadonlyProperty' ||
269
+ result.type === 'JsdocTypeObjectField' || result.type === 'JsdocTypeJsdocObjectField' ||
270
+ result.type === 'JsdocTypeIndexSignature' || result.type === 'JsdocTypeMappedType') {
271
+ throw new UnexpectedTypeError(result);
272
+ }
273
+ return result;
274
+ }
275
+ function assertPlainKeyValueOrRootResult(result) {
276
+ if (result.type === 'JsdocTypeKeyValue') {
277
+ return assertPlainKeyValueResult(result);
278
+ }
279
+ return assertRootResult(result);
280
+ }
281
+ function assertPlainKeyValueOrNameResult(result) {
282
+ if (result.type === 'JsdocTypeName') {
283
+ return result;
284
+ }
285
+ return assertPlainKeyValueResult(result);
286
+ }
287
+ function assertPlainKeyValueResult(result) {
288
+ if (result.type !== 'JsdocTypeKeyValue') {
289
+ throw new UnexpectedTypeError(result);
290
+ }
291
+ return result;
292
+ }
293
+ function assertNumberOrVariadicNameResult(result) {
294
+ var _a;
295
+ if (result.type === 'JsdocTypeVariadic') {
296
+ if (((_a = result.element) === null || _a === void 0 ? void 0 : _a.type) === 'JsdocTypeName') {
297
+ return result;
298
+ }
299
+ throw new UnexpectedTypeError(result);
300
+ }
301
+ if (result.type !== 'JsdocTypeNumber' && result.type !== 'JsdocTypeName') {
302
+ throw new UnexpectedTypeError(result);
303
+ }
304
+ return result;
305
+ }
306
+ function isSquaredProperty(result) {
307
+ return result.type === 'JsdocTypeIndexSignature' || result.type === 'JsdocTypeMappedType';
308
+ }
309
+
310
+ // higher precedence = higher importance
311
+ var Precedence;
312
+ (function (Precedence) {
313
+ Precedence[Precedence["ALL"] = 0] = "ALL";
314
+ Precedence[Precedence["PARAMETER_LIST"] = 1] = "PARAMETER_LIST";
315
+ Precedence[Precedence["OBJECT"] = 2] = "OBJECT";
316
+ Precedence[Precedence["KEY_VALUE"] = 3] = "KEY_VALUE";
317
+ Precedence[Precedence["INDEX_BRACKETS"] = 4] = "INDEX_BRACKETS";
318
+ Precedence[Precedence["UNION"] = 5] = "UNION";
319
+ Precedence[Precedence["INTERSECTION"] = 6] = "INTERSECTION";
320
+ Precedence[Precedence["PREFIX"] = 7] = "PREFIX";
321
+ Precedence[Precedence["INFIX"] = 8] = "INFIX";
322
+ Precedence[Precedence["TUPLE"] = 9] = "TUPLE";
323
+ Precedence[Precedence["SYMBOL"] = 10] = "SYMBOL";
324
+ Precedence[Precedence["OPTIONAL"] = 11] = "OPTIONAL";
325
+ Precedence[Precedence["NULLABLE"] = 12] = "NULLABLE";
326
+ Precedence[Precedence["KEY_OF_TYPE_OF"] = 13] = "KEY_OF_TYPE_OF";
327
+ Precedence[Precedence["FUNCTION"] = 14] = "FUNCTION";
328
+ Precedence[Precedence["ARROW"] = 15] = "ARROW";
329
+ Precedence[Precedence["ARRAY_BRACKETS"] = 16] = "ARRAY_BRACKETS";
330
+ Precedence[Precedence["GENERIC"] = 17] = "GENERIC";
331
+ Precedence[Precedence["NAME_PATH"] = 18] = "NAME_PATH";
332
+ Precedence[Precedence["PARENTHESIS"] = 19] = "PARENTHESIS";
333
+ Precedence[Precedence["SPECIAL_TYPES"] = 20] = "SPECIAL_TYPES";
334
+ })(Precedence || (Precedence = {}));
335
+
336
+ class Parser {
337
+ constructor(grammar, textOrLexer, baseParser) {
338
+ this.grammar = grammar;
339
+ if (typeof textOrLexer === 'string') {
340
+ this._lexer = Lexer.create(textOrLexer);
341
+ }
342
+ else {
343
+ this._lexer = textOrLexer;
344
+ }
345
+ this.baseParser = baseParser;
346
+ }
347
+ get lexer() {
348
+ return this._lexer;
349
+ }
350
+ /**
351
+ * Parses a given string and throws an error if the parse ended before the end of the string.
352
+ */
353
+ parse() {
354
+ const result = this.parseType(Precedence.ALL);
355
+ if (this.lexer.current.type !== 'EOF') {
356
+ throw new EarlyEndOfParseError(this.lexer.current);
357
+ }
358
+ return result;
359
+ }
360
+ /**
361
+ * Parses with the current lexer and asserts that the result is a {@link RootResult}.
362
+ */
363
+ parseType(precedence) {
364
+ return assertRootResult(this.parseIntermediateType(precedence));
365
+ }
366
+ /**
367
+ * The main parsing function. First it tries to parse the current state in the prefix step, and then it continues
368
+ * to parse the state in the infix step.
369
+ */
370
+ parseIntermediateType(precedence) {
371
+ const result = this.tryParslets(null, precedence);
372
+ if (result === null) {
373
+ throw new NoParsletFoundError(this.lexer.current);
374
+ }
375
+ return this.parseInfixIntermediateType(result, precedence);
376
+ }
377
+ /**
378
+ * In the infix parsing step the parser continues to parse the current state with all parslets until none returns
379
+ * a result.
380
+ */
381
+ parseInfixIntermediateType(left, precedence) {
382
+ let result = this.tryParslets(left, precedence);
383
+ while (result !== null) {
384
+ left = result;
385
+ result = this.tryParslets(left, precedence);
386
+ }
387
+ return left;
388
+ }
389
+ /**
390
+ * Tries to parse the current state with all parslets in the grammar and returns the first non null result.
391
+ */
392
+ tryParslets(left, precedence) {
393
+ for (const parslet of this.grammar) {
394
+ const result = parslet(this, precedence, left);
395
+ if (result !== null) {
396
+ return result;
397
+ }
398
+ }
399
+ return null;
400
+ }
401
+ /**
402
+ * If the given type equals the current type of the {@link Lexer} advance the lexer. Return true if the lexer was
403
+ * advanced.
404
+ */
405
+ consume(types) {
406
+ if (!Array.isArray(types)) {
407
+ types = [types];
408
+ }
409
+ if (types.includes(this.lexer.current.type)) {
410
+ this._lexer = this.lexer.advance();
411
+ return true;
412
+ }
413
+ else {
414
+ return false;
415
+ }
416
+ }
417
+ acceptLexerState(parser) {
418
+ this._lexer = parser.lexer;
419
+ }
420
+ }
421
+
422
+ function isQuestionMarkUnknownType(next) {
423
+ return next === 'EOF' || next === '|' || next === ',' || next === ')' || next === '>';
424
+ }
425
+
426
+ const nullableParslet = (parser, precedence, left) => {
427
+ const type = parser.lexer.current.type;
428
+ const next = parser.lexer.next.type;
429
+ const accept = ((left == null) && type === '?' && !isQuestionMarkUnknownType(next)) ||
430
+ ((left != null) && type === '?');
431
+ if (!accept) {
432
+ return null;
433
+ }
434
+ parser.consume('?');
435
+ if (left == null) {
436
+ return {
437
+ type: 'JsdocTypeNullable',
438
+ element: parser.parseType(Precedence.NULLABLE),
439
+ meta: {
440
+ position: 'prefix'
441
+ }
442
+ };
443
+ }
444
+ else {
445
+ return {
446
+ type: 'JsdocTypeNullable',
447
+ element: assertRootResult(left),
448
+ meta: {
449
+ position: 'suffix'
450
+ }
451
+ };
452
+ }
453
+ };
454
+
455
+ function composeParslet(options) {
456
+ const parslet = (parser, curPrecedence, left) => {
457
+ const type = parser.lexer.current.type;
458
+ const next = parser.lexer.next.type;
459
+ if (left === null) {
460
+ if ('parsePrefix' in options) {
461
+ if (options.accept(type, next)) {
462
+ return options.parsePrefix(parser);
463
+ }
464
+ }
465
+ }
466
+ else {
467
+ if ('parseInfix' in options) {
468
+ if (options.precedence > curPrecedence && options.accept(type, next)) {
469
+ return options.parseInfix(parser, left);
470
+ }
471
+ }
472
+ }
473
+ return null;
474
+ };
475
+ // for debugging
476
+ Object.defineProperty(parslet, 'name', {
477
+ value: options.name
478
+ });
479
+ return parslet;
480
+ }
481
+
482
+ const optionalParslet = composeParslet({
483
+ name: 'optionalParslet',
484
+ accept: type => type === '=',
485
+ precedence: Precedence.OPTIONAL,
486
+ parsePrefix: parser => {
487
+ parser.consume('=');
488
+ return {
489
+ type: 'JsdocTypeOptional',
490
+ element: parser.parseType(Precedence.OPTIONAL),
491
+ meta: {
492
+ position: 'prefix'
493
+ }
494
+ };
495
+ },
496
+ parseInfix: (parser, left) => {
497
+ parser.consume('=');
498
+ return {
499
+ type: 'JsdocTypeOptional',
500
+ element: assertRootResult(left),
501
+ meta: {
502
+ position: 'suffix'
503
+ }
504
+ };
505
+ }
506
+ });
507
+
508
+ const numberParslet = composeParslet({
509
+ name: 'numberParslet',
510
+ accept: type => type === 'Number',
511
+ parsePrefix: parser => {
512
+ const value = parseFloat(parser.lexer.current.text);
513
+ parser.consume('Number');
514
+ return {
515
+ type: 'JsdocTypeNumber',
516
+ value
517
+ };
518
+ }
519
+ });
520
+
521
+ const parenthesisParslet = composeParslet({
522
+ name: 'parenthesisParslet',
523
+ accept: type => type === '(',
524
+ parsePrefix: parser => {
525
+ parser.consume('(');
526
+ if (parser.consume(')')) {
527
+ return {
528
+ type: 'JsdocTypeParameterList',
529
+ elements: []
530
+ };
531
+ }
532
+ const result = parser.parseIntermediateType(Precedence.ALL);
533
+ if (!parser.consume(')')) {
534
+ throw new Error('Unterminated parenthesis');
535
+ }
536
+ if (result.type === 'JsdocTypeParameterList') {
537
+ return result;
538
+ }
539
+ else if (result.type === 'JsdocTypeKeyValue') {
540
+ return {
541
+ type: 'JsdocTypeParameterList',
542
+ elements: [result]
543
+ };
544
+ }
545
+ return {
546
+ type: 'JsdocTypeParenthesis',
547
+ element: assertRootResult(result)
548
+ };
549
+ }
550
+ });
551
+
552
+ const specialTypesParslet = composeParslet({
553
+ name: 'specialTypesParslet',
554
+ accept: (type, next) => (type === '?' && isQuestionMarkUnknownType(next)) ||
555
+ type === 'null' || type === 'undefined' || type === '*',
556
+ parsePrefix: parser => {
557
+ if (parser.consume('null')) {
558
+ return {
559
+ type: 'JsdocTypeNull'
560
+ };
561
+ }
562
+ if (parser.consume('undefined')) {
563
+ return {
564
+ type: 'JsdocTypeUndefined'
565
+ };
566
+ }
567
+ if (parser.consume('*')) {
568
+ return {
569
+ type: 'JsdocTypeAny'
570
+ };
571
+ }
572
+ if (parser.consume('?')) {
573
+ return {
574
+ type: 'JsdocTypeUnknown'
575
+ };
576
+ }
577
+ throw new Error('Unacceptable token: ' + parser.lexer.current.text);
578
+ }
579
+ });
580
+
581
+ const notNullableParslet = composeParslet({
582
+ name: 'notNullableParslet',
583
+ accept: type => type === '!',
584
+ precedence: Precedence.NULLABLE,
585
+ parsePrefix: parser => {
586
+ parser.consume('!');
587
+ return {
588
+ type: 'JsdocTypeNotNullable',
589
+ element: parser.parseType(Precedence.NULLABLE),
590
+ meta: {
591
+ position: 'prefix'
592
+ }
593
+ };
594
+ },
595
+ parseInfix: (parser, left) => {
596
+ parser.consume('!');
597
+ return {
598
+ type: 'JsdocTypeNotNullable',
599
+ element: assertRootResult(left),
600
+ meta: {
601
+ position: 'suffix'
602
+ }
603
+ };
604
+ }
605
+ });
606
+
607
+ function createParameterListParslet({ allowTrailingComma }) {
608
+ return composeParslet({
609
+ name: 'parameterListParslet',
610
+ accept: type => type === ',',
611
+ precedence: Precedence.PARAMETER_LIST,
612
+ parseInfix: (parser, left) => {
613
+ const elements = [
614
+ assertPlainKeyValueOrRootResult(left)
615
+ ];
616
+ parser.consume(',');
617
+ do {
618
+ try {
619
+ const next = parser.parseIntermediateType(Precedence.PARAMETER_LIST);
620
+ elements.push(assertPlainKeyValueOrRootResult(next));
621
+ }
622
+ catch (e) {
623
+ if (e instanceof NoParsletFoundError) {
624
+ break;
625
+ }
626
+ else {
627
+ throw e;
628
+ }
629
+ }
630
+ } while (parser.consume(','));
631
+ if (elements.length > 0 && elements.slice(0, -1).some(e => e.type === 'JsdocTypeVariadic')) {
632
+ throw new Error('Only the last parameter may be a rest parameter');
633
+ }
634
+ return {
635
+ type: 'JsdocTypeParameterList',
636
+ elements
637
+ };
638
+ }
639
+ });
640
+ }
641
+
642
+ const genericParslet = composeParslet({
643
+ name: 'genericParslet',
644
+ accept: (type, next) => type === '<' || (type === '.' && next === '<'),
645
+ precedence: Precedence.GENERIC,
646
+ parseInfix: (parser, left) => {
647
+ const dot = parser.consume('.');
648
+ parser.consume('<');
649
+ const objects = [];
650
+ do {
651
+ objects.push(parser.parseType(Precedence.PARAMETER_LIST));
652
+ } while (parser.consume(','));
653
+ if (!parser.consume('>')) {
654
+ throw new Error('Unterminated generic parameter list');
655
+ }
656
+ return {
657
+ type: 'JsdocTypeGeneric',
658
+ left: assertRootResult(left),
659
+ elements: objects,
660
+ meta: {
661
+ brackets: 'angle',
662
+ dot
663
+ }
664
+ };
665
+ }
666
+ });
667
+
668
+ const unionParslet = composeParslet({
669
+ name: 'unionParslet',
670
+ accept: type => type === '|',
671
+ precedence: Precedence.UNION,
672
+ parseInfix: (parser, left) => {
673
+ parser.consume('|');
674
+ const elements = [];
675
+ do {
676
+ elements.push(parser.parseType(Precedence.UNION));
677
+ } while (parser.consume('|'));
678
+ return {
679
+ type: 'JsdocTypeUnion',
680
+ elements: [assertRootResult(left), ...elements]
681
+ };
682
+ }
683
+ });
684
+
685
+ const baseGrammar = [
686
+ nullableParslet,
687
+ optionalParslet,
688
+ numberParslet,
689
+ parenthesisParslet,
690
+ specialTypesParslet,
691
+ notNullableParslet,
692
+ createParameterListParslet({
693
+ allowTrailingComma: true
694
+ }),
695
+ genericParslet,
696
+ unionParslet,
697
+ optionalParslet
698
+ ];
699
+
700
+ function createNamePathParslet({ allowSquareBracketsOnAnyType, allowJsdocNamePaths, pathGrammar }) {
701
+ return function namePathParslet(parser, precedence, left) {
702
+ if ((left == null) || precedence >= Precedence.NAME_PATH) {
703
+ return null;
704
+ }
705
+ const type = parser.lexer.current.type;
706
+ const next = parser.lexer.next.type;
707
+ const accept = (type === '.' && next !== '<') ||
708
+ (type === '[' && (allowSquareBracketsOnAnyType || left.type === 'JsdocTypeName')) ||
709
+ (allowJsdocNamePaths && (type === '~' || type === '#'));
710
+ if (!accept) {
711
+ return null;
712
+ }
713
+ let pathType;
714
+ let brackets = false;
715
+ if (parser.consume('.')) {
716
+ pathType = 'property';
717
+ }
718
+ else if (parser.consume('[')) {
719
+ pathType = 'property-brackets';
720
+ brackets = true;
721
+ }
722
+ else if (parser.consume('~')) {
723
+ pathType = 'inner';
724
+ }
725
+ else {
726
+ parser.consume('#');
727
+ pathType = 'instance';
728
+ }
729
+ const pathParser = pathGrammar !== null
730
+ ? new Parser(pathGrammar, parser.lexer, parser)
731
+ : parser;
732
+ const parsed = pathParser.parseIntermediateType(Precedence.NAME_PATH);
733
+ parser.acceptLexerState(pathParser);
734
+ let right;
735
+ switch (parsed.type) {
736
+ case 'JsdocTypeName':
737
+ right = {
738
+ type: 'JsdocTypeProperty',
739
+ value: parsed.value,
740
+ meta: {
741
+ quote: undefined
742
+ }
743
+ };
744
+ break;
745
+ case 'JsdocTypeNumber':
746
+ right = {
747
+ type: 'JsdocTypeProperty',
748
+ value: parsed.value.toString(10),
749
+ meta: {
750
+ quote: undefined
751
+ }
752
+ };
753
+ break;
754
+ case 'JsdocTypeStringValue':
755
+ right = {
756
+ type: 'JsdocTypeProperty',
757
+ value: parsed.value,
758
+ meta: {
759
+ quote: parsed.meta.quote
760
+ }
761
+ };
762
+ break;
763
+ case 'JsdocTypeSpecialNamePath':
764
+ if (parsed.specialType === 'event') {
765
+ right = parsed;
766
+ }
767
+ else {
768
+ throw new UnexpectedTypeError(parsed, 'Type \'JsdocTypeSpecialNamePath\' is only allowed with specialType \'event\'');
769
+ }
770
+ break;
771
+ default:
772
+ throw new UnexpectedTypeError(parsed, 'Expecting \'JsdocTypeName\', \'JsdocTypeNumber\', \'JsdocStringValue\' or \'JsdocTypeSpecialNamePath\'');
773
+ }
774
+ if (brackets && !parser.consume(']')) {
775
+ const token = parser.lexer.current;
776
+ throw new Error(`Unterminated square brackets. Next token is '${token.type}' ` +
777
+ `with text '${token.text}'`);
778
+ }
779
+ return {
780
+ type: 'JsdocTypeNamePath',
781
+ left: assertRootResult(left),
782
+ right,
783
+ pathType
784
+ };
785
+ };
786
+ }
787
+
788
+ function createNameParslet({ allowedAdditionalTokens }) {
789
+ return composeParslet({
790
+ name: 'nameParslet',
791
+ accept: type => type === 'Identifier' || type === 'this' || type === 'new' || allowedAdditionalTokens.includes(type),
792
+ parsePrefix: parser => {
793
+ const { type, text } = parser.lexer.current;
794
+ parser.consume(type);
795
+ return {
796
+ type: 'JsdocTypeName',
797
+ value: text
798
+ };
799
+ }
800
+ });
801
+ }
802
+
803
+ const stringValueParslet = composeParslet({
804
+ name: 'stringValueParslet',
805
+ accept: type => type === 'StringValue',
806
+ parsePrefix: parser => {
807
+ const text = parser.lexer.current.text;
808
+ parser.consume('StringValue');
809
+ return {
810
+ type: 'JsdocTypeStringValue',
811
+ value: text.slice(1, -1),
812
+ meta: {
813
+ quote: text[0] === '\'' ? 'single' : 'double'
814
+ }
815
+ };
816
+ }
817
+ });
818
+
819
+ function createSpecialNamePathParslet({ pathGrammar, allowedTypes }) {
820
+ return composeParslet({
821
+ name: 'specialNamePathParslet',
822
+ accept: type => allowedTypes.includes(type),
823
+ parsePrefix: parser => {
824
+ const type = parser.lexer.current.type;
825
+ parser.consume(type);
826
+ if (!parser.consume(':')) {
827
+ return {
828
+ type: 'JsdocTypeName',
829
+ value: type
830
+ };
831
+ }
832
+ let result;
833
+ let token = parser.lexer.current;
834
+ if (parser.consume('StringValue')) {
835
+ result = {
836
+ type: 'JsdocTypeSpecialNamePath',
837
+ value: token.text.slice(1, -1),
838
+ specialType: type,
839
+ meta: {
840
+ quote: token.text[0] === '\'' ? 'single' : 'double'
841
+ }
842
+ };
843
+ }
844
+ else {
845
+ let value = '';
846
+ const allowed = ['Identifier', '@', '/'];
847
+ while (allowed.some(type => parser.consume(type))) {
848
+ value += token.text;
849
+ token = parser.lexer.current;
850
+ }
851
+ result = {
852
+ type: 'JsdocTypeSpecialNamePath',
853
+ value,
854
+ specialType: type,
855
+ meta: {
856
+ quote: undefined
857
+ }
858
+ };
859
+ }
860
+ const moduleParser = new Parser(pathGrammar, parser.lexer, parser);
861
+ const moduleResult = moduleParser.parseInfixIntermediateType(result, Precedence.ALL);
862
+ parser.acceptLexerState(moduleParser);
863
+ return assertRootResult(moduleResult);
864
+ }
865
+ });
866
+ }
867
+
868
+ const basePathGrammar = [
869
+ createNameParslet({
870
+ allowedAdditionalTokens: ['external', 'module']
871
+ }),
872
+ stringValueParslet,
873
+ numberParslet,
874
+ createNamePathParslet({
875
+ allowSquareBracketsOnAnyType: false,
876
+ allowJsdocNamePaths: true,
877
+ pathGrammar: null
878
+ })
879
+ ];
880
+ const pathGrammar = [
881
+ ...basePathGrammar,
882
+ createSpecialNamePathParslet({
883
+ allowedTypes: ['event'],
884
+ pathGrammar: basePathGrammar
885
+ })
886
+ ];
887
+
888
+ function getParameters(value) {
889
+ let parameters;
890
+ if (value.type === 'JsdocTypeParameterList') {
891
+ parameters = value.elements;
892
+ }
893
+ else if (value.type === 'JsdocTypeParenthesis') {
894
+ parameters = [value.element];
895
+ }
896
+ else {
897
+ throw new UnexpectedTypeError(value);
898
+ }
899
+ return parameters.map(p => assertPlainKeyValueOrRootResult(p));
900
+ }
901
+ function getUnnamedParameters(value) {
902
+ const parameters = getParameters(value);
903
+ if (parameters.some(p => p.type === 'JsdocTypeKeyValue')) {
904
+ throw new Error('No parameter should be named');
905
+ }
906
+ return parameters;
907
+ }
908
+ function createFunctionParslet({ allowNamedParameters, allowNoReturnType, allowWithoutParenthesis, allowNewAsFunctionKeyword }) {
909
+ return composeParslet({
910
+ name: 'functionParslet',
911
+ accept: (type, next) => type === 'function' || (allowNewAsFunctionKeyword && type === 'new' && next === '('),
912
+ parsePrefix: parser => {
913
+ const newKeyword = parser.consume('new');
914
+ parser.consume('function');
915
+ const hasParenthesis = parser.lexer.current.type === '(';
916
+ if (!hasParenthesis) {
917
+ if (!allowWithoutParenthesis) {
918
+ throw new Error('function is missing parameter list');
919
+ }
920
+ return {
921
+ type: 'JsdocTypeName',
922
+ value: 'function'
923
+ };
924
+ }
925
+ let result = {
926
+ type: 'JsdocTypeFunction',
927
+ parameters: [],
928
+ arrow: false,
929
+ constructor: newKeyword,
930
+ parenthesis: hasParenthesis
931
+ };
932
+ const value = parser.parseIntermediateType(Precedence.FUNCTION);
933
+ if (allowNamedParameters === undefined) {
934
+ result.parameters = getUnnamedParameters(value);
935
+ }
936
+ else if (newKeyword && value.type === 'JsdocTypeFunction' && value.arrow) {
937
+ result = value;
938
+ result.constructor = true;
939
+ return result;
940
+ }
941
+ else {
942
+ result.parameters = getParameters(value);
943
+ for (const p of result.parameters) {
944
+ if (p.type === 'JsdocTypeKeyValue' && (!allowNamedParameters.includes(p.key))) {
945
+ throw new Error(`only allowed named parameters are ${allowNamedParameters.join(', ')} but got ${p.type}`);
946
+ }
947
+ }
948
+ }
949
+ if (parser.consume(':')) {
950
+ result.returnType = parser.parseType(Precedence.PREFIX);
951
+ }
952
+ else {
953
+ if (!allowNoReturnType) {
954
+ throw new Error('function is missing return type');
955
+ }
956
+ }
957
+ return result;
958
+ }
959
+ });
960
+ }
961
+
962
+ function createVariadicParslet({ allowPostfix, allowEnclosingBrackets }) {
963
+ return composeParslet({
964
+ name: 'variadicParslet',
965
+ accept: type => type === '...',
966
+ precedence: Precedence.PREFIX,
967
+ parsePrefix: parser => {
968
+ parser.consume('...');
969
+ const brackets = allowEnclosingBrackets && parser.consume('[');
970
+ try {
971
+ const element = parser.parseType(Precedence.PREFIX);
972
+ if (brackets && !parser.consume(']')) {
973
+ throw new Error('Unterminated variadic type. Missing \']\'');
974
+ }
975
+ return {
976
+ type: 'JsdocTypeVariadic',
977
+ element: assertRootResult(element),
978
+ meta: {
979
+ position: 'prefix',
980
+ squareBrackets: brackets
981
+ }
982
+ };
983
+ }
984
+ catch (e) {
985
+ if (e instanceof NoParsletFoundError) {
986
+ if (brackets) {
987
+ throw new Error('Empty square brackets for variadic are not allowed.');
988
+ }
989
+ return {
990
+ type: 'JsdocTypeVariadic',
991
+ meta: {
992
+ position: undefined,
993
+ squareBrackets: false
994
+ }
995
+ };
996
+ }
997
+ else {
998
+ throw e;
999
+ }
1000
+ }
1001
+ },
1002
+ parseInfix: allowPostfix
1003
+ ? (parser, left) => {
1004
+ parser.consume('...');
1005
+ return {
1006
+ type: 'JsdocTypeVariadic',
1007
+ element: assertRootResult(left),
1008
+ meta: {
1009
+ position: 'suffix',
1010
+ squareBrackets: false
1011
+ }
1012
+ };
1013
+ }
1014
+ : undefined
1015
+ });
1016
+ }
1017
+
1018
+ const symbolParslet = composeParslet({
1019
+ name: 'symbolParslet',
1020
+ accept: type => type === '(',
1021
+ precedence: Precedence.SYMBOL,
1022
+ parseInfix: (parser, left) => {
1023
+ if (left.type !== 'JsdocTypeName') {
1024
+ throw new Error('Symbol expects a name on the left side. (Reacting on \'(\')');
1025
+ }
1026
+ parser.consume('(');
1027
+ const result = {
1028
+ type: 'JsdocTypeSymbol',
1029
+ value: left.value
1030
+ };
1031
+ if (!parser.consume(')')) {
1032
+ const next = parser.parseIntermediateType(Precedence.SYMBOL);
1033
+ result.element = assertNumberOrVariadicNameResult(next);
1034
+ if (!parser.consume(')')) {
1035
+ throw new Error('Symbol does not end after value');
1036
+ }
1037
+ }
1038
+ return result;
1039
+ }
1040
+ });
1041
+
1042
+ const arrayBracketsParslet = composeParslet({
1043
+ name: 'arrayBracketsParslet',
1044
+ precedence: Precedence.ARRAY_BRACKETS,
1045
+ accept: (type, next) => type === '[' && next === ']',
1046
+ parseInfix: (parser, left) => {
1047
+ parser.consume('[');
1048
+ parser.consume(']');
1049
+ return {
1050
+ type: 'JsdocTypeGeneric',
1051
+ left: {
1052
+ type: 'JsdocTypeName',
1053
+ value: 'Array'
1054
+ },
1055
+ elements: [
1056
+ assertRootResult(left)
1057
+ ],
1058
+ meta: {
1059
+ brackets: 'square',
1060
+ dot: false
1061
+ }
1062
+ };
1063
+ }
1064
+ });
1065
+
1066
+ function createObjectParslet({ objectFieldGrammar, allowKeyTypes }) {
1067
+ return composeParslet({
1068
+ name: 'objectParslet',
1069
+ accept: type => type === '{',
1070
+ parsePrefix: parser => {
1071
+ parser.consume('{');
1072
+ const result = {
1073
+ type: 'JsdocTypeObject',
1074
+ meta: {
1075
+ separator: 'comma'
1076
+ },
1077
+ elements: []
1078
+ };
1079
+ if (!parser.consume('}')) {
1080
+ let separator;
1081
+ const fieldParser = new Parser(objectFieldGrammar, parser.lexer, parser);
1082
+ while (true) {
1083
+ fieldParser.acceptLexerState(parser);
1084
+ let field = fieldParser.parseIntermediateType(Precedence.OBJECT);
1085
+ parser.acceptLexerState(fieldParser);
1086
+ if (field === undefined && allowKeyTypes) {
1087
+ field = parser.parseIntermediateType(Precedence.OBJECT);
1088
+ }
1089
+ let optional = false;
1090
+ if (field.type === 'JsdocTypeNullable') {
1091
+ optional = true;
1092
+ field = field.element;
1093
+ }
1094
+ if (field.type === 'JsdocTypeNumber' || field.type === 'JsdocTypeName' || field.type === 'JsdocTypeStringValue') {
1095
+ let quote;
1096
+ if (field.type === 'JsdocTypeStringValue') {
1097
+ quote = field.meta.quote;
1098
+ }
1099
+ result.elements.push({
1100
+ type: 'JsdocTypeObjectField',
1101
+ key: field.value.toString(),
1102
+ right: undefined,
1103
+ optional,
1104
+ readonly: false,
1105
+ meta: {
1106
+ quote
1107
+ }
1108
+ });
1109
+ }
1110
+ else if (field.type === 'JsdocTypeObjectField' || field.type === 'JsdocTypeJsdocObjectField') {
1111
+ result.elements.push(field);
1112
+ }
1113
+ else {
1114
+ throw new UnexpectedTypeError(field);
1115
+ }
1116
+ if (parser.lexer.current.startOfLine) {
1117
+ separator = 'linebreak';
1118
+ }
1119
+ else if (parser.consume(',')) {
1120
+ separator = 'comma';
1121
+ }
1122
+ else if (parser.consume(';')) {
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 !== null && separator !== void 0 ? separator : 'comma'; // TODO: use undefined here
1134
+ if (!parser.consume('}')) {
1135
+ throw new Error('Unterminated record type. Missing \'}\'');
1136
+ }
1137
+ }
1138
+ return result;
1139
+ }
1140
+ });
1141
+ }
1142
+
1143
+ function createObjectFieldParslet({ allowSquaredProperties, allowKeyTypes, allowReadonly, allowOptional }) {
1144
+ return composeParslet({
1145
+ name: 'objectFieldParslet',
1146
+ precedence: Precedence.KEY_VALUE,
1147
+ accept: type => type === ':',
1148
+ parseInfix: (parser, left) => {
1149
+ var _a;
1150
+ let optional = false;
1151
+ let readonlyProperty = false;
1152
+ if (allowOptional && left.type === 'JsdocTypeNullable') {
1153
+ optional = true;
1154
+ left = left.element;
1155
+ }
1156
+ if (allowReadonly && left.type === 'JsdocTypeReadonlyProperty') {
1157
+ readonlyProperty = true;
1158
+ left = left.element;
1159
+ }
1160
+ // object parslet uses a special grammar and for the value we want to switch back to the parent
1161
+ const parentParser = (_a = parser.baseParser) !== null && _a !== void 0 ? _a : parser;
1162
+ parentParser.acceptLexerState(parser);
1163
+ if (left.type === 'JsdocTypeNumber' || left.type === 'JsdocTypeName' || left.type === 'JsdocTypeStringValue' ||
1164
+ isSquaredProperty(left)) {
1165
+ if (isSquaredProperty(left) && !allowSquaredProperties) {
1166
+ throw new UnexpectedTypeError(left);
1167
+ }
1168
+ parentParser.consume(':');
1169
+ let quote;
1170
+ if (left.type === 'JsdocTypeStringValue') {
1171
+ quote = left.meta.quote;
1172
+ }
1173
+ const right = parentParser.parseType(Precedence.KEY_VALUE);
1174
+ parser.acceptLexerState(parentParser);
1175
+ return {
1176
+ type: 'JsdocTypeObjectField',
1177
+ key: isSquaredProperty(left) ? left : left.value.toString(),
1178
+ right,
1179
+ optional,
1180
+ readonly: readonlyProperty,
1181
+ meta: {
1182
+ quote
1183
+ }
1184
+ };
1185
+ }
1186
+ else {
1187
+ if (!allowKeyTypes) {
1188
+ throw new UnexpectedTypeError(left);
1189
+ }
1190
+ parentParser.consume(':');
1191
+ const right = parentParser.parseType(Precedence.KEY_VALUE);
1192
+ parser.acceptLexerState(parentParser);
1193
+ return {
1194
+ type: 'JsdocTypeJsdocObjectField',
1195
+ left: assertRootResult(left),
1196
+ right
1197
+ };
1198
+ }
1199
+ }
1200
+ });
1201
+ }
1202
+
1203
+ function createKeyValueParslet({ allowOptional, allowVariadic }) {
1204
+ return composeParslet({
1205
+ name: 'keyValueParslet',
1206
+ precedence: Precedence.KEY_VALUE,
1207
+ accept: type => type === ':',
1208
+ parseInfix: (parser, left) => {
1209
+ let optional = false;
1210
+ let variadic = false;
1211
+ if (allowOptional && left.type === 'JsdocTypeNullable') {
1212
+ optional = true;
1213
+ left = left.element;
1214
+ }
1215
+ if (allowVariadic && left.type === 'JsdocTypeVariadic' && left.element !== undefined) {
1216
+ variadic = true;
1217
+ left = left.element;
1218
+ }
1219
+ if (left.type !== 'JsdocTypeName') {
1220
+ throw new UnexpectedTypeError(left);
1221
+ }
1222
+ parser.consume(':');
1223
+ const right = parser.parseType(Precedence.KEY_VALUE);
1224
+ return {
1225
+ type: 'JsdocTypeKeyValue',
1226
+ key: left.value,
1227
+ right,
1228
+ optional,
1229
+ variadic
1230
+ };
1231
+ }
1232
+ });
1233
+ }
1234
+
1235
+ const jsdocBaseGrammar = [
1236
+ ...baseGrammar,
1237
+ createFunctionParslet({
1238
+ allowWithoutParenthesis: true,
1239
+ allowNamedParameters: ['this', 'new'],
1240
+ allowNoReturnType: true,
1241
+ allowNewAsFunctionKeyword: false
1242
+ }),
1243
+ stringValueParslet,
1244
+ createSpecialNamePathParslet({
1245
+ allowedTypes: ['module', 'external', 'event'],
1246
+ pathGrammar
1247
+ }),
1248
+ createVariadicParslet({
1249
+ allowEnclosingBrackets: true,
1250
+ allowPostfix: true
1251
+ }),
1252
+ createNameParslet({
1253
+ allowedAdditionalTokens: ['keyof']
1254
+ }),
1255
+ symbolParslet,
1256
+ arrayBracketsParslet,
1257
+ createNamePathParslet({
1258
+ allowSquareBracketsOnAnyType: false,
1259
+ allowJsdocNamePaths: true,
1260
+ pathGrammar
1261
+ })
1262
+ ];
1263
+ const jsdocGrammar = [
1264
+ ...jsdocBaseGrammar,
1265
+ createObjectParslet({
1266
+ // jsdoc syntax allows full types as keys, so we need to pull in the full grammar here
1267
+ // we leave out the object type deliberately
1268
+ objectFieldGrammar: [
1269
+ createNameParslet({
1270
+ allowedAdditionalTokens: ['module', 'in']
1271
+ }),
1272
+ createObjectFieldParslet({
1273
+ allowSquaredProperties: false,
1274
+ allowKeyTypes: true,
1275
+ allowOptional: false,
1276
+ allowReadonly: false
1277
+ }),
1278
+ ...jsdocBaseGrammar
1279
+ ],
1280
+ allowKeyTypes: true
1281
+ }),
1282
+ createKeyValueParslet({
1283
+ allowOptional: true,
1284
+ allowVariadic: true
1285
+ })
1286
+ ];
1287
+
1288
+ const typeOfParslet = composeParslet({
1289
+ name: 'typeOfParslet',
1290
+ accept: type => type === 'typeof',
1291
+ parsePrefix: parser => {
1292
+ parser.consume('typeof');
1293
+ return {
1294
+ type: 'JsdocTypeTypeof',
1295
+ element: assertRootResult(parser.parseType(Precedence.KEY_OF_TYPE_OF))
1296
+ };
1297
+ }
1298
+ });
1299
+
1300
+ const objectFieldGrammar$1 = [
1301
+ createNameParslet({
1302
+ allowedAdditionalTokens: ['module', 'keyof', 'event', 'external', 'in']
1303
+ }),
1304
+ nullableParslet,
1305
+ optionalParslet,
1306
+ stringValueParslet,
1307
+ numberParslet,
1308
+ createObjectFieldParslet({
1309
+ allowSquaredProperties: false,
1310
+ allowKeyTypes: false,
1311
+ allowOptional: false,
1312
+ allowReadonly: false
1313
+ })
1314
+ ];
1315
+ const closureGrammar = [
1316
+ ...baseGrammar,
1317
+ createObjectParslet({
1318
+ allowKeyTypes: false,
1319
+ objectFieldGrammar: objectFieldGrammar$1
1320
+ }),
1321
+ createNameParslet({
1322
+ allowedAdditionalTokens: ['event', 'external', 'in']
1323
+ }),
1324
+ typeOfParslet,
1325
+ createFunctionParslet({
1326
+ allowWithoutParenthesis: false,
1327
+ allowNamedParameters: ['this', 'new'],
1328
+ allowNoReturnType: true,
1329
+ allowNewAsFunctionKeyword: false
1330
+ }),
1331
+ createVariadicParslet({
1332
+ allowEnclosingBrackets: false,
1333
+ allowPostfix: false
1334
+ }),
1335
+ // additional name parslet is needed for some special cases
1336
+ createNameParslet({
1337
+ allowedAdditionalTokens: ['keyof']
1338
+ }),
1339
+ createSpecialNamePathParslet({
1340
+ allowedTypes: ['module'],
1341
+ pathGrammar
1342
+ }),
1343
+ createNamePathParslet({
1344
+ allowSquareBracketsOnAnyType: false,
1345
+ allowJsdocNamePaths: true,
1346
+ pathGrammar
1347
+ }),
1348
+ createKeyValueParslet({
1349
+ allowOptional: false,
1350
+ allowVariadic: false
1351
+ }),
1352
+ symbolParslet
1353
+ ];
1354
+
1355
+ const assertsParslet = composeParslet({
1356
+ name: 'assertsParslet',
1357
+ accept: type => type === 'asserts',
1358
+ parsePrefix: (parser) => {
1359
+ parser.consume('asserts');
1360
+ const left = parser.parseIntermediateType(Precedence.SYMBOL);
1361
+ if (left.type !== 'JsdocTypeName') {
1362
+ throw new UnexpectedTypeError(left, 'A typescript asserts always has to have a name on the left side.');
1363
+ }
1364
+ parser.consume('is');
1365
+ return {
1366
+ type: 'JsdocTypeAsserts',
1367
+ left,
1368
+ right: assertRootResult(parser.parseIntermediateType(Precedence.INFIX))
1369
+ };
1370
+ }
1371
+ });
1372
+
1373
+ function createTupleParslet({ allowQuestionMark }) {
1374
+ return composeParslet({
1375
+ name: 'tupleParslet',
1376
+ accept: type => type === '[',
1377
+ parsePrefix: parser => {
1378
+ parser.consume('[');
1379
+ const result = {
1380
+ type: 'JsdocTypeTuple',
1381
+ elements: []
1382
+ };
1383
+ if (parser.consume(']')) {
1384
+ return result;
1385
+ }
1386
+ const typeList = parser.parseIntermediateType(Precedence.ALL);
1387
+ if (typeList.type === 'JsdocTypeParameterList') {
1388
+ if (typeList.elements[0].type === 'JsdocTypeKeyValue') {
1389
+ result.elements = typeList.elements.map(assertPlainKeyValueResult);
1390
+ }
1391
+ else {
1392
+ result.elements = typeList.elements.map(assertRootResult);
1393
+ }
1394
+ }
1395
+ else {
1396
+ if (typeList.type === 'JsdocTypeKeyValue') {
1397
+ result.elements = [assertPlainKeyValueResult(typeList)];
1398
+ }
1399
+ else {
1400
+ result.elements = [assertRootResult(typeList)];
1401
+ }
1402
+ }
1403
+ if (!parser.consume(']')) {
1404
+ throw new Error('Unterminated \'[\'');
1405
+ }
1406
+ if (result.elements.some((e) => e.type === 'JsdocTypeUnknown')) {
1407
+ throw new Error('Question mark in tuple not allowed');
1408
+ }
1409
+ return result;
1410
+ }
1411
+ });
1412
+ }
1413
+
1414
+ const keyOfParslet = composeParslet({
1415
+ name: 'keyOfParslet',
1416
+ accept: type => type === 'keyof',
1417
+ parsePrefix: parser => {
1418
+ parser.consume('keyof');
1419
+ return {
1420
+ type: 'JsdocTypeKeyof',
1421
+ element: assertRootResult(parser.parseType(Precedence.KEY_OF_TYPE_OF))
1422
+ };
1423
+ }
1424
+ });
1425
+
1426
+ const importParslet = composeParslet({
1427
+ name: 'importParslet',
1428
+ accept: type => type === 'import',
1429
+ parsePrefix: parser => {
1430
+ parser.consume('import');
1431
+ if (!parser.consume('(')) {
1432
+ throw new Error('Missing parenthesis after import keyword');
1433
+ }
1434
+ const path = parser.parseType(Precedence.PREFIX);
1435
+ if (path.type !== 'JsdocTypeStringValue') {
1436
+ throw new Error('Only string values are allowed as paths for imports');
1437
+ }
1438
+ if (!parser.consume(')')) {
1439
+ throw new Error('Missing closing parenthesis after import keyword');
1440
+ }
1441
+ return {
1442
+ type: 'JsdocTypeImport',
1443
+ element: path
1444
+ };
1445
+ }
1446
+ });
1447
+
1448
+ const readonlyPropertyParslet = composeParslet({
1449
+ name: 'readonlyPropertyParslet',
1450
+ accept: type => type === 'readonly',
1451
+ parsePrefix: parser => {
1452
+ parser.consume('readonly');
1453
+ return {
1454
+ type: 'JsdocTypeReadonlyProperty',
1455
+ element: parser.parseType(Precedence.KEY_VALUE)
1456
+ };
1457
+ }
1458
+ });
1459
+
1460
+ const arrowFunctionParslet = composeParslet({
1461
+ name: 'arrowFunctionParslet',
1462
+ precedence: Precedence.ARROW,
1463
+ accept: type => type === '=>',
1464
+ parseInfix: (parser, left) => {
1465
+ parser.consume('=>');
1466
+ return {
1467
+ type: 'JsdocTypeFunction',
1468
+ parameters: getParameters(left).map(assertPlainKeyValueOrNameResult),
1469
+ arrow: true,
1470
+ constructor: false,
1471
+ parenthesis: true,
1472
+ returnType: parser.parseType(Precedence.OBJECT)
1473
+ };
1474
+ }
1475
+ });
1476
+
1477
+ const intersectionParslet = composeParslet({
1478
+ name: 'intersectionParslet',
1479
+ accept: type => type === '&',
1480
+ precedence: Precedence.INTERSECTION,
1481
+ parseInfix: (parser, left) => {
1482
+ parser.consume('&');
1483
+ const elements = [];
1484
+ do {
1485
+ elements.push(parser.parseType(Precedence.INTERSECTION));
1486
+ } while (parser.consume('&'));
1487
+ return {
1488
+ type: 'JsdocTypeIntersection',
1489
+ elements: [assertRootResult(left), ...elements]
1490
+ };
1491
+ }
1492
+ });
1493
+
1494
+ const predicateParslet = composeParslet({
1495
+ name: 'predicateParslet',
1496
+ precedence: Precedence.INFIX,
1497
+ accept: type => type === 'is',
1498
+ parseInfix: (parser, left) => {
1499
+ if (left.type !== 'JsdocTypeName') {
1500
+ throw new UnexpectedTypeError(left, 'A typescript predicate always has to have a name on the left side.');
1501
+ }
1502
+ parser.consume('is');
1503
+ return {
1504
+ type: 'JsdocTypePredicate',
1505
+ left,
1506
+ right: assertRootResult(parser.parseIntermediateType(Precedence.INFIX))
1507
+ };
1508
+ }
1509
+ });
1510
+
1511
+ const objectSquaredPropertyParslet = composeParslet({
1512
+ name: 'objectSquareBracketPropertyParslet',
1513
+ accept: type => type === '[',
1514
+ parsePrefix: parser => {
1515
+ if (parser.baseParser === undefined) {
1516
+ throw new Error('Only allowed inside object grammar');
1517
+ }
1518
+ parser.consume('[');
1519
+ const key = parser.lexer.current.text;
1520
+ parser.consume('Identifier');
1521
+ let result;
1522
+ if (parser.consume(':')) {
1523
+ const parentParser = parser.baseParser;
1524
+ parentParser.acceptLexerState(parser);
1525
+ result = {
1526
+ type: 'JsdocTypeIndexSignature',
1527
+ key,
1528
+ right: parentParser.parseType(Precedence.INDEX_BRACKETS)
1529
+ };
1530
+ parser.acceptLexerState(parentParser);
1531
+ }
1532
+ else if (parser.consume('in')) {
1533
+ const parentParser = parser.baseParser;
1534
+ parentParser.acceptLexerState(parser);
1535
+ result = {
1536
+ type: 'JsdocTypeMappedType',
1537
+ key,
1538
+ right: parentParser.parseType(Precedence.ARRAY_BRACKETS)
1539
+ };
1540
+ parser.acceptLexerState(parentParser);
1541
+ }
1542
+ else {
1543
+ throw new Error('Missing \':\' or \'in\' inside square bracketed property.');
1544
+ }
1545
+ if (!parser.consume(']')) {
1546
+ throw new Error('Unterminated square brackets');
1547
+ }
1548
+ return result;
1549
+ }
1550
+ });
1551
+
1552
+ const objectFieldGrammar = [
1553
+ readonlyPropertyParslet,
1554
+ createNameParslet({
1555
+ allowedAdditionalTokens: ['module', 'event', 'keyof', 'event', 'external', 'in']
1556
+ }),
1557
+ nullableParslet,
1558
+ optionalParslet,
1559
+ stringValueParslet,
1560
+ numberParslet,
1561
+ createObjectFieldParslet({
1562
+ allowSquaredProperties: true,
1563
+ allowKeyTypes: false,
1564
+ allowOptional: true,
1565
+ allowReadonly: true
1566
+ }),
1567
+ objectSquaredPropertyParslet
1568
+ ];
1569
+ const typescriptGrammar = [
1570
+ ...baseGrammar,
1571
+ createObjectParslet({
1572
+ allowKeyTypes: false,
1573
+ objectFieldGrammar
1574
+ }),
1575
+ typeOfParslet,
1576
+ keyOfParslet,
1577
+ importParslet,
1578
+ stringValueParslet,
1579
+ createFunctionParslet({
1580
+ allowWithoutParenthesis: true,
1581
+ allowNoReturnType: false,
1582
+ allowNamedParameters: ['this', 'new', 'args'],
1583
+ allowNewAsFunctionKeyword: true
1584
+ }),
1585
+ createTupleParslet({
1586
+ allowQuestionMark: false
1587
+ }),
1588
+ createVariadicParslet({
1589
+ allowEnclosingBrackets: false,
1590
+ allowPostfix: false
1591
+ }),
1592
+ assertsParslet,
1593
+ createNameParslet({
1594
+ allowedAdditionalTokens: ['event', 'external', 'in']
1595
+ }),
1596
+ createSpecialNamePathParslet({
1597
+ allowedTypes: ['module'],
1598
+ pathGrammar
1599
+ }),
1600
+ arrayBracketsParslet,
1601
+ arrowFunctionParslet,
1602
+ createNamePathParslet({
1603
+ allowSquareBracketsOnAnyType: true,
1604
+ allowJsdocNamePaths: false,
1605
+ pathGrammar
1606
+ }),
1607
+ intersectionParslet,
1608
+ predicateParslet,
1609
+ createKeyValueParslet({
1610
+ allowVariadic: true,
1611
+ allowOptional: true
1612
+ })
1613
+ ];
1614
+
1615
+ /**
1616
+ * This function parses the given expression in the given mode and produces a {@link RootResult}.
1617
+ * @param expression
1618
+ * @param mode
1619
+ */
1620
+ function parse(expression, mode) {
1621
+ switch (mode) {
1622
+ case 'closure':
1623
+ return (new Parser(closureGrammar, expression)).parse();
1624
+ case 'jsdoc':
1625
+ return (new Parser(jsdocGrammar, expression)).parse();
1626
+ case 'typescript':
1627
+ return (new Parser(typescriptGrammar, expression)).parse();
1628
+ }
1629
+ }
1630
+ /**
1631
+ * This function tries to parse the given expression in multiple modes and returns the first successful
1632
+ * {@link RootResult}. By default it tries `'typescript'`, `'closure'` and `'jsdoc'` in this order. If
1633
+ * no mode was successful it throws the error that was produced by the last parsing attempt.
1634
+ * @param expression
1635
+ * @param modes
1636
+ */
1637
+ function tryParse(expression, modes = ['typescript', 'closure', 'jsdoc']) {
1638
+ let error;
1639
+ for (const mode of modes) {
1640
+ try {
1641
+ return parse(expression, mode);
1642
+ }
1643
+ catch (e) {
1644
+ error = e;
1645
+ }
1646
+ }
1647
+ throw error;
1648
+ }
1649
+
1650
+ function transform(rules, parseResult) {
1651
+ const rule = rules[parseResult.type];
1652
+ if (rule === undefined) {
1653
+ throw new Error(`In this set of transform rules exists no rule for type ${parseResult.type}.`);
1654
+ }
1655
+ return rule(parseResult, aParseResult => transform(rules, aParseResult));
1656
+ }
1657
+ function notAvailableTransform(parseResult) {
1658
+ throw new Error('This transform is not available. Are you trying the correct parsing mode?');
1659
+ }
1660
+ function extractSpecialParams(source) {
1661
+ const result = {
1662
+ params: []
1663
+ };
1664
+ for (const param of source.parameters) {
1665
+ if (param.type === 'JsdocTypeKeyValue') {
1666
+ if (param.key === 'this') {
1667
+ result.this = param.right;
1668
+ }
1669
+ else if (param.key === 'new') {
1670
+ result.new = param.right;
1671
+ }
1672
+ else {
1673
+ result.params.push(param);
1674
+ }
1675
+ }
1676
+ else {
1677
+ result.params.push(param);
1678
+ }
1679
+ }
1680
+ return result;
1681
+ }
1682
+
1683
+ function applyPosition(position, target, value) {
1684
+ return position === 'prefix' ? value + target : target + value;
1685
+ }
1686
+ function quote(value, quote) {
1687
+ switch (quote) {
1688
+ case 'double':
1689
+ return `"${value}"`;
1690
+ case 'single':
1691
+ return `'${value}'`;
1692
+ case undefined:
1693
+ return value;
1694
+ }
1695
+ }
1696
+ function stringifyRules() {
1697
+ return {
1698
+ JsdocTypeParenthesis: (result, transform) => `(${result.element !== undefined ? transform(result.element) : ''})`,
1699
+ JsdocTypeKeyof: (result, transform) => `keyof ${transform(result.element)}`,
1700
+ JsdocTypeFunction: (result, transform) => {
1701
+ if (!result.arrow) {
1702
+ let stringified = result.constructor ? 'new' : 'function';
1703
+ if (!result.parenthesis) {
1704
+ return stringified;
1705
+ }
1706
+ stringified += `(${result.parameters.map(transform).join(', ')})`;
1707
+ if (result.returnType !== undefined) {
1708
+ stringified += `: ${transform(result.returnType)}`;
1709
+ }
1710
+ return stringified;
1711
+ }
1712
+ else {
1713
+ if (result.returnType === undefined) {
1714
+ throw new Error('Arrow function needs a return type.');
1715
+ }
1716
+ let stringified = `(${result.parameters.map(transform).join(', ')}) => ${transform(result.returnType)}`;
1717
+ if (result.constructor) {
1718
+ stringified = 'new ' + stringified;
1719
+ }
1720
+ return stringified;
1721
+ }
1722
+ },
1723
+ JsdocTypeName: result => result.value,
1724
+ JsdocTypeTuple: (result, transform) => `[${result.elements.map(transform).join(', ')}]`,
1725
+ JsdocTypeVariadic: (result, transform) => result.meta.position === undefined
1726
+ ? '...'
1727
+ : applyPosition(result.meta.position, transform(result.element), '...'),
1728
+ JsdocTypeNamePath: (result, transform) => {
1729
+ const left = transform(result.left);
1730
+ const right = transform(result.right);
1731
+ switch (result.pathType) {
1732
+ case 'inner':
1733
+ return `${left}~${right}`;
1734
+ case 'instance':
1735
+ return `${left}#${right}`;
1736
+ case 'property':
1737
+ return `${left}.${right}`;
1738
+ case 'property-brackets':
1739
+ return `${left}[${right}]`;
1740
+ }
1741
+ },
1742
+ JsdocTypeStringValue: result => quote(result.value, result.meta.quote),
1743
+ JsdocTypeAny: () => '*',
1744
+ JsdocTypeGeneric: (result, transform) => {
1745
+ if (result.meta.brackets === 'square') {
1746
+ const element = result.elements[0];
1747
+ const transformed = transform(element);
1748
+ if (element.type === 'JsdocTypeUnion' || element.type === 'JsdocTypeIntersection') {
1749
+ return `(${transformed})[]`;
1750
+ }
1751
+ else {
1752
+ return `${transformed}[]`;
1753
+ }
1754
+ }
1755
+ else {
1756
+ return `${transform(result.left)}${result.meta.dot ? '.' : ''}<${result.elements.map(transform).join(', ')}>`;
1757
+ }
1758
+ },
1759
+ JsdocTypeImport: (result, transform) => `import(${transform(result.element)})`,
1760
+ JsdocTypeObjectField: (result, transform) => {
1761
+ let text = '';
1762
+ if (result.readonly) {
1763
+ text += 'readonly ';
1764
+ }
1765
+ if (typeof result.key === 'string') {
1766
+ text += quote(result.key, result.meta.quote);
1767
+ }
1768
+ else {
1769
+ text += transform(result.key);
1770
+ }
1771
+ if (result.optional) {
1772
+ text += '?';
1773
+ }
1774
+ if (result.right === undefined) {
1775
+ return text;
1776
+ }
1777
+ else {
1778
+ return text + `: ${transform(result.right)}`;
1779
+ }
1780
+ },
1781
+ JsdocTypeJsdocObjectField: (result, transform) => {
1782
+ return `${transform(result.left)}: ${transform(result.right)}`;
1783
+ },
1784
+ JsdocTypeKeyValue: (result, transform) => {
1785
+ let text = result.key;
1786
+ if (result.optional) {
1787
+ text += '?';
1788
+ }
1789
+ if (result.variadic) {
1790
+ text = '...' + text;
1791
+ }
1792
+ if (result.right === undefined) {
1793
+ return text;
1794
+ }
1795
+ else {
1796
+ return text + `: ${transform(result.right)}`;
1797
+ }
1798
+ },
1799
+ JsdocTypeSpecialNamePath: result => `${result.specialType}:${quote(result.value, result.meta.quote)}`,
1800
+ JsdocTypeNotNullable: (result, transform) => applyPosition(result.meta.position, transform(result.element), '!'),
1801
+ JsdocTypeNull: () => 'null',
1802
+ JsdocTypeNullable: (result, transform) => applyPosition(result.meta.position, transform(result.element), '?'),
1803
+ JsdocTypeNumber: result => result.value.toString(),
1804
+ JsdocTypeObject: (result, transform) => `{${result.elements.map(transform).join((result.meta.separator === 'comma' ? ',' : ';') + ' ')}}`,
1805
+ JsdocTypeOptional: (result, transform) => applyPosition(result.meta.position, transform(result.element), '='),
1806
+ JsdocTypeSymbol: (result, transform) => `${result.value}(${result.element !== undefined ? transform(result.element) : ''})`,
1807
+ JsdocTypeTypeof: (result, transform) => `typeof ${transform(result.element)}`,
1808
+ JsdocTypeUndefined: () => 'undefined',
1809
+ JsdocTypeUnion: (result, transform) => result.elements.map(transform).join(' | '),
1810
+ JsdocTypeUnknown: () => '?',
1811
+ JsdocTypeIntersection: (result, transform) => result.elements.map(transform).join(' & '),
1812
+ JsdocTypeProperty: result => quote(result.value, result.meta.quote),
1813
+ JsdocTypePredicate: (result, transform) => `${transform(result.left)} is ${transform(result.right)}`,
1814
+ JsdocTypeIndexSignature: (result, transform) => `[${result.key}: ${transform(result.right)}]`,
1815
+ JsdocTypeMappedType: (result, transform) => `[${result.key} in ${transform(result.right)}]`,
1816
+ JsdocTypeAsserts: (result, transform) => `asserts ${transform(result.left)} is ${transform(result.right)}`
1817
+ };
1818
+ }
1819
+ const storedStringifyRules = stringifyRules();
1820
+ function stringify(result) {
1821
+ return transform(storedStringifyRules, result);
1822
+ }
1823
+
1824
+ const reservedWords = [
1825
+ 'null',
1826
+ 'true',
1827
+ 'false',
1828
+ 'break',
1829
+ 'case',
1830
+ 'catch',
1831
+ 'class',
1832
+ 'const',
1833
+ 'continue',
1834
+ 'debugger',
1835
+ 'default',
1836
+ 'delete',
1837
+ 'do',
1838
+ 'else',
1839
+ 'export',
1840
+ 'extends',
1841
+ 'finally',
1842
+ 'for',
1843
+ 'function',
1844
+ 'if',
1845
+ 'import',
1846
+ 'in',
1847
+ 'instanceof',
1848
+ 'new',
1849
+ 'return',
1850
+ 'super',
1851
+ 'switch',
1852
+ 'this',
1853
+ 'throw',
1854
+ 'try',
1855
+ 'typeof',
1856
+ 'var',
1857
+ 'void',
1858
+ 'while',
1859
+ 'with',
1860
+ 'yield'
1861
+ ];
1862
+ function makeName(value) {
1863
+ const result = {
1864
+ type: 'NameExpression',
1865
+ name: value
1866
+ };
1867
+ if (reservedWords.includes(value)) {
1868
+ result.reservedWord = true;
1869
+ }
1870
+ return result;
1871
+ }
1872
+ const catharsisTransformRules = {
1873
+ JsdocTypeOptional: (result, transform) => {
1874
+ const transformed = transform(result.element);
1875
+ transformed.optional = true;
1876
+ return transformed;
1877
+ },
1878
+ JsdocTypeNullable: (result, transform) => {
1879
+ const transformed = transform(result.element);
1880
+ transformed.nullable = true;
1881
+ return transformed;
1882
+ },
1883
+ JsdocTypeNotNullable: (result, transform) => {
1884
+ const transformed = transform(result.element);
1885
+ transformed.nullable = false;
1886
+ return transformed;
1887
+ },
1888
+ JsdocTypeVariadic: (result, transform) => {
1889
+ if (result.element === undefined) {
1890
+ throw new Error('dots without value are not allowed in catharsis mode');
1891
+ }
1892
+ const transformed = transform(result.element);
1893
+ transformed.repeatable = true;
1894
+ return transformed;
1895
+ },
1896
+ JsdocTypeAny: () => ({
1897
+ type: 'AllLiteral'
1898
+ }),
1899
+ JsdocTypeNull: () => ({
1900
+ type: 'NullLiteral'
1901
+ }),
1902
+ JsdocTypeStringValue: result => makeName(quote(result.value, result.meta.quote)),
1903
+ JsdocTypeUndefined: () => ({
1904
+ type: 'UndefinedLiteral'
1905
+ }),
1906
+ JsdocTypeUnknown: () => ({
1907
+ type: 'UnknownLiteral'
1908
+ }),
1909
+ JsdocTypeFunction: (result, transform) => {
1910
+ const params = extractSpecialParams(result);
1911
+ const transformed = {
1912
+ type: 'FunctionType',
1913
+ params: params.params.map(transform)
1914
+ };
1915
+ if (params.this !== undefined) {
1916
+ transformed.this = transform(params.this);
1917
+ }
1918
+ if (params.new !== undefined) {
1919
+ transformed.new = transform(params.new);
1920
+ }
1921
+ if (result.returnType !== undefined) {
1922
+ transformed.result = transform(result.returnType);
1923
+ }
1924
+ return transformed;
1925
+ },
1926
+ JsdocTypeGeneric: (result, transform) => ({
1927
+ type: 'TypeApplication',
1928
+ applications: result.elements.map(o => transform(o)),
1929
+ expression: transform(result.left)
1930
+ }),
1931
+ JsdocTypeSpecialNamePath: result => makeName(result.specialType + ':' + quote(result.value, result.meta.quote)),
1932
+ JsdocTypeName: result => {
1933
+ if (result.value !== 'function') {
1934
+ return makeName(result.value);
1935
+ }
1936
+ else {
1937
+ return {
1938
+ type: 'FunctionType',
1939
+ params: []
1940
+ };
1941
+ }
1942
+ },
1943
+ JsdocTypeNumber: result => makeName(result.value.toString()),
1944
+ JsdocTypeObject: (result, transform) => {
1945
+ const transformed = {
1946
+ type: 'RecordType',
1947
+ fields: []
1948
+ };
1949
+ for (const field of result.elements) {
1950
+ if (field.type !== 'JsdocTypeObjectField' && field.type !== 'JsdocTypeJsdocObjectField') {
1951
+ transformed.fields.push({
1952
+ type: 'FieldType',
1953
+ key: transform(field),
1954
+ value: undefined
1955
+ });
1956
+ }
1957
+ else {
1958
+ transformed.fields.push(transform(field));
1959
+ }
1960
+ }
1961
+ return transformed;
1962
+ },
1963
+ JsdocTypeObjectField: (result, transform) => {
1964
+ if (typeof result.key !== 'string') {
1965
+ throw new Error('Index signatures and mapped types are not supported');
1966
+ }
1967
+ return {
1968
+ type: 'FieldType',
1969
+ key: makeName(quote(result.key, result.meta.quote)),
1970
+ value: result.right === undefined ? undefined : transform(result.right)
1971
+ };
1972
+ },
1973
+ JsdocTypeJsdocObjectField: (result, transform) => ({
1974
+ type: 'FieldType',
1975
+ key: transform(result.left),
1976
+ value: transform(result.right)
1977
+ }),
1978
+ JsdocTypeUnion: (result, transform) => ({
1979
+ type: 'TypeUnion',
1980
+ elements: result.elements.map(e => transform(e))
1981
+ }),
1982
+ JsdocTypeKeyValue: (result, transform) => {
1983
+ return {
1984
+ type: 'FieldType',
1985
+ key: makeName(result.key),
1986
+ value: result.right === undefined ? undefined : transform(result.right)
1987
+ };
1988
+ },
1989
+ JsdocTypeNamePath: (result, transform) => {
1990
+ const leftResult = transform(result.left);
1991
+ let rightValue;
1992
+ if (result.right.type === 'JsdocTypeSpecialNamePath') {
1993
+ rightValue = transform(result.right).name;
1994
+ }
1995
+ else {
1996
+ rightValue = quote(result.right.value, result.right.meta.quote);
1997
+ }
1998
+ const joiner = result.pathType === 'inner' ? '~' : result.pathType === 'instance' ? '#' : '.';
1999
+ return makeName(`${leftResult.name}${joiner}${rightValue}`);
2000
+ },
2001
+ JsdocTypeSymbol: result => {
2002
+ let value = '';
2003
+ let element = result.element;
2004
+ let trailingDots = false;
2005
+ if ((element === null || element === void 0 ? void 0 : element.type) === 'JsdocTypeVariadic') {
2006
+ if (element.meta.position === 'prefix') {
2007
+ value = '...';
2008
+ }
2009
+ else {
2010
+ trailingDots = true;
2011
+ }
2012
+ element = element.element;
2013
+ }
2014
+ if ((element === null || element === void 0 ? void 0 : element.type) === 'JsdocTypeName') {
2015
+ value += element.value;
2016
+ }
2017
+ else if ((element === null || element === void 0 ? void 0 : element.type) === 'JsdocTypeNumber') {
2018
+ value += element.value.toString();
2019
+ }
2020
+ if (trailingDots) {
2021
+ value += '...';
2022
+ }
2023
+ return makeName(`${result.value}(${value})`);
2024
+ },
2025
+ JsdocTypeParenthesis: (result, transform) => transform(assertRootResult(result.element)),
2026
+ JsdocTypeMappedType: notAvailableTransform,
2027
+ JsdocTypeIndexSignature: notAvailableTransform,
2028
+ JsdocTypeImport: notAvailableTransform,
2029
+ JsdocTypeKeyof: notAvailableTransform,
2030
+ JsdocTypeTuple: notAvailableTransform,
2031
+ JsdocTypeTypeof: notAvailableTransform,
2032
+ JsdocTypeIntersection: notAvailableTransform,
2033
+ JsdocTypeProperty: notAvailableTransform,
2034
+ JsdocTypePredicate: notAvailableTransform,
2035
+ JsdocTypeAsserts: notAvailableTransform
2036
+ };
2037
+ function catharsisTransform(result) {
2038
+ return transform(catharsisTransformRules, result);
2039
+ }
2040
+
2041
+ function getQuoteStyle(quote) {
2042
+ switch (quote) {
2043
+ case undefined:
2044
+ return 'none';
2045
+ case 'single':
2046
+ return 'single';
2047
+ case 'double':
2048
+ return 'double';
2049
+ }
2050
+ }
2051
+ function getMemberType(type) {
2052
+ switch (type) {
2053
+ case 'inner':
2054
+ return 'INNER_MEMBER';
2055
+ case 'instance':
2056
+ return 'INSTANCE_MEMBER';
2057
+ case 'property':
2058
+ return 'MEMBER';
2059
+ case 'property-brackets':
2060
+ return 'MEMBER';
2061
+ }
2062
+ }
2063
+ function nestResults(type, results) {
2064
+ if (results.length === 2) {
2065
+ return {
2066
+ type,
2067
+ left: results[0],
2068
+ right: results[1]
2069
+ };
2070
+ }
2071
+ else {
2072
+ return {
2073
+ type,
2074
+ left: results[0],
2075
+ right: nestResults(type, results.slice(1))
2076
+ };
2077
+ }
2078
+ }
2079
+ const jtpRules = {
2080
+ JsdocTypeOptional: (result, transform) => ({
2081
+ type: 'OPTIONAL',
2082
+ value: transform(result.element),
2083
+ meta: {
2084
+ syntax: result.meta.position === 'prefix' ? 'PREFIX_EQUAL_SIGN' : 'SUFFIX_EQUALS_SIGN'
2085
+ }
2086
+ }),
2087
+ JsdocTypeNullable: (result, transform) => ({
2088
+ type: 'NULLABLE',
2089
+ value: transform(result.element),
2090
+ meta: {
2091
+ syntax: result.meta.position === 'prefix' ? 'PREFIX_QUESTION_MARK' : 'SUFFIX_QUESTION_MARK'
2092
+ }
2093
+ }),
2094
+ JsdocTypeNotNullable: (result, transform) => ({
2095
+ type: 'NOT_NULLABLE',
2096
+ value: transform(result.element),
2097
+ meta: {
2098
+ syntax: result.meta.position === 'prefix' ? 'PREFIX_BANG' : 'SUFFIX_BANG'
2099
+ }
2100
+ }),
2101
+ JsdocTypeVariadic: (result, transform) => {
2102
+ const transformed = {
2103
+ type: 'VARIADIC',
2104
+ meta: {
2105
+ syntax: result.meta.position === 'prefix'
2106
+ ? 'PREFIX_DOTS'
2107
+ : result.meta.position === 'suffix' ? 'SUFFIX_DOTS' : 'ONLY_DOTS'
2108
+ }
2109
+ };
2110
+ if (result.element !== undefined) {
2111
+ transformed.value = transform(result.element);
2112
+ }
2113
+ return transformed;
2114
+ },
2115
+ JsdocTypeName: result => ({
2116
+ type: 'NAME',
2117
+ name: result.value
2118
+ }),
2119
+ JsdocTypeTypeof: (result, transform) => ({
2120
+ type: 'TYPE_QUERY',
2121
+ name: transform(result.element)
2122
+ }),
2123
+ JsdocTypeTuple: (result, transform) => ({
2124
+ type: 'TUPLE',
2125
+ entries: result.elements.map(transform)
2126
+ }),
2127
+ JsdocTypeKeyof: (result, transform) => ({
2128
+ type: 'KEY_QUERY',
2129
+ value: transform(result.element)
2130
+ }),
2131
+ JsdocTypeImport: result => ({
2132
+ type: 'IMPORT',
2133
+ path: {
2134
+ type: 'STRING_VALUE',
2135
+ quoteStyle: getQuoteStyle(result.element.meta.quote),
2136
+ string: result.element.value
2137
+ }
2138
+ }),
2139
+ JsdocTypeUndefined: () => ({
2140
+ type: 'NAME',
2141
+ name: 'undefined'
2142
+ }),
2143
+ JsdocTypeAny: () => ({
2144
+ type: 'ANY'
2145
+ }),
2146
+ JsdocTypeFunction: (result, transform) => {
2147
+ const specialParams = extractSpecialParams(result);
2148
+ const transformed = {
2149
+ type: result.arrow ? 'ARROW' : 'FUNCTION',
2150
+ params: specialParams.params.map(param => {
2151
+ if (param.type === 'JsdocTypeKeyValue') {
2152
+ if (param.right === undefined) {
2153
+ throw new Error('Function parameter without \':\' is not expected to be \'KEY_VALUE\'');
2154
+ }
2155
+ return {
2156
+ type: 'NAMED_PARAMETER',
2157
+ name: param.key,
2158
+ typeName: transform(param.right)
2159
+ };
2160
+ }
2161
+ else {
2162
+ return transform(param);
2163
+ }
2164
+ }),
2165
+ new: null,
2166
+ returns: null
2167
+ };
2168
+ if (specialParams.this !== undefined) {
2169
+ transformed.this = transform(specialParams.this);
2170
+ }
2171
+ else if (!result.arrow) {
2172
+ transformed.this = null;
2173
+ }
2174
+ if (specialParams.new !== undefined) {
2175
+ transformed.new = transform(specialParams.new);
2176
+ }
2177
+ if (result.returnType !== undefined) {
2178
+ transformed.returns = transform(result.returnType);
2179
+ }
2180
+ return transformed;
2181
+ },
2182
+ JsdocTypeGeneric: (result, transform) => {
2183
+ const transformed = {
2184
+ type: 'GENERIC',
2185
+ subject: transform(result.left),
2186
+ objects: result.elements.map(transform),
2187
+ meta: {
2188
+ syntax: result.meta.brackets === 'square' ? 'SQUARE_BRACKET' : result.meta.dot ? 'ANGLE_BRACKET_WITH_DOT' : 'ANGLE_BRACKET'
2189
+ }
2190
+ };
2191
+ if (result.meta.brackets === 'square' && result.elements[0].type === 'JsdocTypeFunction' && !result.elements[0].parenthesis) {
2192
+ transformed.objects[0] = {
2193
+ type: 'NAME',
2194
+ name: 'function'
2195
+ };
2196
+ }
2197
+ return transformed;
2198
+ },
2199
+ JsdocTypeObjectField: (result, transform) => {
2200
+ if (typeof result.key !== 'string') {
2201
+ throw new Error('Index signatures and mapped types are not supported');
2202
+ }
2203
+ if (result.right === undefined) {
2204
+ return {
2205
+ type: 'RECORD_ENTRY',
2206
+ key: result.key,
2207
+ quoteStyle: getQuoteStyle(result.meta.quote),
2208
+ value: null,
2209
+ readonly: false
2210
+ };
2211
+ }
2212
+ let right = transform(result.right);
2213
+ if (result.optional) {
2214
+ right = {
2215
+ type: 'OPTIONAL',
2216
+ value: right,
2217
+ meta: {
2218
+ syntax: 'SUFFIX_KEY_QUESTION_MARK'
2219
+ }
2220
+ };
2221
+ }
2222
+ return {
2223
+ type: 'RECORD_ENTRY',
2224
+ key: result.key.toString(),
2225
+ quoteStyle: getQuoteStyle(result.meta.quote),
2226
+ value: right,
2227
+ readonly: false
2228
+ };
2229
+ },
2230
+ JsdocTypeJsdocObjectField: () => {
2231
+ throw new Error('Keys may not be typed in jsdoctypeparser.');
2232
+ },
2233
+ JsdocTypeKeyValue: (result, transform) => {
2234
+ if (result.right === undefined) {
2235
+ return {
2236
+ type: 'RECORD_ENTRY',
2237
+ key: result.key,
2238
+ quoteStyle: 'none',
2239
+ value: null,
2240
+ readonly: false
2241
+ };
2242
+ }
2243
+ let right = transform(result.right);
2244
+ if (result.optional) {
2245
+ right = {
2246
+ type: 'OPTIONAL',
2247
+ value: right,
2248
+ meta: {
2249
+ syntax: 'SUFFIX_KEY_QUESTION_MARK'
2250
+ }
2251
+ };
2252
+ }
2253
+ return {
2254
+ type: 'RECORD_ENTRY',
2255
+ key: result.key,
2256
+ quoteStyle: 'none',
2257
+ value: right,
2258
+ readonly: false
2259
+ };
2260
+ },
2261
+ JsdocTypeObject: (result, transform) => {
2262
+ const entries = [];
2263
+ for (const field of result.elements) {
2264
+ if (field.type === 'JsdocTypeObjectField' || field.type === 'JsdocTypeJsdocObjectField') {
2265
+ entries.push(transform(field));
2266
+ }
2267
+ }
2268
+ return {
2269
+ type: 'RECORD',
2270
+ entries
2271
+ };
2272
+ },
2273
+ JsdocTypeSpecialNamePath: result => {
2274
+ if (result.specialType !== 'module') {
2275
+ throw new Error(`jsdoctypeparser does not support type ${result.specialType} at this point.`);
2276
+ }
2277
+ return {
2278
+ type: 'MODULE',
2279
+ value: {
2280
+ type: 'FILE_PATH',
2281
+ quoteStyle: getQuoteStyle(result.meta.quote),
2282
+ path: result.value
2283
+ }
2284
+ };
2285
+ },
2286
+ JsdocTypeNamePath: (result, transform) => {
2287
+ let hasEventPrefix = false;
2288
+ let name;
2289
+ let quoteStyle;
2290
+ if (result.right.type === 'JsdocTypeSpecialNamePath' && result.right.specialType === 'event') {
2291
+ hasEventPrefix = true;
2292
+ name = result.right.value;
2293
+ quoteStyle = getQuoteStyle(result.right.meta.quote);
2294
+ }
2295
+ else {
2296
+ name = result.right.value;
2297
+ quoteStyle = getQuoteStyle(result.right.meta.quote);
2298
+ }
2299
+ const transformed = {
2300
+ type: getMemberType(result.pathType),
2301
+ owner: transform(result.left),
2302
+ name,
2303
+ quoteStyle,
2304
+ hasEventPrefix
2305
+ };
2306
+ if (transformed.owner.type === 'MODULE') {
2307
+ const tModule = transformed.owner;
2308
+ transformed.owner = transformed.owner.value;
2309
+ tModule.value = transformed;
2310
+ return tModule;
2311
+ }
2312
+ else {
2313
+ return transformed;
2314
+ }
2315
+ },
2316
+ JsdocTypeUnion: (result, transform) => nestResults('UNION', result.elements.map(transform)),
2317
+ JsdocTypeParenthesis: (result, transform) => ({
2318
+ type: 'PARENTHESIS',
2319
+ value: transform(assertRootResult(result.element))
2320
+ }),
2321
+ JsdocTypeNull: () => ({
2322
+ type: 'NAME',
2323
+ name: 'null'
2324
+ }),
2325
+ JsdocTypeUnknown: () => ({
2326
+ type: 'UNKNOWN'
2327
+ }),
2328
+ JsdocTypeStringValue: result => ({
2329
+ type: 'STRING_VALUE',
2330
+ quoteStyle: getQuoteStyle(result.meta.quote),
2331
+ string: result.value
2332
+ }),
2333
+ JsdocTypeIntersection: (result, transform) => nestResults('INTERSECTION', result.elements.map(transform)),
2334
+ JsdocTypeNumber: result => ({
2335
+ type: 'NUMBER_VALUE',
2336
+ number: result.value.toString()
2337
+ }),
2338
+ JsdocTypeSymbol: notAvailableTransform,
2339
+ JsdocTypeProperty: notAvailableTransform,
2340
+ JsdocTypePredicate: notAvailableTransform,
2341
+ JsdocTypeMappedType: notAvailableTransform,
2342
+ JsdocTypeIndexSignature: notAvailableTransform,
2343
+ JsdocTypeAsserts: notAvailableTransform
2344
+ };
2345
+ function jtpTransform(result) {
2346
+ return transform(jtpRules, result);
2347
+ }
2348
+
2349
+ function identityTransformRules() {
2350
+ return {
2351
+ JsdocTypeIntersection: (result, transform) => ({
2352
+ type: 'JsdocTypeIntersection',
2353
+ elements: result.elements.map(transform)
2354
+ }),
2355
+ JsdocTypeGeneric: (result, transform) => ({
2356
+ type: 'JsdocTypeGeneric',
2357
+ left: transform(result.left),
2358
+ elements: result.elements.map(transform),
2359
+ meta: {
2360
+ dot: result.meta.dot,
2361
+ brackets: result.meta.brackets
2362
+ }
2363
+ }),
2364
+ JsdocTypeNullable: result => result,
2365
+ JsdocTypeUnion: (result, transform) => ({
2366
+ type: 'JsdocTypeUnion',
2367
+ elements: result.elements.map(transform)
2368
+ }),
2369
+ JsdocTypeUnknown: result => result,
2370
+ JsdocTypeUndefined: result => result,
2371
+ JsdocTypeTypeof: (result, transform) => ({
2372
+ type: 'JsdocTypeTypeof',
2373
+ element: transform(result.element)
2374
+ }),
2375
+ JsdocTypeSymbol: (result, transform) => {
2376
+ const transformed = {
2377
+ type: 'JsdocTypeSymbol',
2378
+ value: result.value
2379
+ };
2380
+ if (result.element !== undefined) {
2381
+ transformed.element = transform(result.element);
2382
+ }
2383
+ return transformed;
2384
+ },
2385
+ JsdocTypeOptional: (result, transform) => ({
2386
+ type: 'JsdocTypeOptional',
2387
+ element: transform(result.element),
2388
+ meta: {
2389
+ position: result.meta.position
2390
+ }
2391
+ }),
2392
+ JsdocTypeObject: (result, transform) => ({
2393
+ type: 'JsdocTypeObject',
2394
+ meta: {
2395
+ separator: 'comma'
2396
+ },
2397
+ elements: result.elements.map(transform)
2398
+ }),
2399
+ JsdocTypeNumber: result => result,
2400
+ JsdocTypeNull: result => result,
2401
+ JsdocTypeNotNullable: (result, transform) => ({
2402
+ type: 'JsdocTypeNotNullable',
2403
+ element: transform(result.element),
2404
+ meta: {
2405
+ position: result.meta.position
2406
+ }
2407
+ }),
2408
+ JsdocTypeSpecialNamePath: result => result,
2409
+ JsdocTypeObjectField: (result, transform) => ({
2410
+ type: 'JsdocTypeObjectField',
2411
+ key: result.key,
2412
+ right: result.right === undefined ? undefined : transform(result.right),
2413
+ optional: result.optional,
2414
+ readonly: result.readonly,
2415
+ meta: result.meta
2416
+ }),
2417
+ JsdocTypeJsdocObjectField: (result, transform) => ({
2418
+ type: 'JsdocTypeJsdocObjectField',
2419
+ left: transform(result.left),
2420
+ right: transform(result.right)
2421
+ }),
2422
+ JsdocTypeKeyValue: (result, transform) => {
2423
+ return {
2424
+ type: 'JsdocTypeKeyValue',
2425
+ key: result.key,
2426
+ right: result.right === undefined ? undefined : transform(result.right),
2427
+ optional: result.optional,
2428
+ variadic: result.variadic
2429
+ };
2430
+ },
2431
+ JsdocTypeImport: (result, transform) => ({
2432
+ type: 'JsdocTypeImport',
2433
+ element: transform(result.element)
2434
+ }),
2435
+ JsdocTypeAny: result => result,
2436
+ JsdocTypeStringValue: result => result,
2437
+ JsdocTypeNamePath: result => result,
2438
+ JsdocTypeVariadic: (result, transform) => {
2439
+ const transformed = {
2440
+ type: 'JsdocTypeVariadic',
2441
+ meta: {
2442
+ position: result.meta.position,
2443
+ squareBrackets: result.meta.squareBrackets
2444
+ }
2445
+ };
2446
+ if (result.element !== undefined) {
2447
+ transformed.element = transform(result.element);
2448
+ }
2449
+ return transformed;
2450
+ },
2451
+ JsdocTypeTuple: (result, transform) => ({
2452
+ type: 'JsdocTypeTuple',
2453
+ elements: result.elements.map(transform)
2454
+ }),
2455
+ JsdocTypeName: result => result,
2456
+ JsdocTypeFunction: (result, transform) => {
2457
+ const transformed = {
2458
+ type: 'JsdocTypeFunction',
2459
+ arrow: result.arrow,
2460
+ parameters: result.parameters.map(transform),
2461
+ constructor: result.constructor,
2462
+ parenthesis: result.parenthesis
2463
+ };
2464
+ if (result.returnType !== undefined) {
2465
+ transformed.returnType = transform(result.returnType);
2466
+ }
2467
+ return transformed;
2468
+ },
2469
+ JsdocTypeKeyof: (result, transform) => ({
2470
+ type: 'JsdocTypeKeyof',
2471
+ element: transform(result.element)
2472
+ }),
2473
+ JsdocTypeParenthesis: (result, transform) => ({
2474
+ type: 'JsdocTypeParenthesis',
2475
+ element: transform(result.element)
2476
+ }),
2477
+ JsdocTypeProperty: result => result,
2478
+ JsdocTypePredicate: (result, transform) => ({
2479
+ type: 'JsdocTypePredicate',
2480
+ left: transform(result.left),
2481
+ right: transform(result.right)
2482
+ }),
2483
+ JsdocTypeIndexSignature: (result, transform) => ({
2484
+ type: 'JsdocTypeIndexSignature',
2485
+ key: result.key,
2486
+ right: transform(result.right)
2487
+ }),
2488
+ JsdocTypeMappedType: (result, transform) => ({
2489
+ type: 'JsdocTypeMappedType',
2490
+ key: result.key,
2491
+ right: transform(result.right)
2492
+ }),
2493
+ JsdocTypeAsserts: (result, transform) => ({
2494
+ type: 'JsdocTypeAsserts',
2495
+ left: transform(result.left),
2496
+ right: transform(result.right)
2497
+ })
2498
+ };
2499
+ }
2500
+
2501
+ const visitorKeys = {
2502
+ JsdocTypeAny: [],
2503
+ JsdocTypeFunction: ['parameters', 'returnType'],
2504
+ JsdocTypeGeneric: ['left', 'elements'],
2505
+ JsdocTypeImport: [],
2506
+ JsdocTypeIndexSignature: ['right'],
2507
+ JsdocTypeIntersection: ['elements'],
2508
+ JsdocTypeKeyof: ['element'],
2509
+ JsdocTypeKeyValue: ['right'],
2510
+ JsdocTypeMappedType: ['right'],
2511
+ JsdocTypeName: [],
2512
+ JsdocTypeNamePath: ['left', 'right'],
2513
+ JsdocTypeNotNullable: ['element'],
2514
+ JsdocTypeNull: [],
2515
+ JsdocTypeNullable: ['element'],
2516
+ JsdocTypeNumber: [],
2517
+ JsdocTypeObject: ['elements'],
2518
+ JsdocTypeObjectField: ['right'],
2519
+ JsdocTypeJsdocObjectField: ['left', 'right'],
2520
+ JsdocTypeOptional: ['element'],
2521
+ JsdocTypeParenthesis: ['element'],
2522
+ JsdocTypeSpecialNamePath: [],
2523
+ JsdocTypeStringValue: [],
2524
+ JsdocTypeSymbol: ['element'],
2525
+ JsdocTypeTuple: ['elements'],
2526
+ JsdocTypeTypeof: ['element'],
2527
+ JsdocTypeUndefined: [],
2528
+ JsdocTypeUnion: ['elements'],
2529
+ JsdocTypeUnknown: [],
2530
+ JsdocTypeVariadic: ['element'],
2531
+ JsdocTypeProperty: [],
2532
+ JsdocTypePredicate: ['left', 'right'],
2533
+ JsdocTypeAsserts: ['left', 'right']
2534
+ };
2535
+
2536
+ function _traverse(node, parentNode, property, onEnter, onLeave) {
2537
+ onEnter === null || onEnter === void 0 ? void 0 : onEnter(node, parentNode, property);
2538
+ const keysToVisit = visitorKeys[node.type];
2539
+ for (const key of keysToVisit) {
2540
+ const value = node[key];
2541
+ if (value !== undefined) {
2542
+ if (Array.isArray(value)) {
2543
+ for (const element of value) {
2544
+ _traverse(element, node, key, onEnter, onLeave);
2545
+ }
2546
+ }
2547
+ else {
2548
+ _traverse(value, node, key, onEnter, onLeave);
2549
+ }
2550
+ }
2551
+ }
2552
+ onLeave === null || onLeave === void 0 ? void 0 : onLeave(node, parentNode, property);
2553
+ }
2554
+ /**
2555
+ * A function to traverse an AST. It traverses it depth first.
2556
+ * @param node the node to start traversing at.
2557
+ * @param onEnter node visitor function that will be called on entering the node. This corresponds to preorder traversing.
2558
+ * @param onLeave node visitor function that will be called on leaving the node. This corresponds to postorder traversing.
2559
+ */
2560
+ function traverse(node, onEnter, onLeave) {
2561
+ _traverse(node, undefined, undefined, onEnter, onLeave);
2562
+ }
2563
+
2564
+ exports.catharsisTransform = catharsisTransform;
2565
+ exports.identityTransformRules = identityTransformRules;
2566
+ exports.jtpTransform = jtpTransform;
2567
+ exports.parse = parse;
2568
+ exports.stringify = stringify;
2569
+ exports.stringifyRules = stringifyRules;
2570
+ exports.transform = transform;
2571
+ exports.traverse = traverse;
2572
+ exports.tryParse = tryParse;
2573
+ exports.visitorKeys = visitorKeys;
2574
+
2575
+ }));
2576
+ } (dist$1, dist$1.exports));
2577
+ return dist$1.exports;
2578
+ }
2579
+
2580
+ export { requireDist as r };