diff --git a/src/app/components/generator/McdocRenderer.tsx b/src/app/components/generator/McdocRenderer.tsx index 222f44d4..c382bfa0 100644 --- a/src/app/components/generator/McdocRenderer.tsx +++ b/src/app/components/generator/McdocRenderer.tsx @@ -9,6 +9,7 @@ import { simplify } from '@spyglassmc/mcdoc/lib/runtime/checker/index.js' import { getValues } from '@spyglassmc/mcdoc/lib/runtime/completer/index.js' import { useCallback, useMemo } from 'preact/hooks' import { useLocale } from '../../contexts/Locale.jsx' +import { useFocus } from '../../hooks/useFocus.js' import { generateColor, hexId } from '../../Utils.js' import { Octicon } from '../Octicon.jsx' @@ -22,14 +23,17 @@ interface Props { ctx: McdocContext } export function McdocRoot({ node, makeEdit, ctx } : Props) { + const { locale } = useLocale() const type = node?.typeDef ?? { kind: 'unsafe' } - if (type.kind === 'struct') { + if (type.kind === 'struct' && JsonObjectNode.is(node)) { return } return <>
+ +
@@ -369,6 +373,9 @@ function Body({ type, optional, node, makeEdit, ctx }: BodyProps) { return } if (type.kind === 'struct') { + if (!JsonObjectNode.is(node)) { + return <> + } if (type.fields.length === 0) { return <> } @@ -470,6 +477,7 @@ function StructBody({ type: outerType, node, makeEdit, ctx }: StructBodyProps) { } return
+
@@ -517,6 +525,7 @@ function ListBody({ type: outerType, node, makeEdit, ctx }: ListBodyProps) { } return
+ @@ -564,6 +573,7 @@ function TupleBody({ type, node, makeEdit, ctx }: TupleBodyProps) { } return
+
@@ -573,6 +583,37 @@ function TupleBody({ type, node, makeEdit, ctx }: TupleBodyProps) { } +interface ErrorsProps { + node: JsonNode | undefined + ctx: McdocContext +} +function Errors({ node, ctx }: ErrorsProps) { + const errors = useMemo(() => { + if (node === undefined) { + return [] + } + return ctx.err.errors + .filter(e => core.Range.containsRange(node.range, e.range, true)) + .filter(e => !node.children?.some(c => (c.type === 'item' || c.type === 'pair') && core.Range.containsRange(c.range, e.range, true))) + }, [node, ctx]) + + return <> + {errors.map(e => )} + +} + +interface ErrorIndicatorProps { + error: core.LanguageError +} +function ErrorIndicator({ error }: ErrorIndicatorProps) { + const [active, setActive] = useFocus() + + return
setActive()}> + {Octicon.issue_opened} + {error.message} +
+} + function getDefault(type: McdocType, range: core.Range, ctx: McdocContext): JsonNode { if (type.kind === 'string') { return JsonStringNode.mock(range) diff --git a/src/app/components/generator/Tree.tsx b/src/app/components/generator/Tree.tsx index 3ecc7f61..38aefdc7 100644 --- a/src/app/components/generator/Tree.tsx +++ b/src/app/components/generator/Tree.tsx @@ -11,13 +11,14 @@ type TreePanelProps = { docAndNode: DocAndNode, onError: (message: string) => unknown, } -export function Tree({ docAndNode, onError }: TreePanelProps) { +export function Tree({ docAndNode: original, onError }: TreePanelProps) { const { lang } = useLocale() const { service } = useSpyglass() if (lang === 'none') return <> - const fileChild = useDocAndNode(docAndNode).node.children[0] + const docAndNode = useDocAndNode(original) + const fileChild = docAndNode.node.children[0] if (!JsonFileNode.is(fileChild)) { return <> } @@ -49,7 +50,12 @@ export function Tree({ docAndNode, onError }: TreePanelProps) { if (!service) { return undefined } - return service.getCheckerContext(docAndNode.doc) + const errors = [ + ...docAndNode.node.binderErrors ?? [], + ...docAndNode.node.checkerErrors ?? [], + ...docAndNode.node.linterErrors ?? [], + ] + return service.getCheckerContext(docAndNode.doc, errors) }, [docAndNode, service]) return
diff --git a/src/app/services/Spyglass.ts b/src/app/services/Spyglass.ts index 5fcc512c..677aee17 100644 --- a/src/app/services/Spyglass.ts +++ b/src/app/services/Spyglass.ts @@ -57,8 +57,9 @@ export class SpyglassService { }) } - public getCheckerContext(doc: TextDocument) { + public getCheckerContext(doc: TextDocument, errors: core.LanguageError[]) { const err = new ErrorReporter() + err.errors = errors return core.CheckerContext.create(this.service.project, { doc, err }) } diff --git a/src/locales/en.json b/src/locales/en.json index 54c70095..2efe10f6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -225,6 +225,7 @@ "reset_default": "Reset to default", "resource_location": "Resource location", "restore_backup": "Restore last backup", + "root": "Root", "search": "Search", "settings": "Settings", "settings.fields.description": "Customize advanced field settings", diff --git a/src/styles/nodes.css b/src/styles/nodes.css index e57150d7..c3bbc878 100644 --- a/src/styles/nodes.css +++ b/src/styles/nodes.css @@ -147,6 +147,13 @@ border-color: var(--node-remove) !important; } +.node-warning ~ select:last-child, +.node-warning ~ input:last-child, +.node-warning ~ input[list]:nth-last-child(2), +.node-warning + .fixed-list ~ input { + border-color: var(--node-selected) !important; +} + /** Rounded corners */ .node-header > .node-icon { @@ -296,6 +303,10 @@ button.move:disabled { fill: var(--node-remove); } +.node-icon.node-warning svg { + fill: var(--node-selected); +} + .node-menu { position: absolute; left: 0;