From 65a394c3ed25380bb5ca6aeda7e75403c067b14d Mon Sep 17 00:00:00 2001 From: Misode Date: Tue, 29 Oct 2024 03:31:16 +0100 Subject: [PATCH] Improve union member matching --- .../components/generator/McdocRenderer.tsx | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/app/components/generator/McdocRenderer.tsx b/src/app/components/generator/McdocRenderer.tsx index 78a2c8e2..241ed984 100644 --- a/src/app/components/generator/McdocRenderer.tsx +++ b/src/app/components/generator/McdocRenderer.tsx @@ -318,10 +318,10 @@ function UnionHead({ type, optional, node, makeEdit, ctx }: Props -1 ? memberIndex : SPECIAL_UNSET} onInput={(e) => onSelect((e.target as HTMLSelectElement).value)}> {(selectedType === undefined || optional) && } {type.members.map((member, index) => - + )} - {selectedType && } + {selectedType && selectedType.kind !== 'literal' && } } @@ -1007,6 +1007,24 @@ function getDefault(type: SimplifiedMcdocType, range: core.Range, ctx: McdocCont return { type: 'json:null', range } } +function formatUnionMember(type: SimplifiedMcdocTypeNoUnion, others: SimplifiedMcdocTypeNoUnion[]): string { + if (type.kind === 'literal') { + return formatIdentifier(type.value.value.toString()) + } + if (!others.some(o => o.kind === type.kind)) { + // No other member is of this kind + return formatIdentifier(type.kind) + } + if (type.kind === 'struct') { + // Show the first literal key + const firstKey = type.fields.find(f => f.key.kind === 'literal')?.key + if (firstKey) { + return formatUnionMember(firstKey, []) + } + } + return formatIdentifier(type.kind) +} + function formatIdentifier(id: string): string { if (id.startsWith('!')) { return '! ' + formatIdentifier(id.substring(1)) @@ -1172,11 +1190,23 @@ function getItemType(type: ListType | PrimitiveArrayType): McdocType { : { kind: 'any' } } -function quickEqualTypes(a: SimplifiedMcdocType, b: SimplifiedMcdocType) { +function quickEqualTypes(a: SimplifiedMcdocTypeNoUnion, b: SimplifiedMcdocTypeNoUnion): boolean { + if (a === b) { + return true + } if (a.kind !== b.kind) { return false } - // TODO: improve this + if (a.kind === 'literal' && b.kind === 'literal') { + return a.value.kind === b.value.kind && a.value.value === b.value.value + } + if (a.kind === 'struct' && b.kind === 'struct') { + // Compare the first key of both structs + const keyA = a.fields[0]?.key + const keyB = b.fields[0]?.key + return (!keyA && !keyB) || (keyA && keyB && quickEqualTypes(keyA, keyB)) + } + // Types are of the same kind return true }