-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patherrors.ts
More file actions
80 lines (75 loc) · 3.19 KB
/
errors.ts
File metadata and controls
80 lines (75 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { renderDiagnosticHeader, renderLocation, renderSection, renderCustomSection, renderTranslationTable, } from "../sections";
import { renderDerivationNode } from "./derivation-nodes";
import type {
ArgumentMismatchError,
InvalidRefinementError,
LJError,
NotFoundError,
RefinementError,
StateConflictError,
StateRefinementError,
SyntaxError,
TranslationTable,
} from "../../../types/diagnostics";
export function renderErrors(errors: LJError[], expandedErrors: Set<number>): string {
return /*html*/`
<ul>
${errors.map(error => {
const errorIndex = errors.indexOf(error);
const isExpanded = expandedErrors.has(errorIndex);
return /*html*/`
<li class="diagnostic-item error-item">
${renderError(error, errorIndex, isExpanded)}
</li>
`;
}).join("")}
</ul>
`;
}
const errorContentRenderers: Partial<Record<LJError['type'], (error: LJError) => string>> = {
'refinement-error': (e: RefinementError) => /*html*/`
${e.customMessage ? renderSection('Message', e.customMessage) : ''}
${renderCustomSection('Expected', renderDerivationNode(e, e.expected))}
${renderCustomSection('Found', renderDerivationNode(e, e.found))}
${e.counterexample ? renderSection('Counterexample', e.counterexample) : ''}
`,
'state-refinement-error': (e: StateRefinementError) => /*html*/`
${e.customMessage ? renderSection('Message', e.customMessage) : ''}
${renderSection('Expected', e.expected)}
${renderSection('Found', e.found)}
`,
'invalid-refinement-error': (e: InvalidRefinementError) => /*html*/`
${renderSection('Refinement', e.refinement)}
`,
'not-found-error': (e: NotFoundError) => /*html*/`
${renderSection(e.kind, e.name)}
`,
'state-conflict-error': (e: StateConflictError) => /*html*/`
${renderSection('State', e.state)}
`,
'syntax-error': (e: SyntaxError) => /*html*/`
${renderSection('Refinement', e.refinement)}
`,
'argument-mismatch-error': (e: ArgumentMismatchError) => /*html*/`
${renderSection('Refinement', e.refinement)}
`
};
export function renderError(error: LJError, errorIndex: number, isExpanded: boolean): string {
const header = renderDiagnosticHeader(error);
const content = errorContentRenderers[error.type]?.(error) ?? '';
const location = renderLocation(error);
const extra = renderExtra(error, errorIndex, isExpanded);
return /*html*/`${header}${content}${location}${extra}`;
}
function renderExtra(error: LJError, errorIndex: number, isExpanded: boolean): string {
const button = /*html*/`
<button class="show-more-button" data-error-index="${errorIndex}" title="Toggle show extra information about the diagnostic">
${isExpanded ? '↑' : '↓'}
</button>
`;
let extra = "";
if (error.hasOwnProperty('translationTable')) {
extra += renderTranslationTable((error as any).translationTable as TranslationTable);
}
return extra ? isExpanded ? /*html*/`${button}<div class="extra-content">${extra}</div>` : button : "";
}