Add visual indicator to lexical errors in code snippets
This commit is contained in:
parent
76aad9cd8a
commit
2fb095896b
@ -1,10 +1,17 @@
|
||||
---
|
||||
import { native_highlighter } from "../lexer/highlighter";
|
||||
import CodeError from "./docs/CodeError.astro";
|
||||
|
||||
const { thpcode } = Astro.props;
|
||||
|
||||
const native_html = await native_highlighter(thpcode);
|
||||
const [native_html, error_message] = await native_highlighter(thpcode);
|
||||
---
|
||||
|
||||
<pre
|
||||
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp</span></pre>
|
||||
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp
|
||||
</span></pre>
|
||||
{
|
||||
error_message !== null && (
|
||||
<CodeError error_type="Lexical">{error_message}</CodeError>
|
||||
)
|
||||
}
|
||||
|
8
src/components/docs/CodeError.astro
Normal file
8
src/components/docs/CodeError.astro
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
const { error_type = "Unknown" } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="px-4 py-2 rounded bg-red-200 dark:bg-red-950">
|
||||
<span class="inline-block font-bold">{error_type} error:</span>
|
||||
<slot />
|
||||
</div>
|
@ -45,13 +45,13 @@ export interface LexError {
|
||||
}
|
||||
|
||||
|
||||
export async function native_highlighter(code: string): Promise<string> {
|
||||
export async function native_highlighter(code: string): Promise<[string, string | null]> {
|
||||
let formatted_code = leftTrimDedent(code).join("\n");
|
||||
|
||||
const result = await native_lex(formatted_code);
|
||||
|
||||
if (result.Err) {
|
||||
throw new Error(JSON.stringify(result.Err.Lex) + "\n" + code);
|
||||
return lex_error_highlighter(formatted_code, result.Err!.Lex);
|
||||
}
|
||||
|
||||
const tokens = result.Ok!;
|
||||
@ -82,7 +82,27 @@ export async function native_highlighter(code: string): Promise<string> {
|
||||
current_pos = token_end;
|
||||
}
|
||||
|
||||
return output;
|
||||
return [output, null];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Highlights code that has a lexic error
|
||||
*/
|
||||
function lex_error_highlighter(code: string, error: LexError): [string, string] {
|
||||
// Create a single error token
|
||||
|
||||
const err_pos = error.position;
|
||||
const before_err = code.substring(0, err_pos);
|
||||
const err_str = code[err_pos];
|
||||
const after_err = code.substring(err_pos + 1);
|
||||
|
||||
const token = `<span class="token underline decoration-wavy decoration-red-500">${err_str}</span>`;
|
||||
|
||||
const all = `${before_err}${token}${after_err}`;
|
||||
|
||||
// TODO: Transform absolute posijion (error.position) into line:column
|
||||
return [all, error.reason + " at position " + error.position]
|
||||
}
|
||||
|
||||
function translate_token_type(tt: TokenType, value: string): string {
|
||||
|
@ -5,3 +5,11 @@ title: Readonly
|
||||
import Code from "../../../components/Code.astro"
|
||||
|
||||
# Readonly
|
||||
|
||||
<Code thpcode={`
|
||||
class Caño
|
||||
{
|
||||
}
|
||||
`} />
|
||||
|
||||
|
||||
|
@ -57,11 +57,11 @@ fun UserDetail(User user) -> HTML
|
||||
{
|
||||
<div>
|
||||
@match user.type
|
||||
case ::Admin
|
||||
@case ::Admin
|
||||
{
|
||||
<button>Delete resource</button>
|
||||
}
|
||||
case ::User
|
||||
@case ::User
|
||||
{
|
||||
<button disable>Not allowed</button>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user