test parse errors are thrown (#294)

This commit is contained in:
Kurt Hutten
2023-08-22 13:28:02 +10:00
committed by GitHub
parent 75bb91c7e1
commit 148e125dd7
5 changed files with 49 additions and 21 deletions

View File

@ -1,4 +1,5 @@
import { parser_wasm } from './abstractSyntaxTree'
import { KCLUnexpectedError } from './errors'
import { initPromise } from './rust'
beforeAll(() => initPromise)
@ -1706,3 +1707,19 @@ describe('should recognise callExpresions in binaryExpressions', () => {
])
})
})
describe('parsing errors', () => {
it('should return an error when there is a unexpected closed curly brace', async () => {
const code = `const myVar = startSketchAt([}], %)`
let _theError
try {
const result = expect(parser_wasm(code))
console.log('result', result)
} catch (e) {
_theError = e
}
const theError = _theError as any
expect(theError).toEqual(new KCLUnexpectedError('Brace', [[29, 30]]))
})
})

View File

@ -3,21 +3,23 @@ import { parse_js } from '../wasm-lib/pkg/wasm_lib'
import { initPromise } from './rust'
import { Token } from './tokeniser'
import { KCLError } from './errors'
import { KclError as RustKclError } from '../wasm-lib/bindings/KclError'
const rangeTypeFix = (ranges: number[][]): [number, number][] =>
ranges.map(([start, end]) => [start, end])
export const parser_wasm = (code: string): Program => {
try {
const program: Program = parse_js(code)
return program
} catch (e: any) {
const parsed: {
kind: string
msg: string
sourceRanges: [number, number][]
} = JSON.parse(e.toString())
const kclError: KCLError = new KCLError(
const parsed: RustKclError = JSON.parse(e.toString())
const kclError = new KCLError(
parsed.kind,
parsed.msg,
parsed.sourceRanges
parsed.kind === 'invalid_expression' ? parsed.kind : parsed.msg,
parsed.kind === 'invalid_expression'
? [[parsed.start, parsed.end]]
: rangeTypeFix(parsed.sourceRanges)
)
console.log(kclError)
@ -31,15 +33,13 @@ export async function asyncParser(code: string): Promise<Program> {
const program: Program = parse_js(code)
return program
} catch (e: any) {
const parsed: {
kind: string
msg: string
sourceRanges: [number, number][]
} = JSON.parse(e.toString())
const kclError: KCLError = new KCLError(
const parsed: RustKclError = JSON.parse(e.toString())
const kclError = new KCLError(
parsed.kind,
parsed.msg,
parsed.sourceRanges
parsed.kind === 'invalid_expression' ? parsed.kind : parsed.msg,
parsed.kind === 'invalid_expression'
? [[parsed.start, parsed.end]]
: rangeTypeFix(parsed.sourceRanges)
)
console.log(kclError)

View File

@ -1,11 +1,13 @@
import { Diagnostic } from '@codemirror/lint'
import { KclError as RustKclError } from '../wasm-lib/bindings/KclError'
type ExtractKind<T> = T extends { kind: infer K } ? K : never
export class KCLError {
kind: string | undefined
kind: ExtractKind<RustKclError> | 'name'
sourceRanges: [number, number][]
msg: string
constructor(
kind: string | undefined,
kind: ExtractKind<RustKclError> | 'name',
msg: string,
sourceRanges: [number, number][]
) {
@ -39,11 +41,18 @@ export class KCLTypeError extends KCLError {
export class KCLUnimplementedError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('unimplemented feature', msg, sourceRanges)
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)

View File

@ -13,6 +13,8 @@ pub enum KclError {
Type(KclErrorDetails),
#[error("unimplemented: {0:?}")]
Unimplemented(KclErrorDetails),
#[error("unexpected: {0:?}")]
Unexpected(KclErrorDetails),
#[error("value already defined: {0:?}")]
ValueAlreadyDefined(KclErrorDetails),
#[error("undefined value: {0:?}")]

View File

@ -614,9 +614,9 @@ fn make_value(tokens: &[Token], index: usize) -> Result<ValueReturn, KclError> {
});
}
Err(KclError::Unimplemented(KclErrorDetails {
Err(KclError::Unexpected(KclErrorDetails {
source_ranges: vec![[current_token.start as i32, current_token.end as i32]],
message: format!("expression with token type {:?}", current_token.token_type),
message: format!("{:?}", current_token.token_type),
}))
}