UNPKG

sucrase

Version:

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

121 lines (84 loc) 3.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _types = require("../tokenizer/types"); var _tokenizer = _interopRequireDefault(require("../tokenizer")); var _whitespace = require("../util/whitespace"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // ## Parser utilities class UtilParser extends _tokenizer.default { // TODO addExtra(node, key, val) { if (!node) return; const extra = node.extra = node.extra || {}; extra[key] = val; } // TODO isRelational(op) { return this.match(_types.types.relational) && this.state.value === op; } // TODO expectRelational(op) { if (this.isRelational(op)) { this.next(); } else { this.unexpected(null, _types.types.relational); } } // eat() for relational operators. eatRelational(op) { if (this.isRelational(op)) { this.next(); return true; } return false; } // Tests whether parsed token is a contextual keyword. isContextual(name) { return this.match(_types.types.name) && this.state.value === name; } isLookaheadContextual(name) { const l = this.lookahead(); return l.type === _types.types.name && l.value === name; } // Consumes contextual keyword if possible. eatContextual(name) { return this.state.value === name && this.eat(_types.types.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(_types.types.eof) || this.match(_types.types.braceR) || this.hasPrecedingLineBreak(); } hasPrecedingLineBreak() { return _whitespace.lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); } // TODO isLineTerminator() { return this.eat(_types.types.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, _types.types.semi); } // Expect a token of a given type. If found, consume it, otherwise, // raise an unexpected token error at given pos. expect(type, pos) { this.eat(type) || this.unexpected(pos, type); } // Raise an unexpected token error. Can take the expected token type // instead of a message string. unexpected(pos, messageOrType = "Unexpected token") { if (typeof messageOrType !== "string") { messageOrType = `Unexpected token, expected "${messageOrType.label}"`; } throw this.raise(pos != null ? pos : this.state.start, messageOrType); } expectPlugin(name, pos) { if (!this.hasPlugin(name)) { throw this.raise(pos != null ? pos : this.state.start, `This experimental syntax requires enabling the parser plugin: '${name}'`, [name]); } return true; } expectOnePlugin(names, pos) { if (!names.some(n => this.hasPlugin(n))) { throw this.raise(pos != null ? pos : this.state.start, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`, names); } } } exports.default = UtilParser;