forked from KittyCAD/modeling-app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.ts
134 lines (122 loc) · 4.04 KB
/
errors.ts
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
import { Diagnostic as CodeMirrorDiagnostic } from '@codemirror/lint'
import { posToOffset } from '@kittycad/codemirror-lsp-client'
import { Diagnostic as LspDiagnostic } from 'vscode-languageserver-protocol'
import { Text } from '@codemirror/state'
type ExtractKind<T> = T extends { kind: infer K } ? K : never
export class KCLError extends Error {
kind: ExtractKind<RustKclError> | 'name'
sourceRanges: [number, number][]
msg: string
constructor(
kind: ExtractKind<RustKclError> | 'name',
msg: string,
sourceRanges: [number, number][]
) {
super()
this.kind = kind
this.msg = msg
this.sourceRanges = sourceRanges
Object.setPrototypeOf(this, KCLError.prototype)
}
}
export class KCLLexicalError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('lexical', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
}
}
export class KCLInternalError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('internal', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
}
}
export class KCLSyntaxError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('syntax', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
}
}
export class KCLSemanticError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('semantic', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSemanticError.prototype)
}
}
export class KCLTypeError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('type', msg, sourceRanges)
Object.setPrototypeOf(this, KCLTypeError.prototype)
}
}
export class KCLUnimplementedError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('unimplemented', msg, sourceRanges)
Object.setPrototypeOf(this, KCLUnimplementedError.prototype)
}
}
export class KCLUnexpectedError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('unexpected', msg, sourceRanges)
Object.setPrototypeOf(this, KCLUnexpectedError.prototype)
}
}
export class KCLValueAlreadyDefined extends KCLError {
constructor(key: string, sourceRanges: [number, number][]) {
super('name', `Key ${key} was already defined elsewhere`, sourceRanges)
Object.setPrototypeOf(this, KCLValueAlreadyDefined.prototype)
}
}
export class KCLUndefinedValueError extends KCLError {
constructor(key: string, sourceRanges: [number, number][]) {
super('name', `Key ${key} has not been defined`, sourceRanges)
Object.setPrototypeOf(this, KCLUndefinedValueError.prototype)
}
}
/**
* Maps the lsp diagnostic to an array of KclErrors.
* Currently the diagnostics are all errors, but in the future they could include lints.
* */
export function lspDiagnosticsToKclErrors(
doc: Text,
diagnostics: LspDiagnostic[]
): KCLError[] {
return diagnostics
.flatMap(
({ range, message }) =>
new KCLError('unexpected', message, [
[posToOffset(doc, range.start)!, posToOffset(doc, range.end)!],
])
)
.filter(({ sourceRanges }) => {
const [from, to] = sourceRanges[0]
return (
from !== null && to !== null && from !== undefined && to !== undefined
)
})
.sort((a, b) => {
const c = a.sourceRanges[0][0]
const d = b.sourceRanges[0][0]
switch (true) {
case c < d:
return -1
case c > d:
return 1
}
return 0
})
}
/**
* Maps the KCL errors to an array of CodeMirror diagnostics.
* Currently the diagnostics are all errors, but in the future they could include lints.
* */
export function kclErrorsToDiagnostics(
errors: KCLError[]
): CodeMirrorDiagnostic[] {
return errors?.flatMap((err) => {
return err.sourceRanges.map(([from, to]) => {
return { from, to, message: err.msg, severity: 'error' }
})
})
}