@spyglassmc/mcdoc 0.3.8 → 0.3.10

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.
@@ -8,9 +8,7 @@ import { NumericTypeFloatKinds, NumericTypeIntKinds, PrimitiveArrayValueKinds, S
8
8
  *
9
9
  * `Failure` when there isn't a comment.
10
10
  */
11
- export const comment = validate(core.comment({
12
- singleLinePrefixes: new Set(['//']),
13
- }), (res, src) => !src.slice(res).startsWith('///'), localize('mcdoc.parser.syntax.doc-comment-unexpected'));
11
+ export const comment = validate(core.comment({ singleLinePrefixes: new Set(['//']) }), (res, src) => !src.slice(res).startsWith('///'), localize('mcdoc.parser.syntax.doc-comment-unexpected'));
14
12
  /**
15
13
  * @returns A parser that parses the gap between **SYNTAX** rules, which may contains whitespace and regular comments.
16
14
  */
@@ -20,9 +18,7 @@ delegatesDocComments = false) {
20
18
  return (src, ctx) => {
21
19
  const ans = [];
22
20
  src.skipWhitespace();
23
- while (src.canRead() &&
24
- src.peek(2) === '//' &&
25
- (!delegatesDocComments || src.peek(3) !== '///')) {
21
+ while (src.canRead() && src.peek(2) === '//' && (!delegatesDocComments || src.peek(3) !== '///')) {
26
22
  const result = comment(src, ctx);
27
23
  ans.push(result);
28
24
  src.skipWhitespace();
@@ -49,8 +45,7 @@ export function literal(literal, options) {
49
45
  value: '',
50
46
  colorTokenType: options?.colorTokenType,
51
47
  };
52
- ans.value = src.readIf((c) => options?.allowedChars?.has(c) ??
53
- (options?.specialChars?.has(c) || /[a-z]/i.test(c)));
48
+ ans.value = src.readIf((c) => options?.allowedChars?.has(c) ?? (options?.specialChars?.has(c) || /[a-z]/i.test(c)));
54
49
  ans.range.end = src.cursor;
55
50
  if (Arrayable.toArray(literal).every((l) => l !== ans.value)) {
56
51
  ctx.err.report(localize('expected-got', arrayToMessage(literal), localeQuote(ans.value)), ans);
@@ -108,10 +103,7 @@ const UnicodeControlCharacters = Object.freeze([
108
103
  '\x7F',
109
104
  ]);
110
105
  export const string = stopBefore(core.string({
111
- escapable: {
112
- characters: ['b', 'f', 'n', 'r', 't', '\\', '"'],
113
- unicode: true,
114
- },
106
+ escapable: { characters: ['b', 'f', 'n', 'r', 't', '\\', '"'], unicode: true },
115
107
  quotes: ['"'],
116
108
  }), ...UnicodeControlCharacters);
117
109
  export const identifier = (src, ctx) => {
@@ -159,17 +151,9 @@ export const identifier = (src, ctx) => {
159
151
  };
160
152
  function indexBody(options) {
161
153
  const accessorKey = select([
162
- {
163
- prefix: '%',
164
- parser: literal(['%key', '%parent'], { specialChars: new Set(['%']) }),
165
- },
166
- {
167
- prefix: '"',
168
- parser: string,
169
- },
170
- {
171
- parser: identifier,
172
- },
154
+ { prefix: '%', parser: literal(['%key', '%parent'], { specialChars: new Set(['%']) }) },
155
+ { prefix: '"', parser: string },
156
+ { parser: identifier },
173
157
  ]);
174
158
  const dynamicIndex = setType('mcdoc:dynamic_index', syntax([
175
159
  punctuation('['),
@@ -182,10 +166,7 @@ function indexBody(options) {
182
166
  prefix: '%',
183
167
  parser: literal(StaticIndexKeywords.map((v) => `%${v}`), { specialChars: new Set(['%']) }),
184
168
  },
185
- {
186
- prefix: '"',
187
- parser: string,
188
- },
169
+ { prefix: '"', parser: string },
189
170
  {
190
171
  prefix: '[',
191
172
  parser: options?.noDynamic
@@ -194,10 +175,7 @@ function indexBody(options) {
194
175
  },
195
176
  {
196
177
  parser: any([
197
- resLoc({
198
- category: 'mcdoc/dispatcher',
199
- accessType: options?.accessType,
200
- }),
178
+ resLoc({ category: 'mcdoc/dispatcher', accessType: options?.accessType }),
201
179
  identifier,
202
180
  ]),
203
181
  },
@@ -210,10 +188,10 @@ function indexBody(options) {
210
188
  punctuation(']'),
211
189
  ]));
212
190
  }
213
- const pathSegment = select([
214
- { prefix: 'super', parser: literal('super') },
215
- { parser: identifier },
216
- ]);
191
+ const pathSegment = select([{
192
+ prefix: 'super',
193
+ parser: literal('super'),
194
+ }, { parser: identifier }]);
217
195
  export const path = (src, ctx) => {
218
196
  let isAbsolute;
219
197
  if (src.trySkip('::')) {
@@ -235,13 +213,10 @@ const attributeTreePosValues = setType('mcdoc:attribute/tree/pos', syntax([
235
213
  ], true));
236
214
  const attributeNamedValue = syntax([
237
215
  select([{ prefix: '"', parser: string }, { parser: identifier }]),
238
- select([
239
- {
216
+ select([{
240
217
  prefix: '=',
241
218
  parser: syntax([punctuation('='), { get: () => attributeValue }], true),
242
- },
243
- { parser: { get: () => attributeTree } },
244
- ]),
219
+ }, { parser: { get: () => attributeTree } }]),
245
220
  ], true);
246
221
  const attributeTreeNamedValues = setType('mcdoc:attribute/tree/named', syntax([
247
222
  attributeNamedValue,
@@ -257,11 +232,7 @@ const treeBody = any([
257
232
  ]),
258
233
  syntax([attributeTreePosValues, optional(marker(','))]),
259
234
  ]);
260
- const AttributeTreeClosure = Object.freeze({
261
- '(': ')',
262
- '[': ']',
263
- '{': '}',
264
- });
235
+ const AttributeTreeClosure = Object.freeze({ '(': ')', '[': ']', '{': '}' });
265
236
  const attributeTree = (src, ctx) => {
266
237
  const delim = src.trySkip('(')
267
238
  ? '('
@@ -283,30 +254,20 @@ const attributeTree = (src, ctx) => {
283
254
  src.trySkip(AttributeTreeClosure[delim]);
284
255
  return ans;
285
256
  };
286
- const attributeValue = select([
287
- {
257
+ const attributeValue = select([{
288
258
  predicate: (src) => ['(', '[', '{'].includes(src.peek()),
289
259
  parser: attributeTree,
290
- },
291
- { parser: { get: () => type } },
292
- ]);
260
+ }, { parser: { get: () => type } }]);
293
261
  export const attribute = setType('mcdoc:attribute', syntax([
294
262
  marker('#['),
295
263
  identifier,
296
- select([
297
- {
264
+ select([{
298
265
  prefix: '=',
299
266
  parser: syntax([punctuation('='), attributeValue, punctuation(']')], true),
300
- },
301
- {
267
+ }, {
302
268
  predicate: (src) => ['(', '[', '{'].includes(src.peek()),
303
- parser: syntax([
304
- attributeTree,
305
- punctuation(']'),
306
- ], true),
307
- },
308
- { parser: punctuation(']') },
309
- ]),
269
+ parser: syntax([attributeTree, punctuation(']')], true),
270
+ }, { parser: punctuation(']') }]),
310
271
  ], true));
311
272
  const attributes = repeat(attribute);
312
273
  const typeParam = setType('mcdoc:type_param', syntax([
@@ -315,17 +276,14 @@ const typeParam = setType('mcdoc:type_param', syntax([
315
276
  ]));
316
277
  const typeParamBlock = setType('mcdoc:type_param_block', syntax([
317
278
  punctuation('<'),
318
- select([
319
- { prefix: '>', parser: punctuation('>') },
320
- {
279
+ select([{ prefix: '>', parser: punctuation('>') }, {
321
280
  parser: syntax([
322
281
  typeParam,
323
282
  syntaxRepeat(syntax([marker(','), failOnEmpty(typeParam)])),
324
283
  optional(marker(',')),
325
284
  punctuation('>'),
326
285
  ]),
327
- },
328
- ]),
286
+ }]),
329
287
  ]));
330
288
  const noop = () => undefined;
331
289
  export const docComment = core.comment({
@@ -336,93 +294,74 @@ export const docComments = setType('mcdoc:doc_comments', repeat(docComment, (src
336
294
  src.skipWhitespace();
337
295
  return [];
338
296
  }));
339
- const prelim = syntax([optional(failOnEmpty(docComments)), attributes]);
340
- const optionalTypeParamBlock = select([{ prefix: '<', parser: typeParamBlock }, { parser: noop }]);
297
+ const prelim = syntax([
298
+ optional(failOnEmpty(docComments)),
299
+ attributes,
300
+ ]);
301
+ const optionalTypeParamBlock = select([{
302
+ prefix: '<',
303
+ parser: typeParamBlock,
304
+ }, { parser: noop }]);
341
305
  export const dispatchStatement = setType('mcdoc:dispatch_statement', syntax([
342
306
  prelim,
343
307
  keyword('dispatch'),
344
- resLoc({
345
- category: 'mcdoc/dispatcher',
346
- accessType: 1 /* SymbolAccessType.Write */,
347
- }),
308
+ resLoc({ category: 'mcdoc/dispatcher', accessType: 1 /* SymbolAccessType.Write */ }),
348
309
  indexBody({ noDynamic: true }),
349
310
  optionalTypeParamBlock,
350
311
  literal('to'),
351
312
  { get: () => type },
352
313
  ], true));
353
- const enumType = literal(['byte', 'short', 'int', 'long', 'string', 'float', 'double'], { colorTokenType: 'type' });
314
+ const enumType = literal([
315
+ 'byte',
316
+ 'short',
317
+ 'int',
318
+ 'long',
319
+ 'string',
320
+ 'float',
321
+ 'double',
322
+ ], { colorTokenType: 'type' });
354
323
  export const float = core.float({
355
324
  pattern: /^[-+]?(?:[0-9]+(?:[eE][-+]?[0-9]+)?|[0-9]*\.[0-9]+(?:[eE][-+]?[0-9]+)?)$/,
356
325
  });
357
326
  export const integer = core.integer({
358
327
  pattern: /^(?:0|[-+]?[1-9][0-9]*)$/,
359
328
  });
360
- export const LiteralIntSuffixes = Object.freeze([
361
- 'b',
362
- 's',
363
- 'l',
364
- ]);
365
- export const LiteralIntCaseInsensitiveSuffixes = Object.freeze([
366
- ...LiteralIntSuffixes,
367
- 'B',
368
- 'S',
369
- 'L',
370
- ]);
371
- export const LiteralFloatSuffixes = Object.freeze([
372
- 'f',
373
- 'd',
374
- ]);
375
- export const LiteralFloatCaseInsensitiveSuffixes = Object.freeze([
376
- ...LiteralFloatSuffixes,
377
- 'F',
378
- 'D',
379
- ]);
380
- export const LiteralNumberSuffixes = Object.freeze([
381
- ...LiteralIntSuffixes,
382
- ...LiteralFloatSuffixes,
383
- ]);
329
+ export const LiteralIntSuffixes = Object.freeze(['b', 's', 'l']);
330
+ export const LiteralIntCaseInsensitiveSuffixes = Object.freeze([...LiteralIntSuffixes, 'B', 'S', 'L']);
331
+ export const LiteralFloatSuffixes = Object.freeze(['f', 'd']);
332
+ export const LiteralFloatCaseInsensitiveSuffixes = Object.freeze([...LiteralFloatSuffixes, 'F', 'D']);
333
+ export const LiteralNumberSuffixes = Object.freeze([...LiteralIntSuffixes, ...LiteralFloatSuffixes]);
384
334
  export const LiteralNumberCaseInsensitiveSuffixes = Object.freeze([
385
335
  ...LiteralNumberSuffixes,
386
336
  ...LiteralIntCaseInsensitiveSuffixes,
387
337
  ...LiteralFloatCaseInsensitiveSuffixes,
388
338
  ]);
389
- export const typedNumber = setType('mcdoc:typed_number', select([
390
- {
339
+ export const typedNumber = setType('mcdoc:typed_number', select([{
391
340
  regex: /^(?:\+|-)?\d+(?!\d|[.dfe])/i,
392
341
  parser: sequence([
393
342
  integer,
394
- optional(keyword(LiteralIntCaseInsensitiveSuffixes, {
395
- colorTokenType: 'keyword',
396
- })),
343
+ optional(keyword(LiteralIntCaseInsensitiveSuffixes, { colorTokenType: 'keyword' })),
397
344
  ]),
398
- },
399
- {
345
+ }, {
400
346
  parser: sequence([
401
347
  float,
402
- optional(keyword(LiteralFloatCaseInsensitiveSuffixes, {
403
- colorTokenType: 'keyword',
404
- })),
348
+ optional(keyword(LiteralFloatCaseInsensitiveSuffixes, { colorTokenType: 'keyword' })),
405
349
  ]),
406
- },
407
- ]));
408
- const enumValue = select([
409
- { prefix: '"', parser: string },
410
- { parser: typedNumber },
411
- ]);
350
+ }]));
351
+ const enumValue = select([{ prefix: '"', parser: string }, {
352
+ parser: typedNumber,
353
+ }]);
412
354
  const enumField = setType('mcdoc:enum/field', syntax([prelim, identifier, punctuation('='), enumValue], true));
413
355
  const enumBlock = setType('mcdoc:enum/block', syntax([
414
356
  punctuation('{'),
415
- select([
416
- { prefix: '}', parser: punctuation('}') },
417
- {
357
+ select([{ prefix: '}', parser: punctuation('}') }, {
418
358
  parser: syntax([
419
359
  enumField,
420
360
  syntaxRepeat(syntax([marker(','), failOnEmpty(enumField)], true), true),
421
361
  optional(marker(',')),
422
362
  punctuation('}'),
423
363
  ], true),
424
- },
425
- ]),
364
+ }]),
426
365
  ], true));
427
366
  export const enum_ = setType('mcdoc:enum', syntax([
428
367
  prelim,
@@ -434,11 +373,10 @@ export const enum_ = setType('mcdoc:enum', syntax([
434
373
  enumBlock,
435
374
  ], true));
436
375
  const structMapKey = setType('mcdoc:struct/map_key', syntax([punctuation('['), { get: () => type }, punctuation(']')], true));
437
- const structKey = select([
438
- { prefix: '"', parser: string },
439
- { prefix: '[', parser: structMapKey },
440
- { parser: identifier },
441
- ]);
376
+ const structKey = select([{ prefix: '"', parser: string }, {
377
+ prefix: '[',
378
+ parser: structMapKey,
379
+ }, { parser: identifier }]);
442
380
  const structPairField = (src, ctx) => {
443
381
  let isOptional;
444
382
  const result0 = syntax([prelim, structKey], true)(src, ctx);
@@ -455,58 +393,35 @@ const structPairField = (src, ctx) => {
455
393
  return ans;
456
394
  };
457
395
  const structSpreadField = setType('mcdoc:struct/field/spread', syntax([attributes, marker('...'), { get: () => type }], true));
458
- const structField = any([structSpreadField, structPairField]);
396
+ const structField = any([
397
+ structSpreadField,
398
+ structPairField,
399
+ ]);
459
400
  const structBlock = setType('mcdoc:struct/block', syntax([
460
401
  punctuation('{'),
461
- select([
462
- { prefix: '}', parser: punctuation('}') },
463
- {
402
+ select([{ prefix: '}', parser: punctuation('}') }, {
464
403
  parser: syntax([
465
404
  structField,
466
405
  syntaxRepeat(syntax([marker(','), failOnEmpty(structField)], true), true),
467
406
  optional(marker(',')),
468
407
  punctuation('}'),
469
408
  ], true),
470
- },
471
- ]),
409
+ }]),
472
410
  ], true));
473
- export const struct = setType('mcdoc:struct', syntax([
474
- prelim,
475
- keyword('struct'),
476
- optional(failOnEmpty(identifier)),
477
- structBlock,
478
- ], true));
479
- const enumInjection = setType('mcdoc:injection/enum', syntax([
480
- literal('enum'),
481
- punctuation('('),
482
- enumType,
483
- punctuation(')'),
484
- path,
485
- enumBlock,
486
- ]));
411
+ export const struct = setType('mcdoc:struct', syntax([prelim, keyword('struct'), optional(failOnEmpty(identifier)), structBlock], true));
412
+ const enumInjection = setType('mcdoc:injection/enum', syntax([literal('enum'), punctuation('('), enumType, punctuation(')'), path, enumBlock]));
487
413
  const structInjection = setType('mcdoc:injection/struct', syntax([literal('struct'), path, structBlock]));
488
414
  export const injection = setType('mcdoc:injection', syntax([
489
415
  keyword('inject'),
490
- select([
491
- { prefix: 'enum', parser: enumInjection },
492
- { parser: structInjection },
493
- ]),
416
+ select([{ prefix: 'enum', parser: enumInjection }, { parser: structInjection }]),
494
417
  ]));
495
- export const typeAliasStatement = setType('mcdoc:type_alias', syntax([
496
- prelim,
497
- keyword('type'),
498
- identifier,
499
- optionalTypeParamBlock,
500
- punctuation('='),
501
- { get: () => type },
502
- ], true));
418
+ export const typeAliasStatement = setType('mcdoc:type_alias', syntax([prelim, keyword('type'), identifier, optionalTypeParamBlock, punctuation('='), {
419
+ get: () => type,
420
+ }], true));
503
421
  export const useStatement = setType('mcdoc:use_statement', syntax([
504
422
  keyword('use'),
505
423
  path,
506
- select([
507
- { prefix: 'as', parser: syntax([literal('as'), identifier]) },
508
- { parser: noop },
509
- ]),
424
+ select([{ prefix: 'as', parser: syntax([literal('as'), identifier]) }, { parser: noop }]),
510
425
  ], true));
511
426
  const topLevel = any([
512
427
  comment,
@@ -520,27 +435,21 @@ const topLevel = any([
520
435
  export const module_ = setType('mcdoc:module', syntaxRepeat(topLevel, true));
521
436
  const typeArgBlock = setType('mcdoc:type_arg_block', syntax([
522
437
  marker('<'),
523
- select([
524
- { prefix: '>', parser: punctuation('>') },
525
- {
438
+ select([{ prefix: '>', parser: punctuation('>') }, {
526
439
  parser: syntax([
527
440
  { get: () => type },
528
441
  syntaxRepeat(syntax([marker(','), { get: () => failOnEmpty(type) }], true), true),
529
442
  optional(marker(',')),
530
443
  punctuation('>'),
531
444
  ], true),
532
- },
533
- ]),
445
+ }]),
534
446
  ]));
535
447
  /* eslint-enable @typescript-eslint/indent */
536
448
  function typeBase(type, parser) {
537
449
  return setType(type, syntax([
538
450
  attributes,
539
451
  parser,
540
- syntaxRepeat(select([
541
- { prefix: '<', parser: typeArgBlock },
542
- { parser: failOnError(indexBody()) },
543
- ]), true),
452
+ syntaxRepeat(select([{ prefix: '<', parser: typeArgBlock }, { parser: failOnError(indexBody()) }]), true),
544
453
  ], true));
545
454
  }
546
455
  export const anyType = typeBase('mcdoc:type/any', keyword('any', { colorTokenType: 'type' }));
@@ -552,30 +461,16 @@ function range(type, number) {
552
461
  `..${RangeExclusiveChar}`,
553
462
  `${RangeExclusiveChar}..`,
554
463
  `${RangeExclusiveChar}..${RangeExclusiveChar}`,
555
- ], {
556
- allowedChars: new Set(['.', RangeExclusiveChar]),
557
- });
558
- return setType(type, select([
559
- {
560
- predicate: delimiterPredicate,
561
- parser: sequence([delimiterParser, number]),
562
- },
563
- {
464
+ ], { allowedChars: new Set(['.', RangeExclusiveChar]) });
465
+ return setType(type, select([{ predicate: delimiterPredicate, parser: sequence([delimiterParser, number]) }, {
564
466
  parser: sequence([
565
467
  stopBefore(number, '..'),
566
- select([
567
- {
468
+ select([{
568
469
  predicate: delimiterPredicate,
569
- parser: sequence([
570
- delimiterParser,
571
- optional(failOnEmpty(number)),
572
- ]),
573
- },
574
- { parser: noop },
575
- ]),
470
+ parser: sequence([delimiterParser, optional(failOnEmpty(number))]),
471
+ }, { parser: noop }]),
576
472
  ]),
577
- },
578
- ]));
473
+ }]));
579
474
  }
580
475
  export const intRange = range('mcdoc:int_range', integer);
581
476
  const atIntRange = optional((src, ctx) => {
@@ -585,7 +480,10 @@ const atIntRange = optional((src, ctx) => {
585
480
  src.skipWhitespace();
586
481
  return intRange(src, ctx);
587
482
  });
588
- export const stringType = typeBase('mcdoc:type/string', syntax([keyword('string', { colorTokenType: 'type' }), atIntRange]));
483
+ export const stringType = typeBase('mcdoc:type/string', syntax([
484
+ keyword('string', { colorTokenType: 'type' }),
485
+ atIntRange,
486
+ ], true));
589
487
  export const literalType = typeBase('mcdoc:type/literal', select([
590
488
  {
591
489
  predicate: (src) => src.tryPeek('false') || src.tryPeek('true'),
@@ -602,28 +500,16 @@ const atFloatRange = optional((src, ctx) => {
602
500
  src.skipWhitespace();
603
501
  return floatRange(src, ctx);
604
502
  });
605
- export const numericType = typeBase('mcdoc:type/numeric_type', select([
606
- {
503
+ export const numericType = typeBase('mcdoc:type/numeric_type', select([{
607
504
  predicate: (src) => NumericTypeFloatKinds.some((k) => src.tryPeek(k)),
608
- parser: syntax([
609
- keyword(NumericTypeFloatKinds, { colorTokenType: 'type' }),
610
- atFloatRange,
611
- ], true),
612
- },
613
- {
614
- parser: syntax([
615
- keyword(NumericTypeIntKinds, { colorTokenType: 'type' }),
616
- atIntRange,
617
- ], true),
618
- },
619
- ]));
505
+ parser: syntax([keyword(NumericTypeFloatKinds, { colorTokenType: 'type' }), atFloatRange], true),
506
+ }, {
507
+ parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atIntRange], true),
508
+ }]));
620
509
  export const primitiveArrayType = typeBase('mcdoc:type/primitive_array', syntax([
621
510
  literal(PrimitiveArrayValueKinds),
622
511
  atIntRange,
623
- keyword('[]', {
624
- allowedChars: new Set(['[', ']']),
625
- colorTokenType: 'type',
626
- }),
512
+ keyword('[]', { allowedChars: new Set(['[', ']']), colorTokenType: 'type' }),
627
513
  atIntRange,
628
514
  ]));
629
515
  export const listType = typeBase('mcdoc:type/list', syntax([marker('['), { get: () => type }, punctuation(']'), atIntRange], true));
@@ -631,32 +517,26 @@ export const tupleType = typeBase('mcdoc:type/tuple', syntax([
631
517
  marker('['),
632
518
  { get: () => type },
633
519
  marker(','),
634
- select([
635
- { prefix: ']', parser: punctuation(']') },
636
- {
520
+ select([{ prefix: ']', parser: punctuation(']') }, {
637
521
  parser: syntax([
638
522
  { get: () => type },
639
523
  syntaxRepeat(syntax([marker(','), { get: () => failOnEmpty(type) }], true), true),
640
524
  optional(marker(',')),
641
525
  punctuation(']'),
642
526
  ], true),
643
- },
644
- ]),
527
+ }]),
645
528
  ], true));
646
529
  export const dispatcherType = typeBase('mcdoc:type/dispatcher', syntax([failOnError(resLoc({ category: 'mcdoc/dispatcher' })), indexBody()]));
647
530
  export const unionType = typeBase('mcdoc:type/union', syntax([
648
531
  marker('('),
649
- select([
650
- { prefix: ')', parser: punctuation(')') },
651
- {
532
+ select([{ prefix: ')', parser: punctuation(')') }, {
652
533
  parser: syntax([
653
534
  { get: () => type },
654
535
  syntaxRepeat(syntax([marker('|'), { get: () => failOnEmpty(type) }], true), true),
655
536
  optional(marker('|')),
656
537
  punctuation(')'),
657
538
  ], true),
658
- },
659
- ]),
539
+ }]),
660
540
  ]));
661
541
  export const referenceType = typeBase('mcdoc:type/reference', syntax([path]));
662
542
  export const type = any([
@@ -0,0 +1,3 @@
1
+ import * as core from '@spyglassmc/core';
2
+ export declare function registerBuiltinAttributes(meta: core.MetaRegistry): void;
3
+ //# sourceMappingURL=builtin.d.ts.map
@@ -0,0 +1,130 @@
1
+ import * as core from '@spyglassmc/core';
2
+ import { registerAttribute, validator } from './index.js';
3
+ const idValidator = validator.alternatives(validator.map(validator.string, v => ({ registry: v })), validator.tree({
4
+ registry: validator.string,
5
+ tags: validator.optional(validator.options('allowed', 'implicit', 'required')),
6
+ definition: validator.optional(validator.boolean),
7
+ prefix: validator.optional(validator.options('!')),
8
+ }), () => ({}));
9
+ function getResourceLocationOptions({ registry, tags, definition }, requireCanonical, ctx, typeDef) {
10
+ if (!registry) {
11
+ if (typeDef?.kind === 'enum' && typeDef.enumKind === 'string') {
12
+ return {
13
+ pool: typeDef.values.map(v => core.ResourceLocation.lengthen(`${v.value}`)),
14
+ allowUnknown: true, // the mcdoc checker will already report errors for this
15
+ };
16
+ }
17
+ if (typeDef?.kind === 'literal' && typeDef.value.kind === 'string') {
18
+ return {
19
+ pool: [core.ResourceLocation.lengthen(typeDef.value.value)],
20
+ allowUnknown: true,
21
+ };
22
+ }
23
+ return { pool: [], allowUnknown: true };
24
+ }
25
+ if (tags === 'implicit') {
26
+ registry = `tag/${registry}`;
27
+ }
28
+ if (tags === 'allowed' || tags === 'required') {
29
+ if (core.TaggableResourceLocationCategory.is(registry)) {
30
+ return {
31
+ category: registry,
32
+ requireCanonical,
33
+ allowTag: true,
34
+ requireTag: tags === 'required',
35
+ };
36
+ }
37
+ }
38
+ else if (core.ResourceLocationCategory.is(registry)) {
39
+ return {
40
+ category: registry,
41
+ requireCanonical,
42
+ usageType: definition ? 'definition' : 'reference',
43
+ };
44
+ }
45
+ ctx.logger.warn(`[mcdoc id] Unhandled registry ${registry}`);
46
+ return undefined;
47
+ }
48
+ export function registerBuiltinAttributes(meta) {
49
+ registerAttribute(meta, 'canonical', () => undefined, {
50
+ // Has hardcoded behavior in the runtime checker
51
+ });
52
+ registerAttribute(meta, 'dispatcher_key', validator.string, {
53
+ stringMocker: (config, _, ctx) => {
54
+ const symbol = ctx.symbols.query(ctx.doc, 'mcdoc/dispatcher', config).symbol;
55
+ const keys = Object.keys(symbol?.members ?? {}).filter(m => !m.startsWith('%'));
56
+ return core.LiteralNode.mock(ctx.offset, { pool: keys });
57
+ },
58
+ });
59
+ registerAttribute(meta, 'id', idValidator, {
60
+ checkInferred: (config, inferred, ctx) => {
61
+ if (inferred.kind === 'string') {
62
+ // Internal mcdoc isAssignable check
63
+ const idAttr = inferred.attributes?.find(a => a.name === 'id');
64
+ if (idAttr) {
65
+ const inferredConfig = idValidator(idAttr.value, ctx);
66
+ return inferredConfig === core.Failure || inferredConfig.prefix === config.prefix;
67
+ // Prefix doesn't match
68
+ }
69
+ }
70
+ if (inferred.kind !== 'literal' || inferred.value.kind !== 'string') {
71
+ return true; // Ignore attribute when not a string
72
+ }
73
+ if (config.prefix && !inferred.value.value.startsWith(config.prefix)) {
74
+ return false; // Missing prefix
75
+ }
76
+ if (!config.prefix && inferred.value.value.startsWith('!')) {
77
+ return false; // Unexpected prefix
78
+ }
79
+ if (!inferred.value.value.includes(':')) {
80
+ if (config.prefix) {
81
+ inferred.value.value = config.prefix + 'minecraft:'
82
+ + inferred.value.value.slice(config.prefix.length);
83
+ }
84
+ else {
85
+ inferred.value.value = 'minecraft:' + inferred.value.value;
86
+ }
87
+ }
88
+ return true;
89
+ },
90
+ mapType: (config, typeDef, ctx) => {
91
+ if (typeDef.kind === 'literal' && typeDef.value.kind === 'string') {
92
+ const value = core.ResourceLocation.lengthen(typeDef.value.value);
93
+ return { ...typeDef, value: { kind: 'string', value } };
94
+ }
95
+ if (typeDef.kind === 'enum' && typeDef.enumKind === 'string') {
96
+ const values = typeDef.values.map(v => ({
97
+ ...v,
98
+ value: core.ResourceLocation.lengthen(`${v.value}`),
99
+ }));
100
+ return { ...typeDef, values };
101
+ }
102
+ return typeDef;
103
+ },
104
+ stringParser: (config, typeDef, ctx) => {
105
+ const options = getResourceLocationOptions(config, ctx.requireCanonical, ctx, typeDef);
106
+ if (!options) {
107
+ return;
108
+ }
109
+ const resourceLocation = core.resourceLocation(options);
110
+ return (src, ctx) => {
111
+ if (config.prefix) {
112
+ return core.prefixed({ prefix: config.prefix, child: resourceLocation })(src, ctx);
113
+ }
114
+ return resourceLocation(src, ctx);
115
+ };
116
+ },
117
+ stringMocker: (config, typeDef, ctx) => {
118
+ const options = getResourceLocationOptions(config, ctx.requireCanonical ?? false, ctx, typeDef);
119
+ if (!options) {
120
+ return undefined;
121
+ }
122
+ const resourceLocation = core.ResourceLocationNode.mock(ctx.offset, options);
123
+ if (config.prefix) {
124
+ return core.PrefixedNode.mock(ctx.offset, config.prefix, resourceLocation);
125
+ }
126
+ return resourceLocation;
127
+ },
128
+ });
129
+ }
130
+ //# sourceMappingURL=builtin.js.map