gherkin
Version:
98 lines (82 loc) • 2.6 kB
text/typescript
import { messages } from 'cucumber-messages'
import Token from './Token'
import createLocation from './cli/createLocation'
class GherkinException extends Error {
public errors: Error[]
public location: messages.ILocation
constructor(message: string) {
super(message)
const actualProto = new.target.prototype
// https://stackoverflow.com/questions/41102060/typescript-extending-error-class
if (Object.setPrototypeOf) {
Object.setPrototypeOf(this, actualProto)
} else {
// @ts-ignore
this.__proto__ = actualProto
}
}
protected static _create<T>(location: messages.ILocation, message: string) {
const column = location.column || 0
const m = `(${location.line}:${column}): ${message}`
const err = new this(m)
err.location = location
return err
}
}
export class ParserException extends GherkinException {}
export class CompositeParserException extends GherkinException {
public static create(errors: Error[]) {
const message = 'Parser errors:\n' + errors.map(e => e.message).join('\n')
const err = new this(message)
err.errors = errors
return err
}
}
export class UnexpectedTokenException extends GherkinException {
public static create(
token: Token,
expectedTokenTypes: string[],
stateComment: string
) {
const message = `expected: ${expectedTokenTypes.join(
', '
)}, got '${token.getTokenValue().trim()}'`
const location = tokenLocation(token)
return this._create(location, message)
}
}
export class UnexpectedEOFException extends GherkinException {
public static create(
token: Token,
expectedTokenTypes: string[],
stateComment: string
) {
const message = `unexpected end of file, expected: ${expectedTokenTypes.join(
', '
)}`
const location = tokenLocation(token)
return this._create(location, message)
}
}
export class AstBuilderException extends GherkinException {
public static create(message: string, location: messages.ILocation) {
return this._create(location, message)
}
}
export class NoSuchLanguageException extends GherkinException {
public static create(language: string, location: messages.ILocation) {
const message = 'Language not supported: ' + language
return this._create(location, message)
}
}
function tokenLocation(token: Token) {
return token.location &&
token.location.line &&
token.line &&
token.line.indent !== undefined
? createLocation({
line: token.location.line,
column: token.line.indent + 1,
})
: token.location
}