diff --git a/src/app/components/generator/McdocHelpers.ts b/src/app/components/generator/McdocHelpers.ts index 320315fe..029c5ec0 100644 --- a/src/app/components/generator/McdocHelpers.ts +++ b/src/app/components/generator/McdocHelpers.ts @@ -2,9 +2,45 @@ import * as core from '@spyglassmc/core' import type { JsonNode } from '@spyglassmc/json' import { JsonArrayNode, JsonObjectNode, JsonStringNode } from '@spyglassmc/json' import { JsonStringOptions } from '@spyglassmc/json/lib/parser/string.js' -import type { Attributes, ListType, McdocType, NumericRange, NumericType, PrimitiveArrayType, TupleType, UnionType } from '@spyglassmc/mcdoc' +import type { Attributes, AttributeValue, ListType, McdocType, NumericType, PrimitiveArrayType, TupleType, UnionType } from '@spyglassmc/mcdoc' +import { NumericRange, RangeKind } from '@spyglassmc/mcdoc' import type { McdocCheckerContext, SimplifiedMcdocType, SimplifiedMcdocTypeNoUnion, SimplifyValueNode } from '@spyglassmc/mcdoc/lib/runtime/checker/index.js' import { simplify } from '@spyglassmc/mcdoc/lib/runtime/checker/index.js' +import config from '../../Config.js' +import { randomInt, randomSeed } from '../../Utils.js' + +export function getRootType(id: string): McdocType { + if (id === 'pack_mcmeta') { + return { kind: 'reference', path: '::java::pack::Pack' } + } + if (id === 'text_component' ) { + return { kind: 'reference', path: '::java::server::util::text::Text' } + } + if (id.startsWith('tag/')) { + const attribute: AttributeValue = { + kind: 'tree', + values: { + registry: { kind: 'literal', value: { kind: 'string', value: id.slice(4) } }, + tags: { kind: 'literal', value: { kind: 'string', value: 'allowed' } }, + }, + } + return { + kind: 'concrete', + child: { kind: 'reference', path: '::java::data::tag::Tag' }, + typeArgs: [{ kind: 'string', attributes: [{ name: 'id', value: attribute }] }], + } + } + return { + kind: 'dispatcher', + registry: 'minecraft:resource', + parallelIndices: [{ kind: 'static', value: id }], + } +} + +export function getRootDefault(id: string, ctx: core.CheckerContext) { + const type = simplifyType(getRootType(id), ctx) + return getDefault(type, core.Range.create(0), ctx) +} export function getDefault(type: SimplifiedMcdocType, range: core.Range, ctx: core.CheckerContext): JsonNode { if (type.kind === 'string') { @@ -14,7 +50,41 @@ export function getDefault(type: SimplifiedMcdocType, range: core.Range, ctx: co return { type: 'json:boolean', range, value: false } } if (isNumericType(type)) { - const value: core.LongNode = { type: 'long', range, value: BigInt(0) } + let num: number | bigint = 0 + if (type.valueRange) { + // Best effort. First try 0 or 1, else set to the lowest bound + if (NumericRange.isInRange(type.valueRange, 0)) { + num = 0 + } else if (NumericRange.isInRange(type.valueRange, 1)) { + num = 1 + } else if (type.valueRange.min && type.valueRange.min > 0) { + num = type.valueRange.min + if (RangeKind.isLeftExclusive(type.valueRange.kind)) { + // Assume that left exclusive ranges are longer than 1 + num += 1 + } + } + } + if (type.attributes?.some(a => a.name === 'pack_format')) { + // Set to the latest pack format + const release = ctx.project['loadedVersion'] + console + const version = config.versions.find(v => v.ref === release || v.id === release) + if (version) { + num = version.pack_format + } + } + if (type.attributes?.some(a => a.name === 'random')) { + // Generate random number + if (type.kind === 'long') { + num = randomSeed() + } else { + num = randomInt() + } + } + const value: core.LongNode | core.FloatNode = typeof num !== 'number' || Number.isInteger(num) + ? { type: 'long', range, value: typeof num === 'number' ? BigInt(num) : num } + : { type: 'float', range, value: num } return { type: 'json:number', range, value, children: [value] } } if (type.kind === 'struct' || type.kind === 'any' || type.kind === 'unsafe') { diff --git a/src/app/components/generator/SchemaGenerator.tsx b/src/app/components/generator/SchemaGenerator.tsx index 5deecab5..adb0cb1d 100644 --- a/src/app/components/generator/SchemaGenerator.tsx +++ b/src/app/components/generator/SchemaGenerator.tsx @@ -11,6 +11,7 @@ import { checkVersion, fetchDependencyMcdoc, fetchPreset, fetchRegistries, getSn import { Store } from '../../Store.js' import { cleanUrl, genPath, safeJsonParse } from '../../Utils.js' import { Ad, Btn, BtnMenu, ErrorPanel, FileCreation, FileRenaming, Footer, HasPreview, Octicon, PreviewPanel, ProjectCreation, ProjectDeletion, ProjectPanel, SearchList, SourcePanel, TextInput, Tree, VersionSwitcher } from '../index.js' +import { getRootDefault } from './McdocHelpers.js' export const SHARE_KEY = 'share' @@ -95,8 +96,8 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) { } else { text = await service.readFile(uri) if (text === undefined) { - // TODO: set to generator's default - text = '{}' + const node = getRootDefault(gen.id, service.getCheckerContext()) + text = service.formatNode(node, uri) await service.writeFile(uri, text) } } @@ -122,9 +123,14 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) { setError(null) }, [updateFile]) - const reset = () => { + const reset = async () => { + if (!service || !uri) { + return + } Analytics.resetGenerator(gen.id, 1, 'menu') - // TODO + const node = getRootDefault(gen.id, service.getCheckerContext()) + const newText = service.formatNode(node, uri) + await service.writeFile(uri, newText) } const undo = async (e: MouseEvent) => { e.stopPropagation() diff --git a/src/app/components/generator/Tree.tsx b/src/app/components/generator/Tree.tsx index 28390502..0f3bf77a 100644 --- a/src/app/components/generator/Tree.tsx +++ b/src/app/components/generator/Tree.tsx @@ -1,11 +1,10 @@ import type { DocAndNode, Range } from '@spyglassmc/core' import type { JsonNode } from '@spyglassmc/json' import { JsonFileNode } from '@spyglassmc/json' -import type { AttributeValue, McdocType } from '@spyglassmc/mcdoc' import { useCallback, useErrorBoundary, useMemo } from 'preact/hooks' import { disectFilePath, useLocale, useVersion } from '../../contexts/index.js' import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx' -import { simplifyType } from './McdocHelpers.js' +import { getRootType, simplifyType } from './McdocHelpers.js' import type { McdocContext } from './McdocRenderer.jsx' import { McdocRoot } from './McdocRenderer.jsx' @@ -73,7 +72,8 @@ export function Tree({ docAndNode: original, onError }: TreePanelProps) { if (!ctx || !resourceType) { return undefined } - return simplifyType(getRootType(resourceType), ctx) + const rootType = getRootType(resourceType) + return simplifyType(rootType, ctx) }, [resourceType, ctx]) return