From b5ffbb22952f40bdc096c7d19d6cf02a8e9e0a48 Mon Sep 17 00:00:00 2001 From: NeunEinser Date: Sun, 7 Jul 2024 13:05:24 +0200 Subject: [PATCH 1/2] Use bigint for longtypes in mcdoc --- .../test-out/__fixture__/simple_types.spec.js | 6 +- packages/json/src/checker/index.ts | 5 +- packages/mcdoc/src/binder/index.ts | 38 +++++++---- packages/mcdoc/src/node/index.ts | 68 +++++++++++++------ packages/mcdoc/src/parser/index.ts | 65 ++++++++++++------ packages/mcdoc/src/runtime/checker/index.ts | 5 +- packages/mcdoc/src/type/index.ts | 67 ++++++++++++------ packages/nbt/src/checker/index.ts | 6 +- 8 files changed, 176 insertions(+), 84 deletions(-) diff --git a/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js b/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js index 6e119b1a9..20330916f 100644 --- a/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js +++ b/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js @@ -391,7 +391,7 @@ exports['mcdoc __fixture__ simple types 1'] = { "kind": "literal", "value": { "kind": "long", - "value": 42 + "value": "42" } } }, @@ -1497,12 +1497,12 @@ exports['mcdoc __fixture__ simple types 1'] = { "type": "mcdoc:typed_number", "children": [ { - "type": "integer", + "type": "long", "range": { "start": 249, "end": 251 }, - "value": 42 + "value": "42" }, { "type": "mcdoc:literal", diff --git a/packages/json/src/checker/index.ts b/packages/json/src/checker/index.ts index 40d71a27e..eb25a04e8 100644 --- a/packages/json/src/checker/index.ts +++ b/packages/json/src/checker/index.ts @@ -123,7 +123,10 @@ function inferType(node: JsonNode): Exclude { case 'json:number': return { kind: 'literal', - value: { kind: node.value.type, value: Number(node.value.value) }, + value: { + kind: node.value.type, + value: node.value.value, + } as (mcdoc.LiteralNumericValue | mcdoc.LiteralLongNumberValue), } case 'json:null': return { kind: 'any' } // null is always invalid? diff --git a/packages/mcdoc/src/binder/index.ts b/packages/mcdoc/src/binder/index.ts index a98f438be..760bc2763 100644 --- a/packages/mcdoc/src/binder/index.ts +++ b/packages/mcdoc/src/binder/index.ts @@ -55,6 +55,7 @@ import { ListTypeNode, LiteralNode, LiteralTypeNode, + LongRangeNode, NumericTypeNode, PathNode, PrimitiveArrayTypeNode, @@ -870,7 +871,7 @@ function convertEnumField(node: EnumFieldNode, ctx: McdocBinderContext): EnumTyp } } -function convertEnumValue(node: EnumValueNode, ctx: McdocBinderContext): string | number { +function convertEnumValue(node: EnumValueNode, ctx: McdocBinderContext): string | number | bigint { if (TypedNumberNode.is(node)) { const { value } = TypedNumberNode.destruct(node) return value.value @@ -964,23 +965,30 @@ function convertList(node: ListTypeNode, ctx: McdocBinderContext): McdocType { return wrapType(node, { kind: 'list', item: convertType(item, ctx), - lengthRange: convertRange(lengthRange, ctx), + lengthRange: convertRange(lengthRange), }, ctx) } -function convertRange(node: FloatRangeNode | IntRangeNode, ctx: McdocBinderContext): NumericRange +function convertRange(node: FloatRangeNode | IntRangeNode): NumericRange +function convertRange(node: LongRangeNode): NumericRange function convertRange( node: FloatRangeNode | IntRangeNode | undefined, - ctx: McdocBinderContext, -): NumericRange | undefined +): NumericRange | undefined +function convertRange(node: LongRangeNode | undefined): NumericRange | undefined function convertRange( - node: FloatRangeNode | IntRangeNode | undefined, - ctx: McdocBinderContext, -): NumericRange | undefined { + node: FloatRangeNode | IntRangeNode | LongRangeNode | undefined, +): NumericRange | NumericRange | undefined +function convertRange( + node: FloatRangeNode | IntRangeNode | LongRangeNode | undefined, +): NumericRange | NumericRange | undefined { if (!node) { return undefined } + if (LongRangeNode.is(node)) { + const { kind, min, max } = LongRangeNode.destruct(node) + return { kind, min: min?.value, max: max?.value } + } const { kind, min, max } = FloatRangeNode.is(node) ? FloatRangeNode.destruct(node) : IntRangeNode.destruct(node) @@ -1001,7 +1009,7 @@ function convertLiteralValue(node: LiteralTypeValueNode, ctx: McdocBinderContext kind: convertLiteralNumberSuffix(suffix, ctx) ?? (value.type === 'integer' ? 'int' : 'double'), value: value.value, - } + } as LiteralValue } else { return { kind: 'string', value: node.value } } @@ -1032,22 +1040,22 @@ function convertNumericType(node: NumericTypeNode, ctx: McdocBinderContext): Mcd const { numericKind, valueRange } = NumericTypeNode.destruct(node) return wrapType(node, { kind: numericKind.value as NumericTypeKind, - valueRange: convertRange(valueRange, ctx), - }, ctx) + valueRange: convertRange(valueRange), + } as McdocType, ctx) } function convertPrimitiveArray(node: PrimitiveArrayTypeNode, ctx: McdocBinderContext): McdocType { const { arrayKind, lengthRange, valueRange } = PrimitiveArrayTypeNode.destruct(node) return wrapType(node, { kind: `${arrayKind.value as PrimitiveArrayValueKind}_array`, - lengthRange: convertRange(lengthRange, ctx), - valueRange: convertRange(valueRange, ctx), - }, ctx) + lengthRange: convertRange(lengthRange), + valueRange: convertRange(valueRange), + } as McdocType, ctx) } function convertString(node: StringTypeNode, ctx: McdocBinderContext): McdocType { const { lengthRange } = StringTypeNode.destruct(node) - return wrapType(node, { kind: 'string', lengthRange: convertRange(lengthRange, ctx) }, ctx) + return wrapType(node, { kind: 'string', lengthRange: convertRange(lengthRange) }, ctx) } function convertReference(node: ReferenceTypeNode, ctx: McdocBinderContext): McdocType { diff --git a/packages/mcdoc/src/node/index.ts b/packages/mcdoc/src/node/index.ts index 57f6fc0ed..2189b140b 100644 --- a/packages/mcdoc/src/node/index.ts +++ b/packages/mcdoc/src/node/index.ts @@ -4,6 +4,7 @@ import { CommentNode, FloatNode, IntegerNode, + LongNode, ResourceLocationNode, StringNode, } from '@spyglassmc/core' @@ -329,6 +330,21 @@ export namespace IntRangeNode { } } +export interface LongRangeNode extends AstNode { + type: 'mcdoc:long_range' + children: (LongNode | LiteralNode)[] +} +export namespace LongRangeNode { + export function destruct( + node: LongRangeNode, + ): { kind: RangeKind; min?: LongNode; max?: LongNode } { + return destructRangeNode(node) + } + export function is(node: AstNode | undefined): node is LongRangeNode { + return (node as LongRangeNode | undefined)?.type === 'mcdoc:long_range' + } +} + export interface LiteralTypeNode extends TypeBaseNode { type: 'mcdoc:type/literal' } @@ -350,14 +366,16 @@ export namespace LiteralTypeValueNode { export interface TypedNumberNode extends AstNode { type: 'mcdoc:typed_number' - children: (FloatNode | IntegerNode | LiteralNode)[] + children: (FloatNode | IntegerNode | LongNode | LiteralNode)[] } export namespace TypedNumberNode { export function destruct( node: TypedNumberNode, - ): { value: FloatNode | IntegerNode; suffix?: LiteralNode } { + ): { value: FloatNode | IntegerNode | LongNode; suffix?: LiteralNode } { return { - value: node.children.find(FloatNode.is) ?? node.children.find(IntegerNode.is)!, + value: node.children.find(FloatNode.is) + ?? node.children.find(IntegerNode.is) + ?? node.children.find(LongNode.is)!, suffix: node.children.find(LiteralNode.is), } } @@ -366,16 +384,20 @@ export namespace TypedNumberNode { } } -export interface NumericTypeNode extends TypeBaseNode { +export interface NumericTypeNode + extends TypeBaseNode +{ type: 'mcdoc:type/numeric_type' } export namespace NumericTypeNode { export function destruct( node: NumericTypeNode, - ): { numericKind: LiteralNode; valueRange?: FloatRangeNode | IntRangeNode } { + ): { numericKind: LiteralNode; valueRange?: FloatRangeNode | IntRangeNode | LongRangeNode } { return { numericKind: node.children.find(LiteralNode.is)!, - valueRange: node.children.find(FloatRangeNode.is) || node.children.find(IntRangeNode.is), + valueRange: node.children.find(FloatRangeNode.is) + || node.children.find(IntRangeNode.is) + || node.children.find(LongRangeNode.is), } } export function is(node: AstNode | undefined): node is NumericTypeNode { @@ -406,33 +428,33 @@ export function getRangeDelimiter(kind: RangeKind): string { return `${prefix}..${suffix}` } -function destructRangeNode( +function destructRangeNode( node: N, ): { kind: RangeKind - min?: N extends FloatRangeNode ? FloatNode : IntegerNode - max?: N extends FloatRangeNode ? FloatNode : IntegerNode + min?: N extends IntRangeNode ? IntegerNode : N extends LongRangeNode ? LongNode : FloatNode + max?: N extends IntRangeNode ? IntegerNode : N extends LongRangeNode ? LongNode : FloatNode } { let kind: RangeKind - let min: (FloatNode & IntegerNode) | undefined - let max: (FloatNode & IntegerNode) | undefined + let min: (FloatNode & IntegerNode & LongNode) | undefined + let max: (FloatNode & IntegerNode & LongNode) | undefined if (node.children.length === 1) { // a kind = 0b00 - min = max = node.children[0] as FloatNode & IntegerNode + min = max = node.children[0] as FloatNode & IntegerNode & LongNode } else if (node.children.length === 3) { // a..b kind = getKind(node.children[1] as LiteralNode) - min = node.children[0] as FloatNode & IntegerNode - max = node.children[2] as FloatNode & IntegerNode + min = node.children[0] as FloatNode & IntegerNode & LongNode + max = node.children[2] as FloatNode & IntegerNode & LongNode } else if (LiteralNode.is(node.children[0])) { // ..b kind = getKind(node.children[0]) - max = node.children[1] as FloatNode & IntegerNode + max = node.children[1] as FloatNode & IntegerNode & LongNode } else { // a.. kind = getKind(node.children[1] as LiteralNode) - min = node.children[0] as FloatNode & IntegerNode + min = node.children[0] as FloatNode & IntegerNode & LongNode } return { kind, min, max } @@ -463,19 +485,27 @@ export namespace FloatRangeNode { } } -export interface PrimitiveArrayTypeNode extends TypeBaseNode { +export interface PrimitiveArrayTypeNode + extends TypeBaseNode +{ type: 'mcdoc:type/primitive_array' } export namespace PrimitiveArrayTypeNode { export function destruct( node: PrimitiveArrayTypeNode, - ): { arrayKind: LiteralNode; lengthRange?: IntRangeNode; valueRange?: IntRangeNode } { + ): { + arrayKind: LiteralNode + lengthRange?: IntRangeNode + valueRange?: IntRangeNode | LongRangeNode + } { let lengthRange: IntRangeNode | undefined - let valueRange: IntRangeNode | undefined + let valueRange: IntRangeNode | LongRangeNode | undefined let afterBrackets = false for (const child of node.children) { if (LiteralNode.is(child) && child.value === '[]') { afterBrackets = true + } else if (LongRangeNode.is(child)) { + valueRange = child } else if (IntRangeNode.is(child)) { if (afterBrackets) { lengthRange = child diff --git a/packages/mcdoc/src/parser/index.ts b/packages/mcdoc/src/parser/index.ts index 8475b2f01..e4be0d79a 100644 --- a/packages/mcdoc/src/parser/index.ts +++ b/packages/mcdoc/src/parser/index.ts @@ -5,6 +5,7 @@ import type { FloatNode, InfallibleParser, IntegerNode, + LongNode, Parser, ParserContext, ReadonlySource, @@ -60,6 +61,7 @@ import type { ListTypeNode, LiteralNode, LiteralTypeNode, + LongRangeNode, ModuleNode, NumericTypeNode, PathNode, @@ -580,6 +582,9 @@ export const float: InfallibleParser = core.float({ export const integer: InfallibleParser = core.integer({ pattern: /^(?:0|[-+]?[1-9][0-9]*)$/, }) +export const long: InfallibleParser = core.long({ + pattern: /^(?:0|[-+]?[1-9][0-9]*)$/, +}) export const LiteralIntSuffixes = Object.freeze(['b', 's', 'l'] as const) export type LiteralIntSuffix = (typeof LiteralIntSuffixes)[number] export const LiteralIntCaseInsensitiveSuffixes = Object.freeze( @@ -609,6 +614,12 @@ export type LiteralNumberCaseInsensitiveSuffix = export const typedNumber: InfallibleParser = setType( 'mcdoc:typed_number', select([{ + regex: /^(?:\+|-)?\d+L/i, + parser: sequence([ + long, + optional(keyword(LiteralIntCaseInsensitiveSuffixes, { colorTokenType: 'keyword' })), + ]), + }, { regex: /^(?:\+|-)?\d+(?!\d|[.dfe])/i, parser: sequence([ integer, @@ -819,13 +830,20 @@ export const booleanType: Parser = typeBase( keyword('boolean', { colorTokenType: 'type' }), ) -function range

| InfallibleParser>( +function range< + P extends + | InfallibleParser + | InfallibleParser + | InfallibleParser, +>( type: P extends InfallibleParser ? (V extends IntegerNode ? IntRangeNode + : V extends LongNode ? LongRangeNode : FloatRangeNode)['type'] : never, number: P, ): InfallibleParser< - P extends InfallibleParser ? V extends IntegerNode ? IntRangeNode : FloatRangeNode + P extends InfallibleParser + ? (V extends IntegerNode ? IntRangeNode : V extends LongNode ? LongRangeNode : FloatRangeNode) : never > function range(type: string, number: InfallibleParser): InfallibleParser { @@ -851,15 +869,25 @@ function range(type: string, number: InfallibleParser): InfallibleParser { ) } +function atRange( + parser: InfallibleParser, +) { + return optional((src, ctx) => { + if (!src.trySkip('@')) { + return Failure + } + src.skipWhitespace() + return parser(src, ctx) + }) +} + export const intRange: InfallibleParser = range('mcdoc:int_range', integer) +export const longRange: InfallibleParser = range('mcdoc:long_range', long) +export const floatRange: InfallibleParser = range('mcdoc:float_range', float) -const atIntRange: InfallibleParser = optional((src, ctx) => { - if (!src.trySkip('@')) { - return Failure - } - src.skipWhitespace() - return intRange(src, ctx) -}) +export const atIntRange = atRange(intRange) +export const atLongRange = atRange(longRange) +export const atFloatRange = atRange(floatRange) export const stringType: Parser = typeBase( 'mcdoc:type/string', @@ -881,16 +909,6 @@ export const literalType: Parser = typeBase( ]), ) -export const floatRange: InfallibleParser = range('mcdoc:float_range', float) - -const atFloatRange: InfallibleParser = optional((src, ctx) => { - if (!src.trySkip('@')) { - return Failure - } - src.skipWhitespace() - return floatRange(src, ctx) -}) - export const numericType: Parser = typeBase( 'mcdoc:type/numeric_type', select([{ @@ -899,6 +917,9 @@ export const numericType: Parser = typeBase( [keyword(NumericTypeFloatKinds, { colorTokenType: 'type' }), atFloatRange], true, ), + }, { + predicate: (src) => src.tryPeek('long'), + parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atLongRange], true), }, { parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atIntRange], true), }]), @@ -907,8 +928,10 @@ export const numericType: Parser = typeBase( export const primitiveArrayType: Parser = typeBase( 'mcdoc:type/primitive_array', syntax([ - literal(PrimitiveArrayValueKinds), - atIntRange, + any([ + sequence([literal('long'), atLongRange]), + sequence([literal(PrimitiveArrayValueKinds), atIntRange]), + ]), keyword('[]', { allowedChars: new Set(['[', ']']), colorTokenType: 'type' }), atIntRange, ]), diff --git a/packages/mcdoc/src/runtime/checker/index.ts b/packages/mcdoc/src/runtime/checker/index.ts index 619600f47..c8c8036ee 100644 --- a/packages/mcdoc/src/runtime/checker/index.ts +++ b/packages/mcdoc/src/runtime/checker/index.ts @@ -12,6 +12,7 @@ import type { KeywordType, ListType, LiteralType, + LongType, MappedType, NumericType, ParallelIndices, @@ -44,6 +45,7 @@ export type SimplifiedMcdocTypeNoUnion = | ListType | LiteralType | NumericType + | LongType | PrimitiveArrayType | StringType | SimplifiedStructType @@ -498,7 +500,8 @@ function checkShallowly( if ( typeDef.valueRange && simplifiedInferred.kind === 'literal' - && typeof simplifiedInferred.value.value === 'number' + && simplifiedInferred.value.kind !== 'string' + && simplifiedInferred.value.kind !== 'boolean' && !NumericRange.isInRange(typeDef.valueRange, simplifiedInferred.value.value) ) { errors.push({ diff --git a/packages/mcdoc/src/type/index.ts b/packages/mcdoc/src/type/index.ts index 1f78f4a6b..5354907a4 100644 --- a/packages/mcdoc/src/type/index.ts +++ b/packages/mcdoc/src/type/index.ts @@ -76,9 +76,16 @@ export namespace AttributeValue { } } -export type NumericRange = { kind: RangeKind; min?: number; max?: number } +export interface NumericRange { + kind: RangeKind + min?: T + max?: T +} export namespace NumericRange { - export function isInRange(range: NumericRange, val: number): boolean { + export function isInRange( + range: NumericRange, + val: T, + ): boolean { const { min = -Infinity, max = Infinity } = range if (RangeKind.isLeftExclusive(range.kind) ? val <= min : val < min) { return false @@ -95,14 +102,17 @@ export namespace NumericRange { && a.max === b.max } - export function intersect(a: NumericRange, b: NumericRange): NumericRange { - const min: number | undefined = a.min !== undefined && b.min !== undefined - ? Math.max(a.min, b.min) + export function intersect( + a: NumericRange, + b: NumericRange, + ): NumericRange { + const min: T | undefined = a.min !== undefined && b.min !== undefined + ? (a.min > b.min ? a.min : b.min) : a.min !== undefined ? a.min : b.min - const max: number | undefined = a.max !== undefined && b.max !== undefined - ? Math.min(a.max, b.max) + const max: T | undefined = a.max !== undefined && b.max !== undefined + ? (a.max < b.max ? a.max : b.max) : a.max !== undefined ? a.max : b.max @@ -216,7 +226,7 @@ export interface EnumType extends McdocBaseType { } export interface EnumTypeField extends McdocBaseType { identifier: string - value: string | number + value: string | number | bigint } export interface ReferenceType extends McdocBaseType { @@ -267,10 +277,14 @@ export interface KeywordType extends McdocBaseType { export interface StringType extends McdocBaseType { kind: 'string' - lengthRange?: NumericRange + lengthRange?: NumericRange } -export type LiteralValue = LiteralBooleanValue | LiteralStringValue | LiteralNumericValue +export type LiteralValue = + | LiteralBooleanValue + | LiteralStringValue + | LiteralNumericValue + | LiteralLongNumberValue export interface LiteralBooleanValue { kind: 'boolean' value: boolean @@ -280,17 +294,25 @@ export interface LiteralStringValue { value: string } export interface LiteralNumericValue { - kind: NumericTypeKind + kind: Exclude value: number } +export interface LiteralLongNumberValue { + kind: 'long' + value: bigint +} export interface LiteralType extends McdocBaseType { kind: 'literal' value: LiteralValue } export interface NumericType extends McdocBaseType { - kind: NumericTypeKind - valueRange?: NumericRange + kind: Exclude + valueRange?: NumericRange +} +export interface LongType extends McdocBaseType { + kind: 'long' + valueRange?: NumericRange } export const NumericTypeIntKinds = Object.freeze(['byte', 'short', 'int', 'long'] as const) export type NumericTypeIntKind = (typeof NumericTypeIntKinds)[number] @@ -301,10 +323,16 @@ export const NumericTypeKinds = Object.freeze( ) export type NumericTypeKind = (typeof NumericTypeKinds)[number] -export interface PrimitiveArrayType extends McdocBaseType { - kind: 'byte_array' | 'int_array' | 'long_array' - valueRange?: NumericRange - lengthRange?: NumericRange +export type PrimitiveArrayType = SmallIntArrayType | LongArrayType +export interface SmallIntArrayType extends McdocBaseType { + kind: 'byte_array' | 'int_array' + valueRange?: NumericRange + lengthRange?: NumericRange +} +export interface LongArrayType extends McdocBaseType { + kind: 'long_array' + valueRange?: NumericRange + lengthRange?: NumericRange } export const PrimitiveArrayValueKinds = Object.freeze(['byte', 'int', 'long'] as const) export type PrimitiveArrayValueKind = (typeof PrimitiveArrayValueKinds)[number] @@ -316,7 +344,7 @@ export type PrimitiveArrayKind = (typeof PrimitiveArrayKinds)[number] export interface ListType extends McdocBaseType { kind: 'list' item: McdocType - lengthRange?: NumericRange + lengthRange?: NumericRange } export interface TupleType extends McdocBaseType { @@ -335,6 +363,7 @@ export type McdocType = | ListType | LiteralType | NumericType + | LongType | PrimitiveArrayType | ReferenceType | StringType @@ -489,7 +518,7 @@ export namespace McdocType { } export function toString(type: McdocType | undefined): string { - const rangeToString = (range: NumericRange | undefined): string => { + const rangeToString = (range: NumericRange | undefined): string => { return range ? ` @ ${NumericRange.toString(range)}` : '' } diff --git a/packages/nbt/src/checker/index.ts b/packages/nbt/src/checker/index.ts index c7a2533c1..43dcd1fa3 100644 --- a/packages/nbt/src/checker/index.ts +++ b/packages/nbt/src/checker/index.ts @@ -190,11 +190,7 @@ function inferType(node: NbtNode): Exclude { case 'nbt:float': return { kind: 'literal', value: { kind: 'float', value: node.value } } case 'nbt:long': - return { - kind: 'literal', - // TODO: this should NOT change type from `bigint` to `number` - value: { kind: 'long', value: Number(node.value) }, - } + return { kind: 'literal', value: { kind: 'long', value: node.value } } case 'nbt:int': return { kind: 'literal', value: { kind: 'int', value: node.value } } case 'nbt:short': From 27751ced09723cd98567a4d85884fd50e7cf0860 Mon Sep 17 00:00:00 2001 From: NeunEinser Date: Sun, 7 Jul 2024 13:22:44 +0200 Subject: [PATCH 2/2] Fix minor bugs & add tests --- .../test-out/__fixture__/simple_types.spec.js | 8 +- .../parser/syntax/type/numericType.spec.js | 78 ++++++++++++++++++ .../syntax/type/primitiveArrayType.spec.js | 80 +++++++++++++++++++ packages/mcdoc/src/parser/index.ts | 12 +-- packages/mcdoc/src/runtime/completer/index.ts | 3 +- packages/mcdoc/test/parser/index.spec.ts | 3 + 6 files changed, 174 insertions(+), 10 deletions(-) diff --git a/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js b/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js index 20330916f..cd16b9e89 100644 --- a/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js +++ b/__snapshots__/packages/mcdoc/test-out/__fixture__/simple_types.spec.js @@ -577,7 +577,7 @@ exports['mcdoc __fixture__ simple types 1'] = { "kind": "long_array", "valueRange": { "kind": 0, - "min": 1 + "min": "1" } } }, @@ -1777,15 +1777,15 @@ exports['mcdoc __fixture__ simple types 1'] = { "value": "long" }, { - "type": "mcdoc:int_range", + "type": "mcdoc:long_range", "children": [ { - "type": "integer", + "type": "long", "range": { "start": 380, "end": 381 }, - "value": 1 + "value": "1" }, { "type": "mcdoc:literal", diff --git a/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/numericType.spec.js b/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/numericType.spec.js index 0ddf235f9..adb03561f 100644 --- a/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/numericType.spec.js +++ b/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/numericType.spec.js @@ -213,6 +213,45 @@ exports['mcdoc numericType Parse "int @ 0..1" 1'] = { "errors": [] } +exports['mcdoc numericType Parse "int @ 10000000000000001" 1'] = { + "node": { + "type": "mcdoc:type/numeric_type", + "children": [ + { + "type": "mcdoc:literal", + "range": { + "start": 0, + "end": 3 + }, + "value": "int", + "colorTokenType": "type" + }, + { + "type": "mcdoc:int_range", + "children": [ + { + "type": "integer", + "range": { + "start": 6, + "end": 23 + }, + "value": 10000000000000000 + } + ], + "range": { + "start": 6, + "end": 23 + } + } + ], + "range": { + "start": 0, + "end": 23 + } + }, + "errors": [] +} + exports['mcdoc numericType Parse "int @ 4" 1'] = { "node": { "type": "mcdoc:type/numeric_type", @@ -299,6 +338,45 @@ exports['mcdoc numericType Parse "int @ 4.." 1'] = { "errors": [] } +exports['mcdoc numericType Parse "long @ 10000000000000001" 1'] = { + "node": { + "type": "mcdoc:type/numeric_type", + "children": [ + { + "type": "mcdoc:literal", + "range": { + "start": 0, + "end": 4 + }, + "value": "long", + "colorTokenType": "type" + }, + { + "type": "mcdoc:long_range", + "children": [ + { + "type": "long", + "range": { + "start": 7, + "end": 24 + }, + "value": "10000000000000001" + } + ], + "range": { + "start": 7, + "end": 24 + } + } + ], + "range": { + "start": 0, + "end": 24 + } + }, + "errors": [] +} + exports['mcdoc numericType Parse "other" 1'] = { "node": "FAILURE", "errors": [ diff --git a/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/primitiveArrayType.spec.js b/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/primitiveArrayType.spec.js index 61b0bef16..1b6913cd0 100644 --- a/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/primitiveArrayType.spec.js +++ b/__snapshots__/packages/mcdoc/test-out/parser/syntax/type/primitiveArrayType.spec.js @@ -262,6 +262,86 @@ exports['mcdoc primitiveArrayType Parse "int[] @ 4" 1'] = { "errors": [] } +exports['mcdoc primitiveArrayType Parse "long @ 10000000000000001.. [] @ 0.." 1'] = { + "node": { + "type": "mcdoc:type/primitive_array", + "children": [ + { + "type": "mcdoc:literal", + "range": { + "start": 0, + "end": 4 + }, + "value": "long" + }, + { + "type": "mcdoc:long_range", + "children": [ + { + "type": "long", + "range": { + "start": 7, + "end": 24 + }, + "value": "10000000000000001" + }, + { + "type": "mcdoc:literal", + "range": { + "start": 24, + "end": 26 + }, + "value": ".." + } + ], + "range": { + "start": 7, + "end": 26 + } + }, + { + "type": "mcdoc:literal", + "range": { + "start": 27, + "end": 29 + }, + "value": "[]", + "colorTokenType": "type" + }, + { + "type": "mcdoc:int_range", + "children": [ + { + "type": "integer", + "range": { + "start": 32, + "end": 33 + }, + "value": 0 + }, + { + "type": "mcdoc:literal", + "range": { + "start": 33, + "end": 35 + }, + "value": ".." + } + ], + "range": { + "start": 32, + "end": 35 + } + } + ], + "range": { + "start": 0, + "end": 35 + } + }, + "errors": [] +} + exports['mcdoc primitiveArrayType Parse "other[]" 1'] = { "node": { "type": "mcdoc:type/primitive_array", diff --git a/packages/mcdoc/src/parser/index.ts b/packages/mcdoc/src/parser/index.ts index e4be0d79a..c78e04d0c 100644 --- a/packages/mcdoc/src/parser/index.ts +++ b/packages/mcdoc/src/parser/index.ts @@ -919,7 +919,7 @@ export const numericType: Parser = typeBase( ), }, { predicate: (src) => src.tryPeek('long'), - parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atLongRange], true), + parser: syntax([keyword('long', { colorTokenType: 'type' }), atLongRange], true), }, { parser: syntax([keyword(NumericTypeIntKinds, { colorTokenType: 'type' }), atIntRange], true), }]), @@ -928,10 +928,12 @@ export const numericType: Parser = typeBase( export const primitiveArrayType: Parser = typeBase( 'mcdoc:type/primitive_array', syntax([ - any([ - sequence([literal('long'), atLongRange]), - sequence([literal(PrimitiveArrayValueKinds), atIntRange]), - ]), + select([{ + predicate: (src) => src.tryPeek('long'), + parser: syntax([literal('long'), atLongRange], true), + }, { + parser: syntax([literal(PrimitiveArrayValueKinds), atIntRange], true), + }]), keyword('[]', { allowedChars: new Set(['[', ']']), colorTokenType: 'type' }), atIntRange, ]), diff --git a/packages/mcdoc/src/runtime/completer/index.ts b/packages/mcdoc/src/runtime/completer/index.ts index ac17091c5..2259fae92 100644 --- a/packages/mcdoc/src/runtime/completer/index.ts +++ b/packages/mcdoc/src/runtime/completer/index.ts @@ -2,6 +2,7 @@ import type * as core from '@spyglassmc/core' import { TypeDefSymbolData } from '../../binder/index.js' import type { LiteralType, + LongType, McdocType, NumericType, StringType, @@ -174,7 +175,7 @@ function getStringCompletions( } function getNumericCompletions( - typeDef: core.DeepReadonly, + typeDef: core.DeepReadonly, ctx: McdocCompleterContext, ) { const ans: SimpleCompletionValue[] = [] diff --git a/packages/mcdoc/test/parser/index.spec.ts b/packages/mcdoc/test/parser/index.spec.ts index 400d83ce5..755cf4c25 100644 --- a/packages/mcdoc/test/parser/index.spec.ts +++ b/packages/mcdoc/test/parser/index.spec.ts @@ -176,6 +176,8 @@ const Suites: Record< 'int @ 4..', 'int @ ..4', 'int @ 0..1', + 'int @ 10000000000000001', + 'long @ 10000000000000001', 'double@4.2..5.5', 'double[]', ], @@ -189,6 +191,7 @@ const Suites: Record< 'byte@0..1[]', 'int[] @ 4', 'byte @ 0..1 [] @ 0..', + 'long @ 10000000000000001.. [] @ 0..', ], }, referenceType: { content: ['', '#[uuid] UuidMostLeast', 'MinMaxBounds'] },