Implement set generator default

This commit is contained in:
Misode
2024-11-01 18:33:25 +01:00
parent 7b576da9d2
commit 4d85a9f491
4 changed files with 101 additions and 40 deletions

View File

@@ -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') {

View File

@@ -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()

View File

@@ -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 <div class="tree node-root" data-cy="tree" data-category={getCategory(resourceType)}>
@@ -81,34 +81,6 @@ export function Tree({ docAndNode: original, onError }: TreePanelProps) {
</div>
}
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 }],
}
}
function getCategory(type: string | undefined) {
switch (type) {
case 'item_modifier': return 'function'