Improve diagnostics for parsing errors

This commit is contained in:
Sam Vervaeck 2022-08-31 13:45:46 +02:00
parent eac4279a5e
commit 2d880f0f0d

View file

@ -1,4 +1,5 @@
import { kill } from "process";
import { TypeKind, Type } from "./checker"; import { TypeKind, Type } from "./checker";
import { Syntax, SyntaxKind, TextFile, TextPosition, TextRange, Token } from "./cst"; import { Syntax, SyntaxKind, TextFile, TextPosition, TextRange, Token } from "./cst";
import { countDigits } from "./util"; import { countDigits } from "./util";
@ -67,6 +68,10 @@ const DESCRIPTIONS: Record<SyntaxKind, string> = {
[SyntaxKind.ConstantExpression]: 'a constant expression such as 1 or "foo"', [SyntaxKind.ConstantExpression]: 'a constant expression such as 1 or "foo"',
[SyntaxKind.NamedTupleExpression]: 'a named tuple expression', [SyntaxKind.NamedTupleExpression]: 'a named tuple expression',
[SyntaxKind.StructExpression]: 'a struct expression', [SyntaxKind.StructExpression]: 'a struct expression',
[SyntaxKind.BlockStart]: 'the start of an indented block',
[SyntaxKind.BlockEnd]: 'the end of an indented block',
[SyntaxKind.LineFoldEnd]: 'the end of the current line-fold',
[SyntaxKind.EndOfFile]: 'end-of-file',
} }
function describeSyntaxKind(kind: SyntaxKind): string { function describeSyntaxKind(kind: SyntaxKind): string {
@ -93,6 +98,18 @@ function describeExpected(expected: SyntaxKind[]) {
return out; return out;
} }
function describeActual(token: Token): string {
switch (token.kind) {
case SyntaxKind.BlockStart:
case SyntaxKind.BlockEnd:
case SyntaxKind.LineFoldEnd:
case SyntaxKind.EndOfFile:
return describeSyntaxKind(token.kind);
default:
return `'${token.text}'`;
}
}
export class UnexpectedTokenDiagnostic { export class UnexpectedTokenDiagnostic {
public constructor( public constructor(
@ -105,7 +122,7 @@ export class UnexpectedTokenDiagnostic {
public format(): string { public format(): string {
return ANSI_FG_RED + ANSI_BOLD + 'fatal: ' + ANSI_RESET return ANSI_FG_RED + ANSI_BOLD + 'fatal: ' + ANSI_RESET
+ `expected ${describeExpected(this.expected)} but got '${this.actual.text}'\n\n` + `expected ${describeExpected(this.expected)} but got ${describeActual(this.actual)}\n\n`
+ printExcerpt(this.file, this.actual.getRange()) + '\n'; + printExcerpt(this.file, this.actual.getRange()) + '\n';
} }