@spyglassmc/mcdoc 0.3.49 → 0.3.51

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, 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) {
@@ -288,7 +288,7 @@ async function bindPath(node, ctx) {
288
288
  },
289
289
  })).else(() => {
290
290
  if (indexRight === 0) {
291
- ctx.err.report(localize('mcdoc.binder.path.unknown-identifier', localeQuote(atArray(identifiers, -1)), localeQuote(pathArrayToString(identifiers.slice(0, -1)))), node, ErrorSeverity.Warning);
291
+ ctx.err.report(localize('mcdoc.binder.path.unknown-identifier', localeQuote(identifiers.at(-1)), localeQuote(pathArrayToString(identifiers.slice(0, -1)))), node, ErrorSeverity.Warning);
292
292
  }
293
293
  });
294
294
  }
@@ -413,7 +413,7 @@ function* resolvePathByStep(path, ctx, options = {}) {
413
413
  }
414
414
  }
415
415
  function resolvePath(path, ctx, options = {}) {
416
- return atArray([...resolvePathByStep(path, ctx, options)], -1)?.identifiers;
416
+ return [...resolvePathByStep(path, ctx, options)].at(-1)?.identifiers;
417
417
  }
418
418
  function identifierToUri(module, ctx) {
419
419
  return ctx.symbols.global.mcdoc?.[module]?.definition?.[0]?.uri;
@@ -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<"byte" | "double" | "float" | "int" | "long" | "short" | "string">;
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 { 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;
@@ -563,7 +581,7 @@ export var TypeParamNode;
563
581
  export var PathNode;
564
582
  (function (PathNode) {
565
583
  function destruct(node) {
566
- const lastChild = atArray(node?.children, -1);
584
+ const lastChild = node?.children.at(-1);
567
585
  return {
568
586
  children: node?.children ?? [],
569
587
  isAbsolute: node?.isAbsolute,
@@ -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
  };
@@ -12,7 +12,7 @@ export interface RuntimePair<T> {
12
12
  key: RuntimeNode<T>;
13
13
  possibleValues: RuntimeNode<T>[];
14
14
  }
15
- export type NodeEquivalenceChecker = (inferredNode: Exclude<SimplifiedMcdocTypeNoUnion, LiteralType | EnumType>, definition: Exclude<SimplifiedMcdocTypeNoUnion, LiteralType | EnumType>) => boolean;
15
+ export type TypeConverter<T> = (node: T, definition: Exclude<SimplifiedMcdocTypeNoUnion, LiteralType | EnumType>) => SimplifiedMcdocTypeNoUnion | undefined;
16
16
  export type TypeInfoAttacher<T> = (node: T, definition: SimplifiedMcdocType, description?: string) => void;
17
17
  export type NodeAttacher<T> = (node: T, attacher: (node: core.AstNode) => void) => void;
18
18
  export type StringAttacher<T> = (node: T, attacher: (node: core.StringBaseNode) => void) => void;
@@ -21,7 +21,7 @@ export type ErrorReporter<T> = (error: McdocRuntimeError<T>) => void;
21
21
  export interface McdocCheckerContext<T> extends core.CheckerContext {
22
22
  allowMissingKeys: boolean;
23
23
  requireCanonical: boolean;
24
- isEquivalent: NodeEquivalenceChecker;
24
+ tryConvertTo: TypeConverter<T>;
25
25
  getChildren: ChildrenGetter<T>;
26
26
  reportError: ErrorReporter<T>;
27
27
  attachTypeInfo?: TypeInfoAttacher<T>;
@@ -5,7 +5,7 @@ export var McdocCheckerContext;
5
5
  ...ctx,
6
6
  allowMissingKeys: options.allowMissingKeys ?? false,
7
7
  requireCanonical: options.requireCanonical ?? false,
8
- isEquivalent: options.isEquivalent ?? (() => false),
8
+ tryConvertTo: options.tryConvertTo ?? (() => undefined),
9
9
  getChildren: options.getChildren ?? (() => []),
10
10
  reportError: options.reportError ?? (() => { }),
11
11
  attachTypeInfo: options.attachTypeInfo,
@@ -1,17 +1,13 @@
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
- import type { NodeEquivalenceChecker, RuntimeNode } from './context.js';
4
+ import type { RuntimeNode, TypeConverter } from './context.js';
6
5
  import { McdocCheckerContext } from './context.js';
7
6
  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
  }
@@ -20,7 +16,7 @@ export interface SimplifiedStructTypePairField extends StructTypePairField {
20
16
  }
21
17
  export declare function reference<T>(node: RuntimeNode<T>[], path: string, ctx: McdocCheckerContext<T>): void;
22
18
  export declare function dispatcher<T>(node: RuntimeNode<T>[], registry: FullResourceLocation, index: string | Index | ParallelIndices, ctx: McdocCheckerContext<T>): void;
23
- export declare function isAssignable(assignValue: McdocType, typeDef: McdocType, ctx: CheckerContext, isEquivalent?: NodeEquivalenceChecker): boolean;
19
+ export declare function isAssignable(assignValue: McdocType, typeDef: McdocType, ctx: CheckerContext, convert?: TypeConverter<McdocType>): boolean;
24
20
  export interface CheckerTreeNode<T> {
25
21
  parent: CheckerTreeRuntimeNode<T> | undefined;
26
22
  runtimeKey: RuntimeNode<T> | undefined;
@@ -18,7 +18,7 @@ export function dispatcher(node, registry, index, ctx) {
18
18
  : [index];
19
19
  typeDefinition(node, { kind: 'dispatcher', registry, parallelIndices }, ctx);
20
20
  }
21
- export function isAssignable(assignValue, typeDef, ctx, isEquivalent) {
21
+ export function isAssignable(assignValue, typeDef, ctx, convert) {
22
22
  if (assignValue.kind === 'literal' && typeDef.kind === 'literal'
23
23
  && assignValue.value.kind === typeDef.value.kind
24
24
  && !assignValue.attributes && !typeDef.attributes) {
@@ -26,18 +26,27 @@ export function isAssignable(assignValue, typeDef, ctx, isEquivalent) {
26
26
  }
27
27
  let ans = true;
28
28
  const newCtx = McdocCheckerContext.create(ctx, {
29
- isEquivalent,
29
+ tryConvertTo: convert,
30
30
  getChildren: (_, d) => {
31
31
  switch (d.kind) {
32
32
  case 'list':
33
33
  const vals = getPossibleTypes(d.item);
34
34
  return [vals.map(v => ({ originalNode: v, inferredType: v }))];
35
35
  case 'byte_array':
36
- return [[{ originalNode: { kind: 'byte' }, inferredType: { kind: 'byte' } }]];
36
+ return [[{
37
+ originalNode: { kind: 'byte' },
38
+ inferredType: { kind: 'byte' },
39
+ }]];
37
40
  case 'int_array':
38
- return [[{ originalNode: { kind: 'int' }, inferredType: { kind: 'int' } }]];
41
+ return [[{
42
+ originalNode: { kind: 'int' },
43
+ inferredType: { kind: 'int' },
44
+ }]];
39
45
  case 'long_array':
40
- return [[{ originalNode: { kind: 'long' }, inferredType: { kind: 'long' } }]];
46
+ return [[{
47
+ originalNode: { kind: 'long' },
48
+ inferredType: { kind: 'long' },
49
+ }]];
41
50
  case 'struct':
42
51
  return d.fields.map(f => {
43
52
  const vals = getPossibleTypes(f.type);
@@ -92,6 +101,10 @@ export function typeDefinition(runtimeValues, typeDef, ctx) {
92
101
  const validRootDefinitions = simplifiedRoot.kind === 'union'
93
102
  ? simplifiedRoot.members
94
103
  : [simplifiedRoot];
104
+ if (validRootDefinitions.length === 0
105
+ && (typeDef.kind !== 'union' || typeDef.members.length > 0)) {
106
+ validRootDefinitions.push({ kind: 'any' });
107
+ }
95
108
  value.definitionsByParent = [{
96
109
  parents: [],
97
110
  keyDefinition: undefined,
@@ -274,9 +287,13 @@ function checkShallowly(runtimeNode, simplifiedInferred, children, typeDef, ctx)
274
287
  return { childDefinitions, errors: [] };
275
288
  }
276
289
  const typeDefValueType = getValueType(typeDef);
277
- const runtimeValueType = getValueType(simplifiedInferred);
278
- if (runtimeValueType.kind !== typeDefValueType.kind
279
- && !ctx.isEquivalent(runtimeValueType, typeDefValueType)) {
290
+ let runtimeValueType = getValueType(simplifiedInferred);
291
+ if (runtimeValueType.kind !== typeDefValueType.kind) {
292
+ simplifiedInferred = ctx.tryConvertTo(runtimeNode.originalNode, typeDefValueType)
293
+ ?? simplifiedInferred;
294
+ runtimeValueType = getValueType(simplifiedInferred);
295
+ }
296
+ if (runtimeValueType.kind !== typeDefValueType.kind) {
280
297
  return {
281
298
  childDefinitions,
282
299
  errors: [{ kind: 'type_mismatch', node: runtimeNode, expected: [typeDef] }],
@@ -313,7 +330,8 @@ function checkShallowly(runtimeNode, simplifiedInferred, children, typeDef, ctx)
313
330
  case 'double':
314
331
  if (typeDef.valueRange
315
332
  && simplifiedInferred.kind === 'literal'
316
- && typeof simplifiedInferred.value.value === 'number'
333
+ && simplifiedInferred.value.kind !== 'string'
334
+ && simplifiedInferred.value.kind !== 'boolean'
317
335
  && !NumericRange.isInRange(typeDef.valueRange, simplifiedInferred.value.value)) {
318
336
  errors.push({
319
337
  kind: 'number_out_of_range',
@@ -373,14 +391,22 @@ function checkShallowly(runtimeNode, simplifiedInferred, children, typeDef, ctx)
373
391
  }
374
392
  if (!foundMatch) {
375
393
  for (const kvp of otherKvps) {
376
- if (isAssignable(kvp.value.key.inferredType, pair.key, ctx, ctx.isEquivalent)) {
394
+ if (isAssignable(kvp.value.key.inferredType, pair.key, ctx, (type, target) => type === kvp.value.key.inferredType
395
+ ? ctx.tryConvertTo(kvp.value.key.originalNode, target)
396
+ : undefined)) {
377
397
  foundMatch = true;
378
398
  otherKvpMatches.push(kvp.index);
379
399
  }
380
400
  }
381
401
  for (const kvp of literalKvps.entries()) {
402
+ const literalType = {
403
+ kind: 'literal',
404
+ value: { kind: 'string', value: kvp[0] },
405
+ };
382
406
  if ((!kvp[1].definition || kvp[1].definition.keyType?.kind !== 'literal')
383
- && isAssignable({ kind: 'literal', value: { kind: 'string', value: kvp[0] } }, pair.key, ctx, ctx.isEquivalent)) {
407
+ && kvp[1].values.some(v => isAssignable(literalType, pair.key, ctx, (type, target) => type === literalType
408
+ ? ctx.tryConvertTo(v.pair.key.originalNode, target)
409
+ : undefined))) {
384
410
  foundMatch = true;
385
411
  kvp[1].definition = { keyType: pair.key, type: pair.type, desc: pair.desc };
386
412
  }
@@ -903,7 +929,7 @@ function simplifyTuple(typeDef, context) {
903
929
  }
904
930
  function simplifyEnum(typeDef, context) {
905
931
  const filteredValues = typeDef.values.filter(value => shouldKeepAccordingToAttributeFilters(value.attributes, context.ctx));
906
- return { typeDef: { ...typeDef, enumKind: typeDef.enumKind ?? 'int', values: filteredValues } };
932
+ return { typeDef: { ...typeDef, values: filteredValues } };
907
933
  }
908
934
  function simplifyConcrete(typeDef, context) {
909
935
  let dynamicData = false;
@@ -947,6 +973,9 @@ function getValueType(type) {
947
973
  case 'literal':
948
974
  return { kind: type.value.kind };
949
975
  case 'enum':
976
+ if (type.enumKind === undefined) {
977
+ return { kind: 'any' };
978
+ }
950
979
  return { kind: type.enumKind };
951
980
  default:
952
981
  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,27 @@ 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
+ }
163
+ export declare namespace LiteralNumericValue {
164
+ function makeIfValid(kind: string, value: number | bigint, allowInt?: boolean, allowFloat?: boolean): LiteralNumericValue | LiteralLongNumberValue | undefined;
165
+ }
145
166
  export interface LiteralType extends McdocBaseType {
146
167
  kind: 'literal';
147
168
  value: LiteralValue;
148
169
  }
149
170
  export interface NumericType extends McdocBaseType {
150
- kind: NumericTypeKind;
151
- valueRange?: NumericRange;
171
+ kind: Exclude<NumericTypeKind, 'long'>;
172
+ valueRange?: NumericRange<number>;
173
+ }
174
+ export interface LongType extends McdocBaseType {
175
+ kind: 'long';
176
+ valueRange?: NumericRange<bigint>;
152
177
  }
153
178
  export declare const NumericTypeIntKinds: readonly ["byte", "short", "int", "long"];
154
179
  export type NumericTypeIntKind = (typeof NumericTypeIntKinds)[number];
@@ -156,10 +181,16 @@ export declare const NumericTypeFloatKinds: readonly ["float", "double"];
156
181
  export type NumericTypeFloatKind = (typeof NumericTypeFloatKinds)[number];
157
182
  export declare const NumericTypeKinds: readonly ["byte", "short", "int", "long", "float", "double"];
158
183
  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;
184
+ export type PrimitiveArrayType = SmallIntArrayType | LongArrayType;
185
+ export interface SmallIntArrayType extends McdocBaseType {
186
+ kind: 'byte_array' | 'int_array';
187
+ valueRange?: NumericRange<number>;
188
+ lengthRange?: NumericRange<number>;
189
+ }
190
+ export interface LongArrayType extends McdocBaseType {
191
+ kind: 'long_array';
192
+ valueRange?: NumericRange<bigint>;
193
+ lengthRange?: NumericRange<number>;
163
194
  }
164
195
  export declare const PrimitiveArrayValueKinds: readonly ["byte", "int", "long"];
165
196
  export type PrimitiveArrayValueKind = (typeof PrimitiveArrayValueKinds)[number];
@@ -168,7 +199,7 @@ export type PrimitiveArrayKind = (typeof PrimitiveArrayKinds)[number];
168
199
  export interface ListType extends McdocBaseType {
169
200
  kind: 'list';
170
201
  item: McdocType;
171
- lengthRange?: NumericRange;
202
+ lengthRange?: NumericRange<number>;
172
203
  }
173
204
  export interface TupleType extends McdocBaseType {
174
205
  kind: 'tuple';
@@ -177,9 +208,10 @@ export interface TupleType extends McdocBaseType {
177
208
  export interface McdocBaseType {
178
209
  attributes?: Attributes;
179
210
  }
180
- export type McdocType = DispatcherType | EnumType | KeywordType | ListType | LiteralType | NumericType | PrimitiveArrayType | ReferenceType | StringType | StructType | TupleType | UnionType | IndexedType | TemplateType | ConcreteType | MappedType;
211
+ export type McdocType = DispatcherType | EnumType | KeywordType | ListType | LiteralType | NumericType | LongType | PrimitiveArrayType | ReferenceType | StringType | StructType | TupleType | UnionType | IndexedType | TemplateType | ConcreteType | MappedType;
181
212
  export declare namespace McdocType {
182
213
  function equals(a: McdocType, b: McdocType): boolean;
183
214
  function toString(type: McdocType | undefined): string;
184
215
  }
216
+ export {};
185
217
  //# 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 }) {
@@ -154,6 +150,46 @@ export function createEmptyUnion(attributes) {
154
150
  // attributes,
155
151
  };
156
152
  }
153
+ export var LiteralNumericValue;
154
+ (function (LiteralNumericValue) {
155
+ function makeIfValid(kind, value, allowInt = true, allowFloat = true) {
156
+ value = Number(value);
157
+ switch (kind) {
158
+ case 'byte':
159
+ if (allowInt && value >= -128 && value < 128) {
160
+ return { kind: 'byte', value };
161
+ }
162
+ break;
163
+ case 'short':
164
+ if (allowInt && value >= -32768 && value < 32768) {
165
+ return { kind: 'short', value };
166
+ }
167
+ break;
168
+ case 'int':
169
+ if (allowInt && value >= -2147483648 && value < 2147483648) {
170
+ return { kind: 'int', value };
171
+ }
172
+ break;
173
+ case 'long':
174
+ if (allowInt && value >= -9223372036854775808n && value < 9223372036854775808n) {
175
+ return { kind: 'long', value: BigInt(value) };
176
+ }
177
+ break;
178
+ case 'float':
179
+ if (allowFloat) {
180
+ return { kind: 'float', value };
181
+ }
182
+ break;
183
+ case 'double':
184
+ if (allowFloat) {
185
+ return { kind: 'double', value };
186
+ }
187
+ break;
188
+ }
189
+ return undefined;
190
+ }
191
+ LiteralNumericValue.makeIfValid = makeIfValid;
192
+ })(LiteralNumericValue || (LiteralNumericValue = {}));
157
193
  export const NumericTypeIntKinds = Object.freeze(['byte', 'short', 'int', 'long']);
158
194
  export const NumericTypeFloatKinds = Object.freeze(['float', 'double']);
159
195
  export const NumericTypeKinds = Object.freeze([...NumericTypeIntKinds, ...NumericTypeFloatKinds]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spyglassmc/mcdoc",
3
- "version": "0.3.49",
3
+ "version": "0.3.51",
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.45",
29
- "@spyglassmc/locales": "0.3.23"
28
+ "@spyglassmc/core": "0.4.47",
29
+ "@spyglassmc/locales": "0.3.24"
30
30
  }
31
31
  }