UNPKG

sucrase

Version:

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

141 lines (105 loc) 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTokens = getTokens; exports.parse = parse; exports.parseExpression = parseExpression; Object.defineProperty(exports, "tokTypes", { enumerable: true, get: function () { return _types.types; } }); var _parser = _interopRequireWildcard(require("./parser")); var _types = require("./tokenizer/types"); require("./tokenizer/context"); var _estree = _interopRequireDefault(require("./plugins/estree")); var _flow = _interopRequireDefault(require("./plugins/flow")); var _jsx = _interopRequireDefault(require("./plugins/jsx")); var _typescript = _interopRequireDefault(require("./plugins/typescript")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } _parser.plugins.estree = _estree.default; _parser.plugins.flow = _flow.default; _parser.plugins.jsx = _jsx.default; _parser.plugins.typescript = _typescript.default; function getTokens(input, options) { const parser = getParser(options, input); parser.next(); while (parser.state.type.label !== 'eof') { parser.next(); } parser.next(); return parser.state.tokens; } function parse(input, options) { if (options && options.sourceType === "unambiguous") { options = Object.assign({}, options); try { options.sourceType = "module"; const ast = getParser(options, input).parse(); // Rather than try to parse as a script first, we opt to parse as a module and convert back // to a script where possible to avoid having to do a full re-parse of the input content. if (!hasModuleSyntax(ast)) ast.program.sourceType = "script"; return ast; } catch (moduleError) { try { options.sourceType = "script"; return getParser(options, input).parse(); } catch (scriptError) {} throw moduleError; } } else { return getParser(options, input).parse(); } } function parseExpression(input, options) { const parser = getParser(options, input); if (parser.options.strictMode) { parser.state.strict = true; } return parser.getExpression(); } function getParser(options, input) { const cls = options && options.plugins ? getParserClass(options.plugins) : _parser.default; return new cls(options, input); } const parserClassCache = {}; /** Get a Parser class with plugins applied. */ function getParserClass(pluginsFromOptions) { if (pluginsFromOptions.indexOf("decorators") >= 0 && pluginsFromOptions.indexOf("decorators2") >= 0) { throw new Error("Cannot use decorators and decorators2 plugin together"); } // Filter out just the plugins that have an actual mixin associated with them. let pluginList = pluginsFromOptions.filter(p => p === "estree" || p === "flow" || p === "jsx" || p === "typescript"); if (pluginList.indexOf("flow") >= 0) { // ensure flow plugin loads last pluginList = pluginList.filter(plugin => plugin !== "flow"); pluginList.push("flow"); } if (pluginList.indexOf("flow") >= 0 && pluginList.indexOf("typescript") >= 0) { throw new Error("Cannot combine flow and typescript plugins."); } if (pluginList.indexOf("typescript") >= 0) { // ensure typescript plugin loads last pluginList = pluginList.filter(plugin => plugin !== "typescript"); pluginList.push("typescript"); } if (pluginList.indexOf("estree") >= 0) { // ensure estree plugin loads first pluginList = pluginList.filter(plugin => plugin !== "estree"); pluginList.unshift("estree"); } const key = pluginList.join("/"); let cls = parserClassCache[key]; if (!cls) { cls = _parser.default; for (const plugin of pluginList) { cls = _parser.plugins[plugin](cls); } parserClassCache[key] = cls; } return cls; } function hasModuleSyntax(ast) { return ast.program.body.some(child => child.type === "ImportDeclaration" && (!child.importKind || child.importKind === "value") || child.type === "ExportNamedDeclaration" && (!child.exportKind || child.exportKind === "value") || child.type === "ExportAllDeclaration" && (!child.exportKind || child.exportKind === "value") || child.type === "ExportDefaultDeclaration"); }