| /* |
| * Copyright (C) 2012-2014 by various contributors (see AUTHORS) |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| * THE SOFTWARE. |
| */ |
| |
| import { reservedWords } from "../util/identifier"; |
| import { getOptions } from "../options"; |
| import Tokenizer from "../tokenizer"; |
| |
| export const plugins = {}; |
| |
| export default class Parser extends Tokenizer { |
| constructor(options, input) { |
| options = getOptions(options); |
| super(options, input); |
| |
| this.options = options; |
| this.inModule = this.options.sourceType === "module"; |
| this.input = input; |
| this.plugins = this.loadPlugins(this.options.plugins); |
| this.filename = options.sourceFilename; |
| |
| // If enabled, skip leading hashbang line. |
| if (this.state.pos === 0 && this.input[0] === "#" && this.input[1] === "!") { |
| this.skipLineComment(2); |
| } |
| } |
| |
| isReservedWord(word) { |
| if (word === "await") { |
| return this.inModule; |
| } else { |
| return reservedWords[6](word); |
| } |
| } |
| |
| hasPlugin(name) { |
| return !!this.plugins[name]; |
| } |
| |
| extend(name, f) { |
| this[name] = f(this[name]); |
| } |
| |
| loadPlugins(pluginList) { |
| const pluginMap = {}; |
| |
| if (pluginList.indexOf("flow") >= 0) { |
| // ensure flow plugin loads last |
| pluginList = pluginList.filter((plugin) => plugin !== "flow"); |
| pluginList.push("flow"); |
| } |
| |
| if (pluginList.indexOf("estree") >= 0) { |
| // ensure estree plugin loads first |
| pluginList = pluginList.filter((plugin) => plugin !== "estree"); |
| pluginList.unshift("estree"); |
| } |
| |
| for (const name of pluginList) { |
| if (!pluginMap[name]) { |
| pluginMap[name] = true; |
| |
| const plugin = plugins[name]; |
| if (plugin) plugin(this); |
| } |
| } |
| |
| return pluginMap; |
| } |
| |
| parse() { |
| const file = this.startNode(); |
| const program = this.startNode(); |
| this.nextToken(); |
| return this.parseTopLevel(file, program); |
| } |
| } |