@spyglassmc/mcdoc 0.3.48 → 0.3.50

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.
@@ -1,6 +1,6 @@
1
- import { AsyncBinder, atArray, Dev, ErrorSeverity, Range, ResourceLocationNode, SymbolUtil, traversePreOrder, } from '@spyglassmc/core';
1
+ import { AsyncBinder, atArray, Dev, ErrorSeverity, FloatNode, IntegerNode, LongNode, Range, ResourceLocationNode, StringNode, SymbolUtil, traversePreOrder, } from '@spyglassmc/core';
2
2
  import { localeQuote, localize } from '@spyglassmc/locales';
3
- import { AttributeNode, AttributeTreeNamedValuesNode, AttributeTreeNode, AttributeTreePosValuesNode, DispatcherTypeNode, DispatchStatementNode, DocCommentsNode, DynamicIndexNode, EnumBlockNode, EnumFieldNode, EnumInjectionNode, EnumNode, FloatRangeNode, IndexBodyNode, InjectionNode, IntRangeNode, ListTypeNode, LiteralNode, LiteralTypeNode, NumericTypeNode, PathNode, PrimitiveArrayTypeNode, ReferenceTypeNode, StaticIndexNode, StringTypeNode, StructBlockNode, StructMapKeyNode, StructNode, StructPairFieldNode, StructSpreadFieldNode, TopLevelNode, TupleTypeNode, TypeAliasNode, TypeArgBlockNode, TypeBaseNode, TypedNumberNode, TypeParamBlockNode, TypeParamNode, UnionTypeNode, UseStatementNode, } from '../node/index.js';
3
+ import { AttributeNode, AttributeTreeNamedValuesNode, AttributeTreeNode, AttributeTreePosValuesNode, DispatcherTypeNode, DispatchStatementNode, DocCommentsNode, DynamicIndexNode, EnumBlockNode, EnumFieldNode, EnumInjectionNode, EnumNode, FloatRangeNode, IndexBodyNode, InjectionNode, IntRangeNode, ListTypeNode, LiteralNode, LiteralTypeNode, LongRangeNode, NumericTypeNode, PathNode, PrimitiveArrayTypeNode, ReferenceTypeNode, StaticIndexNode, StringTypeNode, StructBlockNode, StructMapKeyNode, StructNode, StructPairFieldNode, StructSpreadFieldNode, TopLevelNode, TupleTypeNode, TypeAliasNode, TypeArgBlockNode, TypeBaseNode, TypedNumberNode, TypeParamBlockNode, TypeParamNode, UnionTypeNode, UseStatementNode, } from '../node/index.js';
4
4
  var ModuleSymbolData;
5
5
  (function (ModuleSymbolData) {
6
6
  function is(data) {
@@ -571,27 +571,144 @@ function convertEnum(node, ctx) {
571
571
  if (symbol && TypeDefSymbolData.is(symbol.data) && symbol.data.typeDef.kind === 'enum') {
572
572
  return symbol.data.typeDef;
573
573
  }
574
- return wrapType(node, { kind: 'enum', enumKind, values: convertEnumBlock(block, ctx) }, ctx);
575
- }
576
- function convertEnumBlock(node, ctx) {
574
+ switch (enumKind) {
575
+ case 'byte':
576
+ return wrapType(node, {
577
+ kind: 'enum',
578
+ enumKind,
579
+ values: convertEnumBlock(block, convertEnumIntValue(enumKind, 'b'), ctx),
580
+ }, ctx);
581
+ case 'short':
582
+ return wrapType(node, {
583
+ kind: 'enum',
584
+ enumKind,
585
+ values: convertEnumBlock(block, convertEnumIntValue(enumKind, 's'), ctx),
586
+ }, ctx);
587
+ case 'int':
588
+ return wrapType(node, {
589
+ kind: 'enum',
590
+ enumKind,
591
+ values: convertEnumBlock(block, convertEnumIntValue(enumKind), ctx),
592
+ }, ctx);
593
+ case 'long':
594
+ return wrapType(node, {
595
+ kind: 'enum',
596
+ enumKind,
597
+ values: convertEnumBlock(block, convertEnumLongValue, ctx),
598
+ }, ctx);
599
+ case 'float':
600
+ return wrapType(node, {
601
+ kind: 'enum',
602
+ enumKind,
603
+ values: convertEnumBlock(block, convertEnumFloatValue(enumKind, 'f'), ctx),
604
+ }, ctx);
605
+ case 'double':
606
+ return wrapType(node, {
607
+ kind: 'enum',
608
+ enumKind,
609
+ values: convertEnumBlock(block, convertEnumFloatValue(enumKind, 'd'), ctx),
610
+ }, ctx);
611
+ case 'string':
612
+ return wrapType(node, {
613
+ kind: 'enum',
614
+ enumKind,
615
+ values: convertEnumBlock(block, convertEnumStringValue, ctx),
616
+ }, ctx);
617
+ case undefined:
618
+ return wrapType(node, {
619
+ kind: 'enum',
620
+ enumKind,
621
+ values: convertEnumBlock(block, convertEnumValue, ctx),
622
+ }, ctx);
623
+ }
624
+ }
625
+ function convertEnumBlock(node, getEnumFieldValue, ctx) {
577
626
  const { fields } = EnumBlockNode.destruct(node);
578
- return fields.map((n) => convertEnumField(n, ctx));
627
+ return fields.map((n) => convertEnumField(n, getEnumFieldValue, ctx));
579
628
  }
580
- function convertEnumField(node, ctx) {
629
+ function convertEnumField(node, getEnumFieldValue, ctx) {
581
630
  const { attributes, docComments, identifier, value } = EnumFieldNode.destruct(node);
582
631
  return {
583
632
  attributes: convertAttributes(attributes, ctx),
584
633
  desc: DocCommentsNode.asText(docComments),
585
634
  identifier: identifier.value,
586
- value: convertEnumValue(value, ctx),
635
+ value: getEnumFieldValue(value, ctx),
587
636
  };
588
637
  }
589
- function convertEnumValue(node, ctx) {
590
- if (TypedNumberNode.is(node)) {
591
- const { value } = TypedNumberNode.destruct(node);
592
- return value.value;
638
+ function convertEnumIntValue(expected, expectedSuffix) {
639
+ return (node, ctx) => {
640
+ const { value: valueNode, suffix: suffixNode } = TypedNumberNode.is(node)
641
+ ? TypedNumberNode.destruct(node)
642
+ : { value: node };
643
+ const value = Math.floor(typeof valueNode.value === 'string'
644
+ ? Number.parseFloat(valueNode.value)
645
+ : Number(valueNode.value));
646
+ const suffix = suffixNode?.value.toLowerCase();
647
+ if (suffix !== expectedSuffix || !IntegerNode.is(valueNode)) {
648
+ ctx.err.report(localize('expected', localize(expected)), node);
649
+ }
650
+ return value;
651
+ };
652
+ }
653
+ function convertEnumFloatValue(expected, expectedSuffix) {
654
+ return (node, ctx) => {
655
+ const { value: valueNode, suffix: suffixNode } = TypedNumberNode.is(node)
656
+ ? TypedNumberNode.destruct(node)
657
+ : { value: node };
658
+ const value = typeof valueNode.value === 'string'
659
+ ? Number.parseFloat(valueNode.value)
660
+ : Number(valueNode.value);
661
+ const suffix = suffixNode?.value.toLowerCase();
662
+ if (suffix !== expectedSuffix
663
+ && (expectedSuffix !== 'd' || suffix !== undefined || !FloatNode.is(valueNode))) {
664
+ ctx.err.report(localize('expected', localize(expected)), node);
665
+ }
666
+ return value;
667
+ };
668
+ }
669
+ function convertEnumStringValue(node, ctx) {
670
+ const { value: valueNode } = TypedNumberNode.is(node)
671
+ ? TypedNumberNode.destruct(node)
672
+ : { value: node };
673
+ const value = typeof valueNode.value === 'string'
674
+ ? valueNode.value
675
+ : valueNode.value.toString();
676
+ if (!StringNode.is(valueNode)) {
677
+ ctx.err.report(localize('expected', localize('string')), node);
678
+ }
679
+ return value;
680
+ }
681
+ function convertEnumLongValue(node, ctx) {
682
+ const { value: valueNode } = TypedNumberNode.is(node)
683
+ ? TypedNumberNode.destruct(node)
684
+ : { value: node };
685
+ let value = valueNode.value;
686
+ if (typeof value === 'string') {
687
+ if (/^-?\d+$/.test(value)) {
688
+ value = BigInt(value);
689
+ }
690
+ else {
691
+ value = parseFloat(value);
692
+ }
593
693
  }
594
- return node.value;
694
+ if (typeof value === 'number') {
695
+ if (isNaN(value) || !isFinite(value)) {
696
+ value = 0n;
697
+ }
698
+ else {
699
+ value = BigInt(Math.floor(value));
700
+ }
701
+ }
702
+ if (!LongNode.is(valueNode)) {
703
+ ctx.err.report(localize('expected', localize('long')), node);
704
+ }
705
+ return value;
706
+ }
707
+ function convertEnumValue(node, ctx) {
708
+ const { value } = TypedNumberNode.is(node)
709
+ ? TypedNumberNode.destruct(node)
710
+ : { value: node };
711
+ return value.value;
595
712
  }
596
713
  function convertStruct(node, ctx) {
597
714
  const { block, identifier } = StructNode.destruct(node);
@@ -665,13 +782,17 @@ function convertList(node, ctx) {
665
782
  return wrapType(node, {
666
783
  kind: 'list',
667
784
  item: convertType(item, ctx),
668
- lengthRange: convertRange(lengthRange, ctx),
785
+ lengthRange: convertRange(lengthRange),
669
786
  }, ctx);
670
787
  }
671
- function convertRange(node, ctx) {
788
+ function convertRange(node) {
672
789
  if (!node) {
673
790
  return undefined;
674
791
  }
792
+ if (LongRangeNode.is(node)) {
793
+ const { kind, min, max } = LongRangeNode.destruct(node);
794
+ return { kind, min: min?.value, max: max?.value };
795
+ }
675
796
  const { kind, min, max } = FloatRangeNode.is(node)
676
797
  ? FloatRangeNode.destruct(node)
677
798
  : IntRangeNode.destruct(node);
@@ -718,20 +839,20 @@ function convertNumericType(node, ctx) {
718
839
  const { numericKind, valueRange } = NumericTypeNode.destruct(node);
719
840
  return wrapType(node, {
720
841
  kind: numericKind.value,
721
- valueRange: convertRange(valueRange, ctx),
842
+ valueRange: convertRange(valueRange),
722
843
  }, ctx);
723
844
  }
724
845
  function convertPrimitiveArray(node, ctx) {
725
846
  const { arrayKind, lengthRange, valueRange } = PrimitiveArrayTypeNode.destruct(node);
726
847
  return wrapType(node, {
727
848
  kind: `${arrayKind.value}_array`,
728
- lengthRange: convertRange(lengthRange, ctx),
729
- valueRange: convertRange(valueRange, ctx),
849
+ lengthRange: convertRange(lengthRange),
850
+ valueRange: convertRange(valueRange),
730
851
  }, ctx);
731
852
  }
732
853
  function convertString(node, ctx) {
733
854
  const { lengthRange } = StringTypeNode.destruct(node);
734
- return wrapType(node, { kind: 'string', lengthRange: convertRange(lengthRange, ctx) }, ctx);
855
+ return wrapType(node, { kind: 'string', lengthRange: convertRange(lengthRange) }, ctx);
735
856
  }
736
857
  function convertReference(node, ctx) {
737
858
  const { path } = ReferenceTypeNode.destruct(node);
@@ -1,5 +1,5 @@
1
1
  import type { AstNode, ColorTokenType, SymbolBaseNode } from '@spyglassmc/core';
2
- import { CommentNode, FloatNode, IntegerNode, ResourceLocationNode, StringNode } from '@spyglassmc/core';
2
+ import { CommentNode, FloatNode, IntegerNode, LongNode, ResourceLocationNode, StringNode } from '@spyglassmc/core';
3
3
  export interface ModuleNode extends AstNode {
4
4
  type: 'mcdoc:module';
5
5
  children: TopLevelNode[];
@@ -170,6 +170,18 @@ export declare namespace IntRangeNode {
170
170
  };
171
171
  function is(node: AstNode | undefined): node is IntRangeNode;
172
172
  }
173
+ export interface LongRangeNode extends AstNode {
174
+ type: 'mcdoc:long_range';
175
+ children: (LongNode | LiteralNode)[];
176
+ }
177
+ export declare namespace LongRangeNode {
178
+ function destruct(node: LongRangeNode): {
179
+ kind: RangeKind;
180
+ min?: LongNode;
181
+ max?: LongNode;
182
+ };
183
+ function is(node: AstNode | undefined): node is LongRangeNode;
184
+ }
173
185
  export interface LiteralTypeNode extends TypeBaseNode<LiteralTypeValueNode> {
174
186
  type: 'mcdoc:type/literal';
175
187
  }
@@ -185,22 +197,22 @@ export declare namespace LiteralTypeValueNode {
185
197
  }
186
198
  export interface TypedNumberNode extends AstNode {
187
199
  type: 'mcdoc:typed_number';
188
- children: (FloatNode | IntegerNode | LiteralNode)[];
200
+ children: (FloatNode | IntegerNode | LongNode | LiteralNode)[];
189
201
  }
190
202
  export declare namespace TypedNumberNode {
191
203
  function destruct(node: TypedNumberNode): {
192
- value: FloatNode | IntegerNode;
204
+ value: FloatNode | IntegerNode | LongNode;
193
205
  suffix?: LiteralNode;
194
206
  };
195
207
  function is(node: AstNode | undefined): node is TypedNumberNode;
196
208
  }
197
- export interface NumericTypeNode extends TypeBaseNode<LiteralNode | FloatRangeNode | IntRangeNode> {
209
+ export interface NumericTypeNode extends TypeBaseNode<LiteralNode | FloatRangeNode | IntRangeNode | LongRangeNode> {
198
210
  type: 'mcdoc:type/numeric_type';
199
211
  }
200
212
  export declare namespace NumericTypeNode {
201
213
  function destruct(node: NumericTypeNode): {
202
214
  numericKind: LiteralNode;
203
- valueRange?: FloatRangeNode | IntRangeNode;
215
+ valueRange?: FloatRangeNode | IntRangeNode | LongRangeNode;
204
216
  };
205
217
  function is(node: AstNode | undefined): node is NumericTypeNode;
206
218
  }
@@ -228,14 +240,14 @@ export declare namespace FloatRangeNode {
228
240
  };
229
241
  function is(node: AstNode | undefined): node is FloatRangeNode;
230
242
  }
231
- export interface PrimitiveArrayTypeNode extends TypeBaseNode<LiteralNode | IntRangeNode> {
243
+ export interface PrimitiveArrayTypeNode extends TypeBaseNode<LiteralNode | IntRangeNode | LongRangeNode> {
232
244
  type: 'mcdoc:type/primitive_array';
233
245
  }
234
246
  export declare namespace PrimitiveArrayTypeNode {
235
247
  function destruct(node: PrimitiveArrayTypeNode): {
236
248
  arrayKind: LiteralNode;
237
249
  lengthRange?: IntRangeNode;
238
- valueRange?: IntRangeNode;
250
+ valueRange?: IntRangeNode | LongRangeNode;
239
251
  };
240
252
  function is(node: AstNode | undefined): node is PrimitiveArrayTypeNode;
241
253
  }
@@ -272,7 +284,7 @@ export interface EnumNode extends TypeBaseNode<DocCommentsNode | LiteralNode | I
272
284
  }
273
285
  export type EnumKind = typeof EnumNode.Kinds extends Set<infer V> ? V : never;
274
286
  export declare namespace EnumNode {
275
- const Kinds: Set<"string" | "float" | "byte" | "short" | "int" | "long" | "double">;
287
+ const Kinds: Set<"string" | "long" | "float" | "byte" | "short" | "int" | "double">;
276
288
  function destruct(node: EnumNode): {
277
289
  block: EnumBlockNode;
278
290
  docComments?: DocCommentsNode;
package/lib/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { atArray, CommentNode, FloatNode, IntegerNode, ResourceLocationNode, StringNode, } from '@spyglassmc/core';
1
+ import { atArray, CommentNode, FloatNode, IntegerNode, LongNode, ResourceLocationNode, StringNode, } from '@spyglassmc/core';
2
2
  export var ModuleNode;
3
3
  (function (ModuleNode) {
4
4
  function is(node) {
@@ -233,6 +233,17 @@ export var IntRangeNode;
233
233
  }
234
234
  IntRangeNode.is = is;
235
235
  })(IntRangeNode || (IntRangeNode = {}));
236
+ export var LongRangeNode;
237
+ (function (LongRangeNode) {
238
+ function destruct(node) {
239
+ return destructRangeNode(node);
240
+ }
241
+ LongRangeNode.destruct = destruct;
242
+ function is(node) {
243
+ return node?.type === 'mcdoc:long_range';
244
+ }
245
+ LongRangeNode.is = is;
246
+ })(LongRangeNode || (LongRangeNode = {}));
236
247
  export var LiteralTypeNode;
237
248
  (function (LiteralTypeNode) {
238
249
  function destruct(node) {
@@ -255,7 +266,9 @@ export var TypedNumberNode;
255
266
  (function (TypedNumberNode) {
256
267
  function destruct(node) {
257
268
  return {
258
- value: node.children.find(FloatNode.is) ?? node.children.find(IntegerNode.is),
269
+ value: node.children.find(FloatNode.is)
270
+ ?? node.children.find(IntegerNode.is)
271
+ ?? node.children.find(LongNode.is),
259
272
  suffix: node.children.find(LiteralNode.is),
260
273
  };
261
274
  }
@@ -270,7 +283,9 @@ export var NumericTypeNode;
270
283
  function destruct(node) {
271
284
  return {
272
285
  numericKind: node.children.find(LiteralNode.is),
273
- valueRange: node.children.find(FloatRangeNode.is) || node.children.find(IntRangeNode.is),
286
+ valueRange: node.children.find(FloatRangeNode.is)
287
+ || node.children.find(IntRangeNode.is)
288
+ || node.children.find(LongRangeNode.is),
274
289
  };
275
290
  }
276
291
  NumericTypeNode.destruct = destruct;
@@ -354,6 +369,9 @@ export var PrimitiveArrayTypeNode;
354
369
  if (LiteralNode.is(child) && child.value === '[]') {
355
370
  afterBrackets = true;
356
371
  }
372
+ else if (LongRangeNode.is(child)) {
373
+ valueRange = child;
374
+ }
357
375
  else if (IntRangeNode.is(child)) {
358
376
  if (afterBrackets) {
359
377
  lengthRange = child;
@@ -1,6 +1,6 @@
1
- import type { ColorTokenType, CommentNode, FloatNode, InfallibleParser, IntegerNode, Parser, ResourceLocationNode, ResourceLocationOptions, StringNode } from '@spyglassmc/core';
1
+ import type { ColorTokenType, CommentNode, FloatNode, InfallibleParser, IntegerNode, LongNode, Parser, ResourceLocationNode, ResourceLocationOptions, StringNode } from '@spyglassmc/core';
2
2
  import { Arrayable } from '@spyglassmc/core';
3
- import type { AnyTypeNode, AttributeNode, BooleanTypeNode, DispatcherTypeNode, DispatchStatementNode, DocCommentsNode, EnumNode, FloatRangeNode, IdentifierNode, InjectionNode, IntRangeNode, ListTypeNode, LiteralNode, LiteralTypeNode, ModuleNode, NumericTypeNode, PathNode, PrimitiveArrayTypeNode, ReferenceTypeNode, StringTypeNode, StructNode, TupleTypeNode, TypeAliasNode, TypedNumberNode, TypeNode, UnionTypeNode, UseStatementNode } from '../node/index.js';
3
+ import type { AnyTypeNode, AttributeNode, BooleanTypeNode, DispatcherTypeNode, DispatchStatementNode, DocCommentsNode, EnumNode, FloatRangeNode, IdentifierNode, InjectionNode, IntRangeNode, ListTypeNode, LiteralNode, LiteralTypeNode, LongRangeNode, ModuleNode, NumericTypeNode, PathNode, PrimitiveArrayTypeNode, ReferenceTypeNode, StringTypeNode, StructNode, TupleTypeNode, TypeAliasNode, TypedNumberNode, TypeNode, UnionTypeNode, UseStatementNode } from '../node/index.js';
4
4
  /**
5
5
  * @returns A comment parser that accepts normal comments (`//`) and reports an error if it's a doc comment (`///`).
6
6
  *
@@ -27,6 +27,7 @@ export declare const docComments: InfallibleParser<DocCommentsNode>;
27
27
  export declare const dispatchStatement: Parser<DispatchStatementNode>;
28
28
  export declare const float: InfallibleParser<FloatNode>;
29
29
  export declare const integer: InfallibleParser<IntegerNode>;
30
+ export declare const long: InfallibleParser<LongNode>;
30
31
  export declare const LiteralIntSuffixes: readonly ["b", "s", "l"];
31
32
  export type LiteralIntSuffix = (typeof LiteralIntSuffixes)[number];
32
33
  export declare const LiteralIntCaseInsensitiveSuffixes: readonly ["b", "s", "l", "B", "S", "L"];
@@ -40,6 +41,7 @@ export type LiteralNumberSuffix = (typeof LiteralNumberSuffixes)[number];
40
41
  export declare const LiteralNumberCaseInsensitiveSuffixes: readonly ["b", "s", "l", "f", "d", "b", "s", "l", "B", "S", "L", "f", "d", "F", "D"];
41
42
  export type LiteralNumberCaseInsensitiveSuffix = (typeof LiteralNumberCaseInsensitiveSuffixes)[number];
42
43
  export declare const typedNumber: InfallibleParser<TypedNumberNode>;
44
+ export declare const failableTypedNumber: Parser<TypedNumberNode>;
43
45
  export declare const enum_: Parser<EnumNode>;
44
46
  export declare const struct: Parser<StructNode>;
45
47
  export declare const injection: Parser<InjectionNode>;
@@ -49,9 +51,13 @@ export declare const module_: Parser<ModuleNode>;
49
51
  export declare const anyType: Parser<AnyTypeNode>;
50
52
  export declare const booleanType: Parser<BooleanTypeNode>;
51
53
  export declare const intRange: InfallibleParser<IntRangeNode>;
54
+ export declare const longRange: InfallibleParser<LongRangeNode>;
55
+ export declare const floatRange: InfallibleParser<FloatRangeNode>;
56
+ export declare const atIntRange: InfallibleParser<IntRangeNode | undefined>;
57
+ export declare const atLongRange: InfallibleParser<LongRangeNode | undefined>;
58
+ export declare const atFloatRange: InfallibleParser<FloatRangeNode | undefined>;
52
59
  export declare const stringType: Parser<StringTypeNode>;
53
60
  export declare const literalType: Parser<LiteralTypeNode>;
54
- export declare const floatRange: InfallibleParser<FloatRangeNode>;
55
61
  export declare const numericType: Parser<NumericTypeNode>;
56
62
  export declare const primitiveArrayType: Parser<PrimitiveArrayTypeNode>;
57
63
  export declare const listType: Parser<ListTypeNode>;
@@ -326,6 +326,9 @@ export const float = core.float({
326
326
  export const integer = core.integer({
327
327
  pattern: /^(?:0|[-+]?[1-9][0-9]*)$/,
328
328
  });
329
+ export const long = core.long({
330
+ pattern: /^(?:0|[-+]?[1-9][0-9]*)$/,
331
+ });
329
332
  export const LiteralIntSuffixes = Object.freeze(['b', 's', 'l']);
330
333
  export const LiteralIntCaseInsensitiveSuffixes = Object.freeze([...LiteralIntSuffixes, 'B', 'S', 'L']);
331
334
  export const LiteralFloatSuffixes = Object.freeze(['f', 'd']);
@@ -337,17 +340,37 @@ export const LiteralNumberCaseInsensitiveSuffixes = Object.freeze([
337
340
  ...LiteralFloatCaseInsensitiveSuffixes,
338
341
  ]);
339
342
  export const typedNumber = setType('mcdoc:typed_number', select([{
343
+ regex: /^(?:\+|-)?\d+L/i,
344
+ parser: sequence([
345
+ long,
346
+ optional(failOnEmpty(literal(LiteralIntCaseInsensitiveSuffixes, { colorTokenType: 'keyword' }))),
347
+ ]),
348
+ }, {
340
349
  regex: /^(?:\+|-)?\d+(?!\d|[.dfe])/i,
341
350
  parser: sequence([
342
351
  integer,
343
- optional(keyword(LiteralIntCaseInsensitiveSuffixes, { colorTokenType: 'keyword' })),
352
+ optional(failOnEmpty(literal(LiteralIntCaseInsensitiveSuffixes, { colorTokenType: 'keyword' }))),
344
353
  ]),
345
354
  }, {
346
355
  parser: sequence([
347
356
  float,
348
- optional(keyword(LiteralFloatCaseInsensitiveSuffixes, { colorTokenType: 'keyword' })),
357
+ optional(failOnEmpty(literal(LiteralFloatCaseInsensitiveSuffixes, { colorTokenType: 'keyword' }))),
349
358
  ]),
350
359
  }]));
360
+ export const failableTypedNumber = (src, ctx) => {
361
+ const { updateSrcAndCtx, result, errorAmount } = core.attempt(typedNumber, src, ctx);
362
+ if (errorAmount > 0) {
363
+ if (result.children.length !== 2) {
364
+ return Failure;
365
+ }
366
+ const { errorAmount: numberErrors } = core.attempt(float, src, ctx);
367
+ if (numberErrors > 0) {
368
+ return Failure;
369
+ }
370
+ }
371
+ updateSrcAndCtx();
372
+ return result;
373
+ };
351
374
  const enumValue = select([{ prefix: '"', parser: string }, {
352
375
  parser: typedNumber,
353
376
  }]);
@@ -471,14 +494,21 @@ function range(type, number) {
471
494
  ]),
472
495
  }]));
473
496
  }
497
+ function atRange(parser) {
498
+ return optional((src, ctx) => {
499
+ if (!src.trySkip('@')) {
500
+ return Failure;
501
+ }
502
+ src.skipWhitespace();
503
+ return parser(src, ctx);
504
+ });
505
+ }
474
506
  export const intRange = range('mcdoc:int_range', integer);
475
- const atIntRange = optional((src, ctx) => {
476
- if (!src.trySkip('@')) {
477
- return Failure;
478
- }
479
- src.skipWhitespace();
480
- return intRange(src, ctx);
481
- });
507
+ export const longRange = range('mcdoc:long_range', long);
508
+ export const floatRange = range('mcdoc:float_range', float);
509
+ export const atIntRange = atRange(intRange);
510
+ export const atLongRange = atRange(longRange);
511
+ export const atFloatRange = atRange(floatRange);
482
512
  export const stringType = typeBase('mcdoc:type/string', syntax([
483
513
  keyword('string', { colorTokenType: 'type' }),
484
514
  atIntRange,
@@ -489,25 +519,24 @@ export const literalType = typeBase('mcdoc:type/literal', select([
489
519
  parser: keyword(['false', 'true'], { colorTokenType: 'type' }),
490
520
  },
491
521
  { prefix: '"', parser: failOnEmpty(string) },
492
- { parser: failOnError(typedNumber) },
522
+ { parser: failableTypedNumber },
493
523
  ]));
494
- export const floatRange = range('mcdoc:float_range', float);
495
- const atFloatRange = optional((src, ctx) => {
496
- if (!src.trySkip('@')) {
497
- return Failure;
498
- }
499
- src.skipWhitespace();
500
- return floatRange(src, ctx);
501
- });
502
524
  export const numericType = typeBase('mcdoc:type/numeric_type', select([{
503
525
  predicate: (src) => NumericTypeFloatKinds.some((k) => src.tryPeek(k)),
504
526
  parser: syntax([keyword(NumericTypeFloatKinds, { colorTokenType: 'type' }), atFloatRange], true),
527
+ }, {
528
+ predicate: (src) => src.tryPeek('long'),
529
+ parser: syntax([keyword('long', { colorTokenType: 'type' }), atLongRange], true),
505
530
  }, {
506
531
  parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atIntRange], true),
507
532
  }]));
508
533
  export const primitiveArrayType = typeBase('mcdoc:type/primitive_array', syntax([
509
- literal(PrimitiveArrayValueKinds),
510
- atIntRange,
534
+ select([{
535
+ predicate: (src) => src.tryPeek('long'),
536
+ parser: syntax([literal('long'), atLongRange], true),
537
+ }, {
538
+ parser: syntax([literal(PrimitiveArrayValueKinds), atIntRange], true),
539
+ }]),
511
540
  keyword('[]', { allowedChars: new Set(['[', ']']), colorTokenType: 'type' }),
512
541
  atIntRange,
513
542
  ]));
@@ -83,7 +83,8 @@ export function registerBuiltinAttributes(meta) {
83
83
  }
84
84
  const value = typeDef.value.value;
85
85
  return (node, ctx) => {
86
- if (value % config !== 0) {
86
+ const moduloResult = typeof value === 'number' ? value % config : value % BigInt(config);
87
+ if (moduloResult !== 0 && moduloResult !== 0n) {
87
88
  ctx.err.report(localize('not-divisible-by', value, config), node, core.ErrorSeverity.Warning);
88
89
  }
89
90
  };
@@ -1,6 +1,5 @@
1
1
  import type { CheckerContext, FullResourceLocation } from '@spyglassmc/core';
2
- import { type EnumKind } from '../../node/index.js';
3
- import type { EnumType, Index, KeywordType, ListType, LiteralType, NumericType, ParallelIndices, PrimitiveArrayType, StringType, StructType, StructTypePairField, TupleType, UnionType } from '../../type/index.js';
2
+ import type { EnumType, Index, KeywordType, ListType, LiteralType, LongType, NumericType, ParallelIndices, PrimitiveArrayType, StringType, StructType, StructTypePairField, TupleType, UnionType } from '../../type/index.js';
4
3
  import { McdocType } from '../../type/index.js';
5
4
  import type { NodeEquivalenceChecker, RuntimeNode } from './context.js';
6
5
  import { McdocCheckerContext } from './context.js';
@@ -8,10 +7,7 @@ import type { McdocRuntimeError } from './error.js';
8
7
  export * from './context.js';
9
8
  export * from './error.js';
10
9
  export type SimplifiedMcdocType = SimplifiedMcdocTypeNoUnion | UnionType<SimplifiedMcdocTypeNoUnion>;
11
- export type SimplifiedMcdocTypeNoUnion = SimplifiedEnum | KeywordType | ListType | LiteralType | NumericType | PrimitiveArrayType | StringType | SimplifiedStructType | TupleType;
12
- export interface SimplifiedEnum extends EnumType {
13
- enumKind: EnumKind;
14
- }
10
+ export type SimplifiedMcdocTypeNoUnion = EnumType | KeywordType | ListType | LiteralType | NumericType | LongType | PrimitiveArrayType | StringType | SimplifiedStructType | TupleType;
15
11
  export interface SimplifiedStructType extends StructType {
16
12
  fields: SimplifiedStructTypePairField[];
17
13
  }
@@ -92,6 +92,10 @@ export function typeDefinition(runtimeValues, typeDef, ctx) {
92
92
  const validRootDefinitions = simplifiedRoot.kind === 'union'
93
93
  ? simplifiedRoot.members
94
94
  : [simplifiedRoot];
95
+ if (validRootDefinitions.length === 0
96
+ && (typeDef.kind !== 'union' || typeDef.members.length > 0)) {
97
+ validRootDefinitions.push({ kind: 'any' });
98
+ }
95
99
  value.definitionsByParent = [{
96
100
  parents: [],
97
101
  keyDefinition: undefined,
@@ -313,7 +317,8 @@ function checkShallowly(runtimeNode, simplifiedInferred, children, typeDef, ctx)
313
317
  case 'double':
314
318
  if (typeDef.valueRange
315
319
  && simplifiedInferred.kind === 'literal'
316
- && typeof simplifiedInferred.value.value === 'number'
320
+ && simplifiedInferred.value.kind !== 'string'
321
+ && simplifiedInferred.value.kind !== 'boolean'
317
322
  && !NumericRange.isInRange(typeDef.valueRange, simplifiedInferred.value.value)) {
318
323
  errors.push({
319
324
  kind: 'number_out_of_range',
@@ -903,7 +908,7 @@ function simplifyTuple(typeDef, context) {
903
908
  }
904
909
  function simplifyEnum(typeDef, context) {
905
910
  const filteredValues = typeDef.values.filter(value => shouldKeepAccordingToAttributeFilters(value.attributes, context.ctx));
906
- return { typeDef: { ...typeDef, enumKind: typeDef.enumKind ?? 'int', values: filteredValues } };
911
+ return { typeDef: { ...typeDef, values: filteredValues } };
907
912
  }
908
913
  function simplifyConcrete(typeDef, context) {
909
914
  let dynamicData = false;
@@ -947,6 +952,9 @@ function getValueType(type) {
947
952
  case 'literal':
948
953
  return { kind: type.value.kind };
949
954
  case 'enum':
955
+ if (type.enumKind === undefined) {
956
+ return { kind: 'any' };
957
+ }
950
958
  return { kind: type.enumKind };
951
959
  default:
952
960
  return type;
@@ -1,5 +1,4 @@
1
1
  import type { FullResourceLocation } from '@spyglassmc/core';
2
- import type { EnumKind } from '../node/index.js';
3
2
  import { RangeKind } from '../node/index.js';
4
3
  export type Attributes = Attribute[];
5
4
  export declare namespace Attributes {
@@ -23,15 +22,15 @@ export interface AttributeTree {
23
22
  export declare namespace AttributeValue {
24
23
  function equals(a: AttributeValue, b: AttributeValue): boolean;
25
24
  }
26
- export type NumericRange = {
25
+ export interface NumericRange<T extends (number | bigint) = (number | bigint)> {
27
26
  kind: RangeKind;
28
- min?: number;
29
- max?: number;
30
- };
27
+ min?: T;
28
+ max?: T;
29
+ }
31
30
  export declare namespace NumericRange {
32
- function isInRange(range: NumericRange, val: number): boolean;
31
+ function isInRange<T extends (number | bigint) = (number | bigint)>(range: NumericRange<T>, val: T): boolean;
33
32
  function equals(a: NumericRange, b: NumericRange): boolean;
34
- function intersect(a: NumericRange, b: NumericRange): NumericRange;
33
+ function intersect<T extends (number | bigint) = number>(a: NumericRange<T>, b: NumericRange<T>): NumericRange<T>;
35
34
  function toString({ kind, min, max }: NumericRange): string;
36
35
  }
37
36
  export declare const StaticIndexKeywords: readonly ["fallback", "none", "unknown", "spawnitem", "blockitem"];
@@ -78,14 +77,29 @@ export interface StructTypeSpreadField extends McdocBaseType {
78
77
  kind: 'spread';
79
78
  type: McdocType;
80
79
  }
81
- export interface EnumType extends McdocBaseType {
80
+ export type EnumType = NumberEnumType | LongEnumType | StringEnumType | InvalidEnumType;
81
+ interface EnumTypeBase extends McdocBaseType {
82
82
  kind: 'enum';
83
- enumKind?: EnumKind;
84
- values: EnumTypeField[];
85
83
  }
86
- export interface EnumTypeField extends McdocBaseType {
84
+ interface NumberEnumType extends EnumTypeBase {
85
+ enumKind: 'byte' | 'short' | 'int' | 'float' | 'double';
86
+ values: EnumTypeField<number>[];
87
+ }
88
+ interface LongEnumType extends EnumTypeBase {
89
+ enumKind: 'long';
90
+ values: EnumTypeField<bigint>[];
91
+ }
92
+ interface StringEnumType extends EnumTypeBase {
93
+ enumKind: 'string';
94
+ values: EnumTypeField<string>[];
95
+ }
96
+ interface InvalidEnumType extends EnumTypeBase {
97
+ enumKind: undefined;
98
+ values: EnumTypeField<string | number | bigint>[];
99
+ }
100
+ export interface EnumTypeField<T> extends McdocBaseType {
87
101
  identifier: string;
88
- value: string | number;
102
+ value: T;
89
103
  desc?: string;
90
104
  }
91
105
  export interface ReferenceType extends McdocBaseType {
@@ -127,9 +141,9 @@ export interface KeywordType extends McdocBaseType {
127
141
  }
128
142
  export interface StringType extends McdocBaseType {
129
143
  kind: 'string';
130
- lengthRange?: NumericRange;
144
+ lengthRange?: NumericRange<number>;
131
145
  }
132
- export type LiteralValue = LiteralBooleanValue | LiteralStringValue | LiteralNumericValue;
146
+ export type LiteralValue = LiteralBooleanValue | LiteralStringValue | LiteralNumericValue | LiteralLongNumberValue;
133
147
  export interface LiteralBooleanValue {
134
148
  kind: 'boolean';
135
149
  value: boolean;
@@ -139,16 +153,24 @@ export interface LiteralStringValue {
139
153
  value: string;
140
154
  }
141
155
  export interface LiteralNumericValue {
142
- kind: NumericTypeKind;
156
+ kind: Exclude<NumericTypeKind, 'long'>;
143
157
  value: number;
144
158
  }
159
+ export interface LiteralLongNumberValue {
160
+ kind: 'long';
161
+ value: bigint;
162
+ }
145
163
  export interface LiteralType extends McdocBaseType {
146
164
  kind: 'literal';
147
165
  value: LiteralValue;
148
166
  }
149
167
  export interface NumericType extends McdocBaseType {
150
- kind: NumericTypeKind;
151
- valueRange?: NumericRange;
168
+ kind: Exclude<NumericTypeKind, 'long'>;
169
+ valueRange?: NumericRange<number>;
170
+ }
171
+ export interface LongType extends McdocBaseType {
172
+ kind: 'long';
173
+ valueRange?: NumericRange<bigint>;
152
174
  }
153
175
  export declare const NumericTypeIntKinds: readonly ["byte", "short", "int", "long"];
154
176
  export type NumericTypeIntKind = (typeof NumericTypeIntKinds)[number];
@@ -156,10 +178,16 @@ export declare const NumericTypeFloatKinds: readonly ["float", "double"];
156
178
  export type NumericTypeFloatKind = (typeof NumericTypeFloatKinds)[number];
157
179
  export declare const NumericTypeKinds: readonly ["byte", "short", "int", "long", "float", "double"];
158
180
  export type NumericTypeKind = (typeof NumericTypeKinds)[number];
159
- export interface PrimitiveArrayType extends McdocBaseType {
160
- kind: 'byte_array' | 'int_array' | 'long_array';
161
- valueRange?: NumericRange;
162
- lengthRange?: NumericRange;
181
+ export type PrimitiveArrayType = SmallIntArrayType | LongArrayType;
182
+ export interface SmallIntArrayType extends McdocBaseType {
183
+ kind: 'byte_array' | 'int_array';
184
+ valueRange?: NumericRange<number>;
185
+ lengthRange?: NumericRange<number>;
186
+ }
187
+ export interface LongArrayType extends McdocBaseType {
188
+ kind: 'long_array';
189
+ valueRange?: NumericRange<bigint>;
190
+ lengthRange?: NumericRange<number>;
163
191
  }
164
192
  export declare const PrimitiveArrayValueKinds: readonly ["byte", "int", "long"];
165
193
  export type PrimitiveArrayValueKind = (typeof PrimitiveArrayValueKinds)[number];
@@ -168,7 +196,7 @@ export type PrimitiveArrayKind = (typeof PrimitiveArrayKinds)[number];
168
196
  export interface ListType extends McdocBaseType {
169
197
  kind: 'list';
170
198
  item: McdocType;
171
- lengthRange?: NumericRange;
199
+ lengthRange?: NumericRange<number>;
172
200
  }
173
201
  export interface TupleType extends McdocBaseType {
174
202
  kind: 'tuple';
@@ -177,9 +205,10 @@ export interface TupleType extends McdocBaseType {
177
205
  export interface McdocBaseType {
178
206
  attributes?: Attributes;
179
207
  }
180
- export type McdocType = DispatcherType | EnumType | KeywordType | ListType | LiteralType | NumericType | PrimitiveArrayType | ReferenceType | StringType | StructType | TupleType | UnionType | IndexedType | TemplateType | ConcreteType | MappedType;
208
+ export type McdocType = DispatcherType | EnumType | KeywordType | ListType | LiteralType | NumericType | LongType | PrimitiveArrayType | ReferenceType | StringType | StructType | TupleType | UnionType | IndexedType | TemplateType | ConcreteType | MappedType;
181
209
  export declare namespace McdocType {
182
210
  function equals(a: McdocType, b: McdocType): boolean;
183
211
  function toString(type: McdocType | undefined): string;
184
212
  }
213
+ export {};
185
214
  //# sourceMappingURL=index.d.ts.map
package/lib/type/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Arrayable, Dev } from '@spyglassmc/core';
1
+ import { Arrayable, Dev, max, min, numericEquals } from '@spyglassmc/core';
2
2
  import { getRangeDelimiter, RangeKind } from '../node/index.js';
3
3
  export var Attributes;
4
4
  (function (Attributes) {
@@ -73,35 +73,31 @@ export var NumericRange;
73
73
  NumericRange.isInRange = isInRange;
74
74
  function equals(a, b) {
75
75
  return a.kind === b.kind
76
- && a.min === b.min
77
- && a.max === b.max;
76
+ && numericEquals(a.min, b.min)
77
+ && numericEquals(a.max, b.max);
78
78
  }
79
79
  NumericRange.equals = equals;
80
80
  function intersect(a, b) {
81
- const min = a.min !== undefined && b.min !== undefined
82
- ? Math.max(a.min, b.min)
83
- : a.min !== undefined
84
- ? a.min
85
- : b.min;
86
- const max = a.max !== undefined && b.max !== undefined
87
- ? Math.min(a.max, b.max)
88
- : a.max !== undefined
89
- ? a.max
90
- : b.max;
81
+ const rangeMin = a.min !== undefined && b.min !== undefined
82
+ ? max(a.min, b.min)
83
+ : a.min ?? b.min;
84
+ const rangeMax = a.max !== undefined && b.max !== undefined
85
+ ? min(a.max, b.max)
86
+ : a.max ?? b.max;
91
87
  let kind = 0b00;
92
- if (min === a.min && RangeKind.isLeftExclusive(a.kind)) {
88
+ if (numericEquals(rangeMin, a.min) && RangeKind.isLeftExclusive(a.kind)) {
93
89
  kind |= 0b10;
94
90
  }
95
- else if (min === b.min && RangeKind.isLeftExclusive(b.kind)) {
91
+ else if (numericEquals(rangeMin, b.min) && RangeKind.isLeftExclusive(b.kind)) {
96
92
  kind |= 0b10;
97
93
  }
98
- if (max === a.max && RangeKind.isRightExclusive(a.kind)) {
94
+ if (numericEquals(rangeMax, a.max) && RangeKind.isRightExclusive(a.kind)) {
99
95
  kind |= 0b01;
100
96
  }
101
- else if (max === b.max && RangeKind.isRightExclusive(b.kind)) {
97
+ else if (numericEquals(rangeMax, b.max) && RangeKind.isRightExclusive(b.kind)) {
102
98
  kind |= 0b01;
103
99
  }
104
- return { kind: kind, min, max };
100
+ return { kind: kind, min: rangeMin, max: rangeMax };
105
101
  }
106
102
  NumericRange.intersect = intersect;
107
103
  function toString({ kind, min, max }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/mcdoc",
3
- "version": "0.3.48",
3
+ "version": "0.3.50",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "url": "https://github.com/SpyglassMC/Spyglass/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@spyglassmc/core": "0.4.44",
29
- "@spyglassmc/locales": "0.3.23"
28
+ "@spyglassmc/core": "0.4.46",
29
+ "@spyglassmc/locales": "0.3.24"
30
30
  }
31
31
  }