UNPKG

sucrase

Version:

Super-fast alternative to Babel for when you can target modern JS runtimes

56 lines (55 loc) 2.17 kB
import Tokenizer from "../tokenizer"; import { types as tt } from "../tokenizer/types"; import { lineBreak } from "../util/whitespace"; // ## Parser utilities export default class UtilParser extends Tokenizer { // Tests whether parsed token is a contextual keyword. isContextual(name) { return this.match(tt.name) && this.state.value === name; } isLookaheadContextual(name) { const l = this.lookaheadTypeAndValue(); return l.type === tt.name && l.value === name; } // Consumes contextual keyword if possible. eatContextual(name) { return this.state.value === name && this.eat(tt.name); } // Asserts that following token is given contextual keyword. expectContextual(name, message) { if (!this.eatContextual(name)) this.unexpected(null, message); } // Test whether a semicolon can be inserted at the current position. canInsertSemicolon() { return this.match(tt.eof) || this.match(tt.braceR) || this.hasPrecedingLineBreak(); } hasPrecedingLineBreak() { return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); } isLineTerminator() { return this.eat(tt.semi) || this.canInsertSemicolon(); } // Consume a semicolon, or, failing that, see if we are allowed to // pretend that there is a semicolon at this position. semicolon() { if (!this.isLineTerminator()) this.unexpected(null, tt.semi); } // Expect a token of a given type. If found, consume it, otherwise, // raise an unexpected token error at given pos. expect(type, pos) { const matched = this.eat(type); if (!matched) { this.unexpected(pos, type); } } // Raise an unexpected token error. Can take the expected token type // instead of a message string. unexpected(pos = null, messageOrType = "Unexpected token") { if (typeof messageOrType !== "string") { messageOrType = `Unexpected token, expected "${messageOrType.label}"`; } throw this.raise(pos != null ? pos : this.state.start, messageOrType); } }