Skip to content

Commit 3959760

Browse files
authored
Refactor Webview Diagnostics Rendering (#31)
1 parent eb7b6da commit 3959760

File tree

3 files changed

+47
-59
lines changed

3 files changed

+47
-59
lines changed
Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { renderHeader, renderLocation, renderSection } from "./utils";
1+
import { renderHeader, renderLocation, renderSection, renderCustomSection } from "./utils";
22
import {
33
ArgumentMismatchError,
44
InvalidRefinementError,
@@ -37,49 +37,35 @@ export function getErrorsView(errors: LJError[], showAll: boolean, currentFile:
3737
`;
3838
}
3939

40+
const errorContentRenderers: Partial<Record<LJError['type'], (error: LJError) => string>> = {
41+
'refinement-error': (e: RefinementError) => /*html*/`
42+
${renderSection('Expected', e.expected.value)}
43+
${renderCustomSection('Found', renderDerivationNode(e, e.found))}
44+
`,
45+
'state-refinement-error': (e: StateRefinementError) => /*html*/`
46+
${renderSection('Expected', e.expected)}
47+
${renderSection('Found', e.found)}
48+
`,
49+
'invalid-refinement-error': (e: InvalidRefinementError) => /*html*/`
50+
${renderSection('Refinement', e.refinement)}
51+
`,
52+
'not-found-error': (e: NotFoundError) => /*html*/`
53+
${renderSection(e.kind, e.name)}
54+
`,
55+
'state-conflict-error': (e: StateConflictError) => /*html*/`
56+
${renderSection('State', e.state)}
57+
`,
58+
'syntax-error': (e: SyntaxError) => /*html*/`
59+
${renderSection('Refinement', e.refinement)}
60+
`,
61+
'argument-mismatch-error': (e: ArgumentMismatchError) => /*html*/`
62+
${renderSection('Refinement', e.refinement)}
63+
`
64+
};
65+
4066
export function renderError(error: LJError): string {
4167
const header = renderHeader(error);
68+
const content = errorContentRenderers[error.type]?.(error) ?? '';
4269
const location = renderLocation(error);
43-
switch (error.type) {
44-
case 'refinement-error': {
45-
const e = error as RefinementError;
46-
return /*html*/`
47-
${header}
48-
${renderSection('Expected', `<pre>${e.expected.value}</pre>`)}
49-
${renderSection('Found', renderDerivationNode(e, e.found))}
50-
${location}
51-
`;
52-
}
53-
case 'state-refinement-error': {
54-
const e = error as StateRefinementError;
55-
return `${header}${renderSection('Expected', `<pre>${e.expected}</pre>`)}${renderSection('Found', `<pre>${e.found}</pre>`)}${location}`;
56-
}
57-
case 'invalid-refinement-error': {
58-
const e = error as InvalidRefinementError;
59-
return `${header}${renderSection('Refinement', `<pre>"${e.refinement}"</pre>`)}${location}`;
60-
}
61-
case 'not-found-error': {
62-
const e = error as NotFoundError;
63-
const content = `<p>${e.kind} <b>${e.name}</b> not found</p>`;
64-
return `<h3>${error.title}</h3><div class="diagnostic-header">${content}</div>${location}`;
65-
}
66-
case 'state-conflict-error': {
67-
const e = error as StateConflictError;
68-
return `${header}${renderSection('State', `<pre>${e.state}</pre>`)}${location}`;
69-
}
70-
case 'syntax-error': {
71-
const e = error as SyntaxError;
72-
return `${header}${renderSection('Refinement', `<pre>"${e.refinement}"</pre>`)}${location}`;
73-
}
74-
case 'argument-mismatch-error': {
75-
const e = error as ArgumentMismatchError;
76-
return `${header}${renderSection('Refinement', `<pre>"${e.refinement}"</pre>`)}${location}`;
77-
}
78-
default:
79-
return `${header}${location}`;
80-
}
81-
}
82-
function renderToggleButton(showAll: boolean) {
83-
throw new Error("Function not implemented.");
70+
return /*html*/`${header}${content}${location}`;
8471
}
85-

client/src/webview/renderers/diagnostics/utils.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { LJDiagnostic } from "../../../types";
22

3-
export const renderSection = (title: string, body: string): string =>
3+
export const renderCustomSection = (title: string, body: string): string =>
44
`<div class="section"><strong>${title}:</strong><div>${body}</div></div>`;
55

6+
export const renderSection = (title: string, body: string): string =>
7+
renderCustomSection(title, `<pre>${body}</pre>`);
8+
69
export const renderHeader = (diagnostic: LJDiagnostic): string => {
710
return `<h3>${diagnostic.title}</h3><div class="diagnostic-header"><p>${diagnostic.message}</p></div>`;
811
};
@@ -13,5 +16,5 @@ export const renderLocation = (diagnostic: LJDiagnostic): string => {
1316
const column = diagnostic.position?.colStart ?? 0;
1417
const simpleFile = diagnostic.file.split('/').pop() || diagnostic.file;
1518
const link = `<a href="#" class="link location-link" data-file="${diagnostic.file}" data-line="${line}" data-column="${column}">${simpleFile}:${line}</a>`;
16-
return renderSection("Location", `<pre>${link}</pre>`);
19+
return renderCustomSection("Location", `<pre>${link}</pre>`);
1720
};
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ExternalClassNotFoundWarning, ExternalMethodNotFoundWarning, LJWarning } from "../../../types";
2-
import { renderHeader, renderLocation, renderSection } from "./utils";
2+
import { renderHeader, renderLocation, renderCustomSection, renderSection } from "./utils";
33

44
export function getWarningsView(warnings: LJWarning[], showAllDiagnostics: boolean, currentFile: string | undefined): string {
55
return /*html*/`
@@ -17,20 +17,19 @@ export function getWarningsView(warnings: LJWarning[], showAllDiagnostics: boole
1717
`;
1818
}
1919

20+
const warningContentRenderers: Partial<Record<LJWarning['type'], (warning: LJWarning) => string>> = {
21+
'external-class-not-found-warning': (w: ExternalClassNotFoundWarning) => /*html*/`
22+
${renderSection('Class Name', w.className)}
23+
`,
24+
'external-method-not-found-warning': (w: ExternalMethodNotFoundWarning) => /*html*/`
25+
${renderSection('Method', w.methodName)}
26+
${w.overloads.length > 0 ? renderSection('Overloads', w.overloads.join('\n')) : ''}
27+
`
28+
};
29+
2030
export function renderWarning(warning: LJWarning): string {
2131
const header = renderHeader(warning);
32+
const content = warningContentRenderers[warning.type]?.(warning) ?? '';
2233
const location = renderLocation(warning);
23-
switch (warning.type) {
24-
case 'external-class-not-found-warning': {
25-
const e = warning as ExternalClassNotFoundWarning;
26-
return `${header}${renderSection('Class Name', `<pre>${e.className}</pre>`)}${location}`;
27-
}
28-
case 'external-method-not-found-warning': {
29-
const e = warning as ExternalMethodNotFoundWarning;
30-
return `${header}${renderSection('Method', `<pre>${e.methodName}</pre>`)}${e.overloads.length > 0 ? renderSection("Overloads", `<pre>${e.overloads.join("\n")}</pre>`) : ""}${location}`;
31-
}
32-
case 'custom-warning': {
33-
return `${header}${location}`;
34-
}
35-
}
34+
return /*html*/`${header}${content}${location}`;
3635
}

0 commit comments

Comments
 (0)