134 lines
4.1 KiB
TypeScript
134 lines
4.1 KiB
TypeScript
import { For, Match, Show, Switch } from "solid-js";
|
|
import { ParseError } from "src/lang/parser/parser";
|
|
import { SourceRegion } from "source-region";
|
|
import { ShowParseError } from 'src/ui/Component/ParseError';
|
|
import { Program } from "src/lang/program";
|
|
|
|
export type DigithError = {
|
|
payload: DigithError.Payload,
|
|
ids: DigithError.Id[],
|
|
tags: DigithError.Tag[],
|
|
config: DigithError.Config,
|
|
}
|
|
|
|
export namespace DigithError {
|
|
export type Payload =
|
|
| { tag: "Parse", err: ParseError, src: SourceRegion }
|
|
| { tag: "Program", err: Program.Error };
|
|
|
|
export type Id = string;
|
|
export type Tag = string;
|
|
|
|
export type Config = {
|
|
title?: string,
|
|
display?: "box" | "flat",
|
|
}
|
|
|
|
function findById(errors: DigithError[], id: Id): DigithError | undefined {
|
|
return errors.find((e) => e.ids.includes(id));
|
|
}
|
|
|
|
function allWithTag(errors: DigithError[], tag: Tag): DigithError[] {
|
|
return errors.filter((e) => e.tags.includes(tag));
|
|
}
|
|
|
|
export function All(props: { errors: DigithError[] }) {
|
|
return (
|
|
<div class="digith-errors-container">
|
|
<For each={props.errors}>
|
|
{(error) => <Single error={error} />}
|
|
</For>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ById(props: { errors: DigithError[], id: Id }) {
|
|
const error = () => findById(props.errors, props.id);
|
|
return (
|
|
<Show when={error()}>
|
|
{(e) => <Single error={e()} />}
|
|
</Show>
|
|
);
|
|
}
|
|
|
|
export function ByTag(props: { errors: DigithError[], tag: Tag }) {
|
|
const matched = () => allWithTag(props.errors, props.tag);
|
|
return (
|
|
<Show when={matched().length > 0}>
|
|
<All errors={matched()} />
|
|
</Show>
|
|
);
|
|
}
|
|
|
|
function Single(props: { error: DigithError }) {
|
|
const display = () => props.error.config.display ?? "box";
|
|
return (
|
|
<div style={{ "margin-bottom": display() === "box" ? "1rem" : "0.5rem" }} >
|
|
<Switch>
|
|
<Match when={display() === "box"}>
|
|
<article style={{ border: "1px solid var(--pico-del-color)", padding: "0.5rem 1rem", margin: 0 }}>
|
|
<Show when={props.error.config.title}>
|
|
<header style={{ "margin-bottom": "0.5rem", color: "var(--pico-del-color)", "font-weight": "bold" }}>
|
|
{props.error.config.title}
|
|
</header>
|
|
</Show>
|
|
<PayloadView payload={props.error.payload} />
|
|
</article>
|
|
</Match>
|
|
|
|
<Match when={display() === "flat"}>
|
|
<div style={{ color: "var(--pico-del-color)" }}>
|
|
<Show when={props.error.config.title}>
|
|
<small style={{ "font-weight": "bold", display: "block" }}>{props.error.config.title}:</small>
|
|
</Show>
|
|
<PayloadView payload={props.error.payload} />
|
|
</div>
|
|
</Match>
|
|
</Switch>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PayloadView(props: { payload: Payload }) {
|
|
return (
|
|
<Switch>
|
|
<Match
|
|
when={props.payload.tag === "Parse" ? (props.payload as Extract<Payload, { tag: "Parse" }>) : undefined}
|
|
>
|
|
{(err) => <ShowParseError text={err().src} err={err().err} />}
|
|
</Match>
|
|
|
|
<Match
|
|
when={props.payload.tag === "Program" ? (props.payload as Extract<Payload, { tag: "Program" }>) : undefined}
|
|
>
|
|
{(err) => <ProgramErrorDisplay error={err().err} />}
|
|
</Match>
|
|
</Switch>
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
export function ProgramErrorDisplay(props: { error: Program.Error }) {
|
|
const message = () => {
|
|
switch (props.error.tag) {
|
|
case "DuplicateFunctionName":
|
|
return `A function named '${props.error.name}' already exists.`;
|
|
case "PrimitiveFunctionAlreadyExists":
|
|
return `Cannot overwrite the primitive function '${props.error.name}'.`;
|
|
// TODO: handle other cases
|
|
default:
|
|
return `Runtime Error: ${props.error.tag}`;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<article style={{ border: "1px solid var(--pico-del-color)", padding: "0.5rem 1rem" }}>
|
|
<small style={{ color: "var(--pico-del-color)", "font-weight": "bold" }}>
|
|
Registration Failed
|
|
</small>
|
|
<p style={{ margin: 0 }}>{message()}</p>
|
|
</article>
|
|
);
|
|
}
|
|
|