diff options
Diffstat (limited to 'node_modules/acorn-dynamic-import')
47 files changed, 16555 insertions, 0 deletions
diff --git a/node_modules/acorn-dynamic-import/CHANGELOG.md b/node_modules/acorn-dynamic-import/CHANGELOG.md new file mode 100644 index 000000000..52a4e2630 --- /dev/null +++ b/node_modules/acorn-dynamic-import/CHANGELOG.md @@ -0,0 +1,19 @@ +# 2.0.2 + +- Fixing parsing of `yield import()`. + +# 2.0.1 + +- Removing unnecessary `in-publish` dependency. + +# 2.0.0 + +- Updating acorn version to >= 4. + +# 1.0.1 + +- Fixes for publishing the module. + +# 1.0.0 + +- Initial release of plugin. diff --git a/node_modules/acorn-dynamic-import/LICENSE b/node_modules/acorn-dynamic-import/LICENSE new file mode 100755 index 000000000..25c6dc8be --- /dev/null +++ b/node_modules/acorn-dynamic-import/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Jordan Gensler + +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. diff --git a/node_modules/acorn-dynamic-import/README.md b/node_modules/acorn-dynamic-import/README.md new file mode 100755 index 000000000..8fcd583f7 --- /dev/null +++ b/node_modules/acorn-dynamic-import/README.md @@ -0,0 +1,33 @@ +# Dynamic import support in acorn + +This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. + +For more information, check out the [proposal repo](https://github.com/tc39/proposal-dynamic-import). + +## Usage + +You can use this module directly in order to get Acorn instance with plugin installed: + +```js +import acorn from 'acorn-dynamic-import'; +// or... +const acorn = require('acorn-dynamic-import').default; +``` + +Or you can use `inject.js` for injecting plugin into your own version of Acorn like this: + +```js +const acorn = require('acorn-dynamic-import/lib/inject').default(require('./custom-acorn')); +``` + +Then, use the `plugins` option whenever you need to support dynamicImport while parsing: + +```js +const ast = acorn.parse(code, { + plugins: { dynamicImport: true } +}); +``` + +## License + +This plugin is issued under the [MIT license](./LICENSE). diff --git a/node_modules/acorn-dynamic-import/lib/index.js b/node_modules/acorn-dynamic-import/lib/index.js new file mode 100644 index 000000000..b6087debf --- /dev/null +++ b/node_modules/acorn-dynamic-import/lib/index.js @@ -0,0 +1,17 @@ +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _acorn = require('acorn'); + +var acorn = _interopRequireWildcard(_acorn); + +var _inject = require('./inject'); + +var _inject2 = _interopRequireDefault(_inject); + +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)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +exports['default'] = (0, _inject2['default'])(acorn);
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/lib/inject.js b/node_modules/acorn-dynamic-import/lib/inject.js new file mode 100644 index 000000000..7b3832b70 --- /dev/null +++ b/node_modules/acorn-dynamic-import/lib/inject.js @@ -0,0 +1,70 @@ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports['default'] = injectDynamicImport; +/* eslint-disable no-underscore-dangle */ + +function injectDynamicImport(acorn) { + var tt = acorn.tokTypes; + + // NOTE: This allows `yield import()` to parse correctly. + tt._import.startsExpr = true; + + function parseDynamicImport() { + var node = this.startNode(); + this.next(); + if (this.type !== tt.parenL) { + this.unexpected(); + } + return this.finishNode(node, 'Import'); + } + + function peekNext() { + return this.input[this.pos]; + } + + // eslint-disable-next-line no-param-reassign + acorn.plugins.dynamicImport = function () { + function dynamicImportPlugin(instance) { + instance.extend('parseStatement', function (nextMethod) { + return function () { + function parseStatement() { + var node = this.startNode(); + if (this.type === tt._import) { + var nextToken = peekNext.call(this); + if (nextToken === tt.parenL.label) { + var expr = this.parseExpression(); + return this.parseExpressionStatement(node, expr); + } + } + + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return nextMethod.apply(this, args); + } + + return parseStatement; + }(); + }); + + instance.extend('parseExprAtom', function (nextMethod) { + return function () { + function parseExprAtom(refDestructuringErrors) { + if (this.type === tt._import) { + return parseDynamicImport.call(this); + } + return nextMethod.call(this, refDestructuringErrors); + } + + return parseExprAtom; + }(); + }); + } + + return dynamicImportPlugin; + }(); + + return acorn; +}
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/.bin/acorn b/node_modules/acorn-dynamic-import/node_modules/.bin/acorn new file mode 120000 index 000000000..cf7676038 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/.bin/acorn @@ -0,0 +1 @@ +../acorn/bin/acorn
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/.npmignore b/node_modules/acorn-dynamic-import/node_modules/acorn/.npmignore new file mode 100644 index 000000000..eb3644b3a --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/.npmignore @@ -0,0 +1,10 @@ +/.tern-port +/test +/local +/rollup +/bin/generate-identifier-regex.js +/bin/update_authors.sh +.editorconfig +.gitattributes +.tern-project +.travis.yml diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/AUTHORS b/node_modules/acorn-dynamic-import/node_modules/acorn/AUTHORS new file mode 100644 index 000000000..ab64891bf --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/AUTHORS @@ -0,0 +1,62 @@ +List of Acorn contributors. Updated before every release. + +Adrian Rakovsky +Alistair Braidwood +Amila Welihinda +Andres Suarez +Angelo +Aparajita Fishman +Arian Stolwijk +Artem Govorov +Brandon Mills +Charles Hughes +Conrad Irwin +Daniel Tschinder +David Bonnet +Domenico Matteo +Forbes Lindesay +Gilad Peleg +impinball +Ingvar Stepanyan +Jackson Ray Hamilton +Jesse McCarthy +Jiaxing Wang +Joel Kemp +Johannes Herr +Jordan Klassen +Jürg Lehni +Kai Cataldo +keeyipchan +Keheliya Gallaba +Kevin Irish +Kevin Kwok +krator +Marijn Haverbeke +Martin Carlberg +Mat Garcia +Mathias Bynens +Mathieu 'p01' Henri +Matthew Bastien +Max Schaefer +Max Zerzouri +Mihai Bazon +Mike Rennie +naoh +Nicholas C. Zakas +Nick Fitzgerald +Olivier Thomann +Oskar Schöldström +Paul Harper +Peter Rust +PlNG +Prayag Verma +ReadmeCritic +r-e-d +Richard Gibson +Rich Harris +Sebastian McKenzie +Simen Bekkhus +Timothy Gu +Toru Nagashima +Wexpo Lyu +zsjforcn diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/CHANGELOG.md b/node_modules/acorn-dynamic-import/node_modules/acorn/CHANGELOG.md new file mode 100644 index 000000000..f6d1fa8b3 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/CHANGELOG.md @@ -0,0 +1,286 @@ +## 4.0.11 (2017-02-07) + +### Bug fixes + +Allow all forms of member expressions to be parenthesized as lvalue. + +## 4.0.10 (2017-02-07) + +### Bug fixes + +Don't expect semicolons after default-exported functions or classes, +even when they are expressions. + +Check for use of `'use strict'` directives in non-simple parameter +functions, even when already in strict mode. + +## 4.0.9 (2017-02-06) + +### Bug fixes + +Fix incorrect error raised for parenthesized simple assignment +targets, so that `(x) = 1` parses again. + +## 4.0.8 (2017-02-03) + +### Bug fixes + +Solve spurious parenthesized pattern errors by temporarily erring on +the side of accepting programs that our delayed errors don't handle +correctly yet. + +## 4.0.7 (2017-02-02) + +### Bug fixes + +Accept invalidly rejected code like `(x).y = 2` again. + +Don't raise an error when a function _inside_ strict code has a +non-simple parameter list. + +## 4.0.6 (2017-02-02) + +### Bug fixes + +Fix exponential behavior (manifesting itself as a complete hang for +even relatively small source files) introduced by the new 'use strict' +check. + +## 4.0.5 (2017-02-02) + +### Bug fixes + +Disallow parenthesized pattern expressions. + +Allow keywords as export names. + +Don't allow the `async` keyword to be parenthesized. + +Properly raise an error when a keyword contains a character escape. + +Allow `"use strict"` to appear after other string literal expressions. + +Disallow labeled declarations. + +## 4.0.4 (2016-12-19) + +### Bug fixes + +Fix issue with loading acorn_loose.js with an AMD loader. + +Fix crash when `export` was followed by a keyword that can't be +exported. + +## 4.0.3 (2016-08-16) + +### Bug fixes + +Allow regular function declarations inside single-statement `if` +branches in loose mode. Forbid them entirely in strict mode. + +Properly parse properties named `async` in ES2017 mode. + +Fix bug where reserved words were broken in ES2017 mode. + +## 4.0.2 (2016-08-11) + +### Bug fixes + +Don't ignore period or 'e' characters after octal numbers. + +Fix broken parsing for call expressions in default parameter values +of arrow functions. + +## 4.0.1 (2016-08-08) + +### Bug fixes + +Fix false positives in duplicated export name errors. + +## 4.0.0 (2016-08-07) + +### Breaking changes + +The default `ecmaVersion` option value is now 7. + +A number of internal method signatures changed, so plugins might need +to be updated. + +### Bug fixes + +The parser now raises errors on duplicated export names. + +`arguments` and `eval` can now be used in shorthand properties. + +Duplicate parameter names in non-simple argument lists now always +produce an error. + +### New features + +The `ecmaVersion` option now also accepts year-style version numbers +(2015, etc). + +Support for `async`/`await` syntax when `ecmaVersion` is >= 8. + +Support for trailing commas in call expressions when `ecmaVersion` +is >= 8. + +## 3.3.0 (2016-07-25) + +### Bug fixes + +Fix bug in tokenizing of regexp operator after a function declaration. + +Fix parser crash when parsing an array pattern with a hole. + +### New features + +Implement check against complex argument lists in functions that +enable strict mode in ES7. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Improve handling of lack of unicode regexp support in host +environment. + +Properly reject shorthand properties whose name is a keyword. + +Don't crash when the loose parser is called without options object. + +### New features + +Visitors created with `visit.make` now have their base as _prototype_, +rather than copying properties into a fresh object. + +Make it possible to use `visit.ancestor` with a walk state. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Fix issue where the loose parser created invalid TemplateElement nodes +for unclosed template literals. + +Properly tokenize the division operator directly after a function +expression. + +Allow trailing comma in destructuring arrays. + +### New features + +The walker now allows defining handlers for `CatchClause` nodes. + +## 3.0.4 (2016-02-25) + +### Fixes + +Allow update expressions as left-hand-side of the ES7 exponential +operator. + +## 3.0.2 (2016-02-10) + +### Fixes + +Fix bug that accidentally made `undefined` a reserved word when +parsing ES7. + +## 3.0.0 (2016-02-10) + +### Breaking changes + +The default value of the `ecmaVersion` option is now 6 (used to be 5). + +Support for comprehension syntax (which was dropped from the draft +spec) has been removed. + +### Fixes + +`let` and `yield` are now “contextual keywords”, meaning you can +mostly use them as identifiers in ES5 non-strict code. + +A parenthesized class or function expression after `export default` is +now parsed correctly. + +### New features + +When `ecmaVersion` is set to 7, Acorn will parse the exponentiation +operator (`**`). + +The identifier character ranges are now based on Unicode 8.0.0. + +Plugins can now override the `raiseRecoverable` method to override the +way non-critical errors are handled. + +## 2.7.0 (2016-01-04) + +### Fixes + +Stop allowing rest parameters in setters. + +Make sure the loose parser always attaches a `local` property to +`ImportNamespaceSpecifier` nodes. + +Disallow `y` rexexp flag in ES5. + +Disallow `\00` and `\000` escapes in strict mode. + +Raise an error when an import name is a reserved word. + +## 2.6.4 (2015-11-12) + +### Fixes + +Fix crash in loose parser when parsing invalid object pattern. + +### New features + +Support plugins in the loose parser. + +## 2.6.2 (2015-11-10) + +### Fixes + +Don't crash when no options object is passed. + +## 2.6.0 (2015-11-09) + +### Fixes + +Add `await` as a reserved word in module sources. + +Disallow `yield` in a parameter default value for a generator. + +Forbid using a comma after a rest pattern in an array destructuring. + +### New features + +Support parsing stdin in command-line tool. + +## 2.5.2 (2015-10-27) + +### Fixes + +Fix bug where the walker walked an exported `let` statement as an +expression. + +## 2.5.0 (2015-10-27) + +### Fixes + +Fix tokenizer support in the command-line tool. + +In the loose parser, don't allow non-string-literals as import +sources. + +Stop allowing `new.target` outside of functions. + +Remove legacy `guard` and `guardedHandler` properties from try nodes. + +Stop allowing multiple `__proto__` properties on an object literal in +strict mode. + +Don't allow rest parameters to be non-identifier patterns. + +Check for duplicate paramter names in arrow functions. diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/LICENSE b/node_modules/acorn-dynamic-import/node_modules/acorn/LICENSE new file mode 100644 index 000000000..a35ebf44f --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012-2016 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. diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/README.md b/node_modules/acorn-dynamic-import/node_modules/acorn/README.md new file mode 100644 index 000000000..b7efe2341 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/README.md @@ -0,0 +1,409 @@ +# Acorn + +[![Build Status](https://travis-ci.org/ternjs/acorn.svg?branch=master)](https://travis-ci.org/ternjs/acorn) +[![NPM version](https://img.shields.io/npm/v/acorn.svg)](https://www.npmjs.com/package/acorn) +[![CDNJS](https://img.shields.io/cdnjs/v/acorn.svg)](https://cdnjs.com/libraries/acorn) +[Author funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?force)](https://marijnhaverbeke.nl/fund/) + +A tiny, fast JavaScript parser, written completely in JavaScript. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/ternjs/acorn/blob/master/LICENSE). + +You are welcome to +[report bugs](https://github.com/ternjs/acorn/issues) or create pull +requests on [github](https://github.com/ternjs/acorn). For questions +and discussion, please use the +[Tern discussion forum](https://discuss.ternjs.net). + +## Installation + +The easiest way to install acorn is with [`npm`][npm]. + +[npm]: https://www.npmjs.com/ + +```sh +npm install acorn +``` + +Alternately, download the source. + +```sh +git clone https://github.com/ternjs/acorn.git +``` + +## Components + +When run in a CommonJS (node.js) or AMD environment, exported values +appear in the interfaces exposed by the individual files, as usual. +When loaded in the browser (Acorn works in any JS-enabled browser more +recent than IE5) without any kind of module management, a single +global object `acorn` will be defined, and all the exported properties +will be added to that. + +### Main parser + +This is implemented in `dist/acorn.js`, and is what you get when you +`require("acorn")` in node.js. + +**parse**`(input, options)` is used to parse a JavaScript program. +The `input` parameter is a string, `options` can be undefined or an +object setting some of the options listed below. The return value will +be an abstract syntax tree object as specified by the +[ESTree spec][estree]. + +When encountering a syntax error, the parser will raise a +`SyntaxError` object with a meaningful message. The error object will +have a `pos` property that indicates the character offset at which the +error occurred, and a `loc` object that contains a `{line, column}` +object referring to that same position. + +[estree]: https://github.com/estree/estree + +- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be + either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support for strict + mode, the set of reserved words, and support for new syntax features. + Default is 7. + + **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being + implemented by Acorn. + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"` or `"module"`. This influences global strict mode + and parsing of `import` and `export` declarations. + +- **onInsertedSemicolon**: If given a callback, that callback will be + called whenever a missing semicolon is inserted by the parser. The + callback will be given the character offset of the point where the + semicolon is inserted as argument, and if `locations` is on, also a + `{line, column}` object representing this position. + +- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing + commas. + +- **allowReserved**: If `false`, using a reserved word will generate + an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher + versions. When given the value `"never"`, reserved words and + keywords can also not be used as property names (as in Internet + Explorer's old parser). + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed. + +- **allowHashBang**: When this is enabled (off by default), if the + code starts with the characters `#!` (as in a shellscript), the + first line will be treated as a comment. + +- **locations**: When `true`, each node has a `loc` object attached + with `start` and `end` subobjects, each of which contains the + one-based line and zero-based column numbers in `{line, column}` + form. Default is `false`. + +- **onToken**: If a function is passed for this option, each found + token will be passed in same format as tokens returned from + `tokenizer().getToken()`. + + If array is passed, each found token is pushed to it. + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **onComment**: If a function is passed for this option, whenever a + comment is encountered the function will be called with the + following parameters: + + - `block`: `true` if the comment is a block comment, false if it + is a line comment. + - `text`: The content of the comment. + - `start`: Character offset of the start of the comment. + - `end`: Character offset of the end of the comment. + + When the `locations` options is on, the `{line, column}` locations + of the comment’s start and end are passed as two additional + parameters. + + If array is passed for this option, each found comment is pushed + to it as object in Esprima format: + + ```javascript + { + "type": "Line" | "Block", + "value": "comment text", + "start": Number, + "end": Number, + // If `locations` option is on: + "loc": { + "start": {line: Number, column: Number} + "end": {line: Number, column: Number} + }, + // If `ranges` option is on: + "range": [Number, Number] + } + ``` + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **ranges**: Nodes have their start and end characters offsets + recorded in `start` and `end` properties (directly on the node, + rather than the `loc` object, which holds line/column data. To also + add a [semi-standardized][range] `range` property holding a + `[start, end]` array with the same numbers, set the `ranges` option + to `true`. + +- **program**: It is possible to parse multiple files into a single + AST by passing the tree produced by parsing the first file as the + `program` option in subsequent parses. This will add the toplevel + forms of the parsed file to the "Program" (top) node of an existing + parse tree. + +- **sourceFile**: When the `locations` option is `true`, you can pass + this option to add a `source` attribute in every node’s `loc` + object. Note that the contents of this option are not examined or + processed in any way; you are free to use whatever format you + choose. + +- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property + will be added (regardless of the `location` option) directly to the + nodes, rather than the `loc` object. + +- **preserveParens**: If this option is `true`, parenthesized expressions + are represented by (non-standard) `ParenthesizedExpression` nodes + that have a single `expression` property containing the expression + inside parentheses. + +[range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + +**parseExpressionAt**`(input, offset, options)` will parse a single +expression in a string, and return its AST. It will not complain if +there is more of the string left after the expression. + +**getLineInfo**`(input, offset)` can be used to get a `{line, +column}` object for a given program string and character offset. + +**tokenizer**`(input, options)` returns an object with a `getToken` +method that can be called repeatedly to get the next token, a `{start, +end, type, value}` object (with added `loc` property when the +`locations` option is enabled and `range` property when the `ranges` +option is enabled). When the token's type is `tokTypes.eof`, you +should stop calling the method, since it will keep returning that same +token forever. + +In ES6 environment, returned result can be used as any other +protocol-compliant iterable: + +```javascript +for (let token of acorn.tokenizer(str)) { + // iterate over the tokens +} + +// transform code to array of tokens: +var tokens = [...acorn.tokenizer(str)]; +``` + +**tokTypes** holds an object mapping names to the token type objects +that end up in the `type` properties of tokens. + +#### Note on using with [Escodegen][escodegen] + +Escodegen supports generating comments from AST, attached in +Esprima-specific format. In order to simulate same format in +Acorn, consider following example: + +```javascript +var comments = [], tokens = []; + +var ast = acorn.parse('var x = 42; // answer', { + // collect ranges for each node + ranges: true, + // collect comments in Esprima's format + onComment: comments, + // collect token ranges + onToken: tokens +}); + +// attach comments using collected information +escodegen.attachComments(ast, comments, tokens); + +// generate code +console.log(escodegen.generate(ast, {comment: true})); +// > 'var x = 42; // answer' +``` + +[escodegen]: https://github.com/estools/escodegen + +### dist/acorn_loose.js ### + +This file implements an error-tolerant parser. It exposes a single +function. The loose parser is accessible in node.js via `require("acorn/dist/acorn_loose")`. + +**parse_dammit**`(input, options)` takes the same arguments and +returns the same syntax tree as the `parse` function in `acorn.js`, +but never raises an error, and will do its best to parse syntactically +invalid code in as meaningful a way as it can. It'll insert identifier +nodes with name `"✖"` as placeholders in places where it can't make +sense of the input. Depends on `acorn.js`, because it uses the same +tokenizer. + +### dist/walk.js ### + +Implements an abstract syntax tree walker. Will store its interface in +`acorn.walk` when loaded without a module system. + +**simple**`(node, visitors, base, state)` does a 'simple' walk over +a tree. `node` should be the AST node to walk, and `visitors` an +object with properties whose names correspond to node types in the +[ESTree spec][estree]. The properties should contain functions +that will be called with the node object and, if applicable the state +at that point. The last two arguments are optional. `base` is a walker +algorithm, and `state` is a start state. The default walker will +simply visit all statements and expressions and not produce a +meaningful state. (An example of a use of state is to track scope at +each point in the tree.) + +**ancestor**`(node, visitors, base, state)` does a 'simple' walk over +a tree, building up an array of ancestor nodes (including the current node) +and passing the array to the callbacks as a third parameter. + +**recursive**`(node, state, functions, base)` does a 'recursive' +walk, where the walker functions are responsible for continuing the +walk on the child nodes of their target node. `state` is the start +state, and `functions` should contain an object that maps node types +to walker functions. Such functions are called with `(node, state, c)` +arguments, and can cause the walk to continue on a sub-node by calling +the `c` argument on it with `(node, state)` arguments. The optional +`base` argument provides the fallback walker functions for node types +that aren't handled in the `functions` object. If not given, the +default walkers will be used. + +**make**`(functions, base)` builds a new walker object by using the +walker functions in `functions` and filling in the missing ones by +taking defaults from `base`. + +**findNodeAt**`(node, start, end, test, base, state)` tries to +locate a node in a tree at the given start and/or end offsets, which +satisfies the predicate `test`. `start` and `end` can be either `null` +(as wildcard) or a number. `test` may be a string (indicating a node +type) or a function that takes `(nodeType, node)` arguments and +returns a boolean indicating whether this node is interesting. `base` +and `state` are optional, and can be used to specify a custom walker. +Nodes are tested from inner to outer, so if two nodes match the +boundaries, the inner one will be preferred. + +**findNodeAround**`(node, pos, test, base, state)` is a lot like +`findNodeAt`, but will match any node that exists 'around' (spanning) +the given position. + +**findNodeAfter**`(node, pos, test, base, state)` is similar to +`findNodeAround`, but will match all nodes *after* the given position +(testing outer nodes before inner nodes). + +## Command line interface + +The `bin/acorn` utility can be used to parse a file from the command +line. It accepts as arguments its input file and the following +options: + +- `--ecma3|--ecma5|--ecma6|--ecma7`: Sets the ECMAScript version to parse. Default is + version 5. + +- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise. + +- `--locations`: Attaches a "loc" object to each node with "start" and + "end" subobjects, each of which contains the one-based line and + zero-based column numbers in `{line, column}` form. + +- `--allow-hash-bang`: If the code starts with the characters #! (as in a shellscript), the first line will be treated as a comment. + +- `--compact`: No whitespace is used in the AST output. + +- `--silent`: Do not output the AST, just return the exit status. + +- `--help`: Print the usage information and quit. + +The utility spits out the syntax tree as JSON data. + +## Build system + +Acorn is written in ECMAScript 6, as a set of small modules, in the +project's `src` directory, and compiled down to bigger ECMAScript 3 +files in `dist` using [Browserify](http://browserify.org) and +[Babel](http://babeljs.io/). If you are already using Babel, you can +consider including the modules directly. + +The command-line test runner (`npm test`) uses the ES6 modules. The +browser-based test page (`test/index.html`) uses the compiled modules. +The `bin/build-acorn.js` script builds the latter from the former. + +If you are working on Acorn, you'll probably want to try the code out +directly, without an intermediate build step. In your scripts, you can +register the Babel require shim like this: + + require("babel-core/register") + +That will allow you to directly `require` the ES6 modules. + +## Plugins + +Acorn is designed support allow plugins which, within reasonable +bounds, redefine the way the parser works. Plugins can add new token +types and new tokenizer contexts (if necessary), and extend methods in +the parser object. This is not a clean, elegant API—using it requires +an understanding of Acorn's internals, and plugins are likely to break +whenever those internals are significantly changed. But still, it is +_possible_, in this way, to create parsers for JavaScript dialects +without forking all of Acorn. And in principle it is even possible to +combine such plugins, so that if you have, for example, a plugin for +parsing types and a plugin for parsing JSX-style XML literals, you +could load them both and parse code with both JSX tags and types. + +A plugin should register itself by adding a property to +`acorn.plugins`, which holds a function. Calling `acorn.parse`, a +`plugins` option can be passed, holding an object mapping plugin names +to configuration values (or just `true` for plugins that don't take +options). After the parser object has been created, the initialization +functions for the chosen plugins are called with `(parser, +configValue)` arguments. They are expected to use the `parser.extend` +method to extend parser methods. For example, the `readToken` method +could be extended like this: + +```javascript +parser.extend("readToken", function(nextMethod) { + return function(code) { + console.log("Reading a token!") + return nextMethod.call(this, code) + } +}) +``` + +The `nextMethod` argument passed to `extend`'s second argument is the +previous value of this method, and should usually be called through to +whenever the extended method does not handle the call itself. + +Similarly, the loose parser allows plugins to register themselves via +`acorn.pluginsLoose`. The extension mechanism is the same as for the +normal parser: + +```javascript +looseParser.extend("readToken", function(nextMethod) { + return function() { + console.log("Reading a token in the loose parser!") + return nextMethod.call(this) + } +}) +``` + +### Existing plugins + + - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx) + - [`acorn-es7-plugin`](https://github.com/MatAtBread/acorn-es7-plugin/): Parse [async/await syntax proposal](https://github.com/tc39/ecmascript-asyncawait) + - [`acorn-object-spread`](https://github.com/UXtemple/acorn-object-spread): Parse [object spread syntax proposal](https://github.com/sebmarkbage/ecmascript-rest-spread) + - [`acorn-es7`](https://www.npmjs.com/package/acorn-es7): Parse [decorator syntax proposal](https://github.com/wycats/javascript-decorators) + - [`acorn-objj`](https://www.npmjs.com/package/acorn-objj): [Objective-J](http://www.cappuccino-project.org/learn/objective-j.html) language parser built as Acorn plugin diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/bin/acorn b/node_modules/acorn-dynamic-import/node_modules/acorn/bin/acorn new file mode 100755 index 000000000..78ebd4f0e --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/bin/acorn @@ -0,0 +1,67 @@ +#!/usr/bin/env node +'use strict'; + +var path = require('path'); +var fs = require('fs'); +var acorn = require('../dist/acorn.js'); + +var infile; +var forceFile; +var silent = false; +var compact = false; +var tokenize = false; +var options = {} + +function help(status) { + var print = (status == 0) ? console.log : console.error + print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]") + print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]") + process.exit(status) +} + +for (var i = 2; i < process.argv.length; ++i) { + var arg = process.argv[i] + if ((arg == "-" || arg[0] != "-") && !infile) infile = arg + else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i] + else if (arg == "--locations") options.locations = true + else if (arg == "--allow-hash-bang") options.allowHashBang = true + else if (arg == "--silent") silent = true + else if (arg == "--compact") compact = true + else if (arg == "--help") help(0) + else if (arg == "--tokenize") tokenize = true + else if (arg == "--module") options.sourceType = 'module' + else { + var match = arg.match(/^--ecma(\d+)$/) + if (match) + options.ecmaVersion = +match[1] + else + help(1) + } +} + +function run(code) { + var result + if (!tokenize) { + try { result = acorn.parse(code, options) } + catch(e) { console.error(e.message); process.exit(1) } + } else { + result = [] + var tokenizer = acorn.tokenizer(code, options), token + while (true) { + try { token = tokenizer.getToken() } + catch(e) { console.error(e.message); process.exit(1) } + result.push(token) + if (token.type == acorn.tokTypes.eof) break + } + } + if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)) +} + +if (forceFile || infile && infile != "-") { + run(fs.readFileSync(infile, "utf8")) +} else { + var code = "" + process.stdin.resume() + process.stdin.on("data", function (chunk) { return code += chunk; }) + process.stdin.on("end", function () { return run(code); }) +}
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/.keep b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/.keep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/.keep diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.es.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.es.js new file mode 100644 index 000000000..2b34af034 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.es.js @@ -0,0 +1,3401 @@ +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000 + for (var i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; +// Map keyword names to token types. + +var keywordTypes = {} + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name + return keywordTypes[name] = new TokenType(name, options) +} + +var tt = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("</>", 7), + bitShift: binop("<</>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/ +var lineBreakG = new RegExp(lineBreak.source, "g") + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g + +function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line + this.column = col +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + var match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +function getOptions(opts) { + var options = {} + + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + + if (options.ecmaVersion >= 2015) + options.ecmaVersion -= 2009 + + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + var tokens = options.onToken + options.onToken = function (token) { return tokens.push(token); } + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + +// Registered plugins +var plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + var reserved = "" + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + if (reserved = reservedWords[v]) break + if (options.sourceType == "module") reserved += " await" + } + this.reservedWords = keywordRegexp(reserved) + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1 + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module" + this.strict = this.inModule || this.strictDirective(this.pos) + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0 + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) +}; + +var pp = Parser.prototype + +// ## Parser utilities + +var literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/ +pp.strictDirective = function(start) { + var this$1 = this; + + for (;;) { + skipWhiteSpace.lastIndex = start + start += skipWhiteSpace.exec(this$1.input)[0].length + var match = literal.exec(this$1.input.slice(start)) + if (!match) return false + if ((match[1] || match[2]) == "use strict") return true + start += match[0].length + } +} + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false + } +} + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true + } +} + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} + +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + if (!notNext) + this.next() + return true + } +} + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} + +var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1 +}; + +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) return + if (refDestructuringErrors.trailingComma > -1) + this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element") + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind + if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern") +} + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + var pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1 + if (!andThrow) return pos >= 0 + if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} + +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + this.raise(this.yieldPos, "Yield expression cannot be a default value") + if (this.awaitPos) + this.raise(this.awaitPos, "Await expression cannot be a default value") +} + +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + return this.isSimpleAssignTarget(expr.expression) + return expr.type === "Identifier" || expr.type === "MemberExpression" +} + +var pp$1 = Parser.prototype + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var this$1 = this; + + var exports = {} + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + var stmt = this$1.parseStatement(true, true, exports) + node.body.push(stmt) + } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; +pp$1.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + var ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async") + return false + + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node, false) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction() && declaration) { + this.next() + return this.parseFunctionStatement(node, true) + } + + var maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) + } +} + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() + } + + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + var lab = this$1.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp$1.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp$1.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + var isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init$1, true, kind) + this.finishNode(init$1, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) + return this.parseForIn(node, init$1) + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors + var init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.toAssignable(init) + this.checkLVal(init) + this.checkPatternErrors(refDestructuringErrors, true) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp$1.parseFunctionStatement = function(node, isAsync) { + this.next() + return this.parseFunction(node, true, false, isAsync) +} + +pp$1.isFunction = function() { + return this.type === tt._function || this.isAsyncFunction() +} + +pp$1.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.isFunction()) + node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null + return this.finishNode(node, "IfStatement") +} + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this$1.type === tt._case || this$1.type === tt._default) { + var isCase = this$1.type === tt._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) { + cur.test = this$1.parseExpression() + } else { + if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this$1.expect(tt.colon) + } else { + if (!cur) this$1.unexpected() + cur.consequent.push(this$1.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp$1.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +var empty = [] + +pp$1.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + var clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp$1.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp$1.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp$1.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp$1.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i = 0; i < this.labels.length; ++i) + if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") + var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { + var label = this$1.labels[i$1] + if (label.statementStart == node.start) { + label.statementStart = this$1.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + if (node.body.type == "ClassDeclaration" || + node.body.type == "VariableDeclaration" && (this.strict || node.body.kind != "var") || + node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) + this.raiseRecoverable(node.body.start, "Invalid labeled declaration") + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function() { + var this$1 = this; + + var node = this.startNode() + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + var stmt = this$1.parseStatement(true) + node.body.push(stmt) + } + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = [] + node.kind = kind + for (;;) { + var decl = this$1.startNode() + this$1.parseVarId(decl) + if (this$1.eat(tt.eq)) { + decl.init = this$1.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + if (!this$1.eat(tt.comma)) break + } + return node +} + +pp$1.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6 && !isAsync) + node.generator = this.eat(tt.star) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + if (isStatement == null) + isStatement = this.type == tt.name + if (isStatement) + node.id = this.parseIdent() + + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + if (!isStatement && this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp$1.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true) + this.checkYieldAwaitInDefaultParams() +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next() + if (isStatement == null) isStatement = this.type === tt.name + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + var classBody = this.startNode() + var hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this$1.eat(tt.semi)) continue + var method = this$1.startNode() + var isGenerator = this$1.eat(tt.star) + var isAsync = false + var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" + this$1.parsePropertyName(method) + method.static = isMaybeStatic && this$1.type !== tt.parenL + if (method.static) { + if (isGenerator) this$1.unexpected() + isGenerator = this$1.eat(tt.star) + this$1.parsePropertyName(method) + } + if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== tt.parenL && + !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(method) + } + method.kind = "method" + var isGetSet = false + if (!method.computed) { + var key = method.key; + if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this$1.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") + if (isAsync) this$1.raise(key.start, "Constructor can't be an async method") + method.kind = "constructor" + hadConstructor = true + } + } + this$1.parseClassMethod(classBody, method, isGenerator, isAsync) + if (isGetSet) { + var paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + var start = method.value.start + if (method.kind === "get") + this$1.raiseRecoverable(start, "getter should have no params") + else + this$1.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params") + } + } + } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} + +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} + +// Parses module export declaration. + +pp$1.parseExport = function(node, exports) { + var this$1 = this; + + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart) + var isAsync + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, false, isAsync) + } else if (this.type === tt._class) { + var cNode = this.startNode() + node.declaration = this.parseClass(cNode, null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + if (node.declaration.type === "VariableDeclaration") + this.checkVariableExport(exports, node.declaration.declarations) + else + this.checkExport(exports, node.declaration.id.name, node.declaration.id.start) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers(exports) + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (var i = 0; i < node.specifiers.length; i++) { + if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { + this$1.unexpected(node.specifiers[i].local.start) + } + } + + node.source = null + } + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp$1.checkExport = function(exports, name, pos) { + if (!exports) return + if (Object.prototype.hasOwnProperty.call(exports, name)) + this.raiseRecoverable(pos, "Duplicate export '" + name + "'") + exports[name] = true +} + +pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; + + var type = pat.type + if (type == "Identifier") + this.checkExport(exports, pat.name, pat.start) + else if (type == "ObjectPattern") + for (var i = 0; i < pat.properties.length; ++i) + this$1.checkPatternExport(exports, pat.properties[i].value) + else if (type == "ArrayPattern") + for (var i$1 = 0; i$1 < pat.elements.length; ++i$1) { + var elt = pat.elements[i$1] + if (elt) this$1.checkPatternExport(exports, elt) + } + else if (type == "AssignmentPattern") + this.checkPatternExport(exports, pat.left) + else if (type == "ParenthesizedExpression") + this.checkPatternExport(exports, pat.expression) +} + +pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; + + if (!exports) return + for (var i = 0; i < decls.length; i++) + this$1.checkPatternExport(exports, decls[i].id) +} + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" + || this.type.keyword === "const" + || this.type.keyword === "class" + || this.type.keyword === "function" + || this.isLet() + || this.isAsyncFunction() +} + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + + var nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node = this$1.startNode() + node.local = this$1.parseIdent(true) + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local + this$1.checkExport(exports, node.exported.name, node.exported.start) + nodes.push(this$1.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + var node$1 = this.startNode() + this.next() + this.expectContextual("as") + node$1.local = this.parseIdent() + this.checkLVal(node$1.local, true) + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node$2 = this$1.startNode() + node$2.imported = this$1.parseIdent(true) + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent() + } else { + node$2.local = node$2.imported + if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) + if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raiseRecoverable(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") + } + this$1.checkLVal(node$2.local, true) + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) + } + return nodes +} + +var pp$2 = Parser.prototype + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding) { + var this$1 = this; + + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + this.raise(node.start, "Can not use 'await' as identifier inside an async function") + break + + case "ObjectPattern": + case "ArrayPattern": + break + + case "ObjectExpression": + node.type = "ObjectPattern" + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i] + if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") + this$1.toAssignable(prop.value, isBinding) + } + break + + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + this.toAssignable(node.left, isBinding) + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break + + case "MemberExpression": + if (!isBinding) break + + default: + this.raise(node.start, "Assigning to rvalue") + } + } + return node +} + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length + if (end) { + var last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + var arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (var i = 0; i < end; i++) { + var elt = exprList[i] + if (elt) this$1.toAssignable(elt, isBinding) + } + return exprList +} + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} + +pp$2.parseRest = function(allowNonIdent) { + var node = this.startNode() + this.next() + + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() + + return this.finishNode(node, "RestElement") +} + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() + + case tt.bracketL: + var node = this.startNode() + this.next() + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") + + case tt.braceL: + return this.parseObj(true) + + default: + this.unexpected() + } +} + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this$1.expect(tt.comma) + if (allowEmpty && this$1.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === tt.ellipsis) { + var rest = this$1.parseRest(allowNonIdent) + this$1.parseBindingListItem(rest) + elts.push(rest) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + this$1.expect(close) + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) + this$1.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp$2.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp$2.checkLVal = function(expr, isBinding, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (var i = 0; i < expr.properties.length; i++) + this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { + var elem = expr.elements[i$1] + if (elem) this$1.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} + +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + +var pp$3 = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + var key = prop.key; + var name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + var other = propHash[name] + if (other) { + var isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + var node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + var ownDestructuringErrors = false, oldParenAssign = -1 + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign + refDestructuringErrors.parenthesizedAssign = -1 + } else { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + + var startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + var left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + var node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = -1 // reset because shorthand default was used correctly + this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) + } + if (oldParenAssign > -1) refDestructuringErrors.parenthesizedAssign = oldParenAssign + return left +} + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + var node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + var logical = this.type === tt.logicalOR || this.type === tt.logicalAND + var op = this.value + this.next() + var startPos = this.start, startLoc = this.startLoc + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr + if (this.inAsync && this.isContextual("await")) { + expr = this.parseAwait(refDestructuringErrors) + sawUnary = true + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.operator = this$1.value + node$1.prefix = false + node$1.argument = expr + this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$1, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprAtom(refDestructuringErrors) + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + var result = this.parseSubscripts(expr, startPos, startLoc) + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) refDestructuringErrors.parenthesizedAssign = -1 + if (refDestructuringErrors.parenthesizedBind >= result.start) refDestructuringErrors.parenthesizedBind = -1 + } + return result +} + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd == base.end && !this.canInsertSemicolon() + for (var computed;;) { + if ((computed = this$1.eat(tt.bracketL)) || this$1.eat(tt.dot)) { + var node = this$1.startNodeAt(startPos, startLoc) + node.object = base + node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true) + node.computed = !!computed + if (computed) this$1.expect(tt.bracketR) + base = this$1.finishNode(node, "MemberExpression") + } else if (!noCalls && this$1.eat(tt.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos + this$1.yieldPos = 0 + this$1.awaitPos = 0 + var exprList = this$1.parseExprList(tt.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors) + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(tt.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, false) + this$1.checkYieldAwaitInDefaultParams() + this$1.yieldPos = oldYieldPos + this$1.awaitPos = oldAwaitPos + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true) + this$1.yieldPos = oldYieldPos || this$1.yieldPos + this$1.awaitPos = oldAwaitPos || this$1.awaitPos + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.callee = base + node$1.arguments = exprList + base = this$1.finishNode(node$1, "CallExpression") + } else if (this$1.type === tt.backQuote) { + var node$2 = this$1.startNodeAt(startPos, startLoc) + node$2.tag = base + node$2.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$2, "TaggedTemplateExpression") + } else { + return base + } + } +} + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") + + case tt._this: + var type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + var startPos = this.start, startLoc = this.startLoc + var id = this.parseIdent(this.type !== tt.name) + if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) + return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) { + id = this.parseIdent() + if (this.canInsertSemicolon() || !this.eat(tt.arrow)) + this.unexpected() + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + + case tt.regexp: + var value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node + + case tt.num: case tt.string: + return this.parseLiteral(this.value) + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow) + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + refDestructuringErrors.parenthesizedAssign = start + if (refDestructuringErrors.parenthesizedBind < 0) + refDestructuringErrors.parenthesizedBind = start + } + return expr + + case tt.bracketL: + node = this.startNode() + this.next() + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._class: + return this.parseClass(this.startNode(), false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + this.unexpected() + } +} + +pp$3.parseLiteral = function(value) { + var node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} + +pp$3.parseParenExpression = function() { + this.expect(tt.parenL) + var val = this.parseExpression() + this.expect(tt.parenR) + return val +} + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8 + if (this.options.ecmaVersion >= 6) { + this.next() + + var innerStartPos = this.start, innerStartLoc = this.startLoc + var exprList = [], first = true, lastIsComma = false + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart + this.yieldPos = 0 + this.awaitPos = 0 + while (this.type !== tt.parenR) { + first ? first = false : this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(tt.parenR, true)) { + lastIsComma = true + break + } else if (this$1.type === tt.ellipsis) { + spreadStart = this$1.start + exprList.push(this$1.parseParenItem(this$1.parseRest())) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + break + } else { + if (this$1.type === tt.parenL && !innerParenStart) { + innerParenStart = this$1.start + } + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false) + this.checkYieldAwaitInDefaultParams() + if (innerParenStart) this.unexpected(innerParenStart) + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + this.yieldPos = oldYieldPos || this.yieldPos + this.awaitPos = oldAwaitPos || this.awaitPos + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] + } + } else { + val = this.parseParenExpression() + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +} + +pp$3.parseParenItem = function(item) { + return item +} + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = [] + +pp$3.parseNew = function() { + var node = this.startNode() + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) + else node.arguments = empty$1 + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp$3.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp$3.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.expect(tt.dollarBraceL) + node.expressions.push(this$1.parseExpression()) + this$1.expect(tt.braceR) + node.quasis.push(curElt = this$1.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var prop = this$1.startNode(), isGenerator, isAsync, startPos, startLoc + if (this$1.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this$1.start + startLoc = this$1.startLoc + } + if (!isPattern) + isGenerator = this$1.eat(tt.star) + } + this$1.parsePropertyName(prop) + if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && !prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this$1.type !== tt.parenL && + this$1.type !== tt.colon && !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(prop, refDestructuringErrors) + } else { + isAsync = false + } + this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) + this$1.checkPropClash(prop, propHash) + node.properties.push(this$1.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { + if ((isGenerator || isAsync) && this.type === tt.colon) + this.unexpected() + + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator, isAsync) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isAsync || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + var paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + var start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield") || + (this.inAsync && prop.key.name == "await")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8) + this.checkYieldAwaitInDefaultParams() + this.parseFunctionBody(node, false) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = false + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== tt.braceL + var oldStrict = this.strict, useStrict = false + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params) + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end) + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list") + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels + this.labels = [] + if (useStrict) this.strict = true + node.body = this.parseBlock(true) + node.expression = false + this.labels = oldLabels + } + + if (oldStrict || useStrict) { + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node) + this.strict = oldStrict + } else if (isArrowFunction || !this.isSimpleParamList(node.params)) { + this.checkParams(node) + } +} + +pp$3.isSimpleParamList = function(params) { + for (var i = 0; i < params.length; i++) + if (params[i].type !== "Identifier") return false + return true +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node) { + var this$1 = this; + + var nameHash = {} + for (var i = 0; i < node.params.length; i++) this$1.checkLVal(node.params[i], true, nameHash) +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(close)) break + } else first = false + + var elt + if (allowEmpty && this$1.type === tt.comma) + elt = null + else if (this$1.type === tt.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors) + if (refDestructuringErrors && this$1.type === tt.comma && refDestructuringErrors.trailingComma < 0) + refDestructuringErrors.trailingComma = this$1.start + } else { + elt = this$1.parseMaybeAssign(false, refDestructuringErrors) + } + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal) { + var node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + if (this.inAsync && this.value === "await") + this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + if (!this.yieldPos) this.yieldPos = this.start + + var node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +pp$3.parseAwait = function() { + if (!this.awaitPos) this.awaitPos = this.start + + var node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary(null, true) + return this.finishNode(node, "AwaitExpression") +} + +var pp$4 = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + var err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp$4.raiseRecoverable = pp$4.raise + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} + +var Node = function Node(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] +}; + +// Start an AST node, attaching a start offset. + +var pp$5 = Parser.prototype + +pp$5.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp$5.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp$5.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp$5.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} + +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override +}; + +var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), + f_expr: new TokContext("function", true) +} + +var pp$6 = Parser.prototype + +pp$6.initialContext = function() { + return [types.b_stat] +} + +pp$6.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + var parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp$6.updateContext = function(prevType) { + var update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} + +// Token-specific context update code + +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return + } + var out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] +}; + +// ## Tokenizer + +var pp$7 = Parser.prototype + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp$7.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp$7.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp$7[Symbol.iterator] = function () { + var self = this + return {next: function () { + var token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} + } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$7.curContext = function() { + return this.context[this.context.length - 1] +} + +// Read a single token, updating the parser object's token-related +// properties. + +pp$7.nextToken = function() { + var curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() + + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) + + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} + +pp$7.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() + + return this.getTokenFromCode(code) +} + +pp$7.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + var next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} + +pp$7.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition() + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + var match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine + this$1.lineStart = match.index + match[0].length + } + } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} + +pp$7.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos + var startLoc = this.options.onComment && this.curPosition() + var ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this$1.pos + ch = this$1.input.charCodeAt(this$1.pos) + } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$7.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos + } + case 10: case 8232: case 8233: + ++this$1.pos + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment() + break + case 47: + this$1.skipLineComment(2) + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos + } else { + break loop + } + } + } +} + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$7.finishToken = function(type, val) { + this.end = this.pos + if (this.options.locations) this.endLoc = this.curPosition() + var prevType = this.type + this.type = type + this.value = val + + this.updateContext(prevType) +} + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$7.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1) + if (next >= 48 && next <= 57) return this.readNumber(true) + var next2 = this.input.charCodeAt(this.pos + 2) + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3 + return this.finishToken(tt.ellipsis) + } else { + ++this.pos + return this.finishToken(tt.dot) + } +} + +pp$7.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1) + if (this.exprAllowed) {++this.pos; return this.readRegexp()} + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.slash, 1) +} + +pp$7.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + var tokentype = code === 42 ? tt.star : tt.modulo + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && next === 42) { + ++size + tokentype = tt.starstar + next = this.input.charCodeAt(this.pos + 2) + } + + if (next === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tokentype, size) +} + +pp$7.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) +} + +pp$7.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.bitwiseXOR, 1) +} + +pp$7.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) { + if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && + lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { + // A `-->` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `<!--`, an XML-style comment that should be interpreted as a line comment + this.skipLineComment(4) + this.skipSpace() + return this.nextToken() + } + if (next === 61) size = 2 + return this.finishOp(tt.relational, size) +} + +pp$7.readToken_eq_excl = function(code) { // '=!' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) + if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>' + this.pos += 2 + return this.finishToken(tt.arrow) + } + return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1) +} + +pp$7.getTokenFromCode = function(code) { + switch (code) { + // The interpretation of a dot depends on whether it is followed + // by a digit or another two dots. + case 46: // '.' + return this.readToken_dot() + + // Punctuation tokens. + case 40: ++this.pos; return this.finishToken(tt.parenL) + case 41: ++this.pos; return this.finishToken(tt.parenR) + case 59: ++this.pos; return this.finishToken(tt.semi) + case 44: ++this.pos; return this.finishToken(tt.comma) + case 91: ++this.pos; return this.finishToken(tt.bracketL) + case 93: ++this.pos; return this.finishToken(tt.bracketR) + case 123: ++this.pos; return this.finishToken(tt.braceL) + case 125: ++this.pos; return this.finishToken(tt.braceR) + case 58: ++this.pos; return this.finishToken(tt.colon) + case 63: ++this.pos; return this.finishToken(tt.question) + + case 96: // '`' + if (this.options.ecmaVersion < 6) break + ++this.pos + return this.finishToken(tt.backQuote) + + case 48: // '0' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 120 || next === 88) return this.readRadixNumber(16) // '0x', '0X' - hex number + if (this.options.ecmaVersion >= 6) { + if (next === 111 || next === 79) return this.readRadixNumber(8) // '0o', '0O' - octal number + if (next === 98 || next === 66) return this.readRadixNumber(2) // '0b', '0B' - binary number + } + // Anything else beginning with a digit is an integer, octal + // number, or float. + case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 + return this.readNumber(false) + + // Quotes produce strings. + case 34: case 39: // '"', "'" + return this.readString(code) + + // Operators are parsed inline in tiny state machines. '=' (61) is + // often referred to. `finishOp` simply skips the amount of + // characters it is given as second argument, and returns a token + // of the type given by its first argument. + + case 47: // '/' + return this.readToken_slash() + + case 37: case 42: // '%*' + return this.readToken_mult_modulo_exp(code) + + case 124: case 38: // '|&' + return this.readToken_pipe_amp(code) + + case 94: // '^' + return this.readToken_caret() + + case 43: case 45: // '+-' + return this.readToken_plus_min(code) + + case 60: case 62: // '<>' + return this.readToken_lt_gt(code) + + case 61: case 33: // '=!' + return this.readToken_eq_excl(code) + + case 126: // '~' + return this.finishOp(tt.prefix, 1) + } + + this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'") +} + +pp$7.finishOp = function(type, size) { + var str = this.input.slice(this.pos, this.pos + size) + this.pos += size + return this.finishToken(type, str) +} + +// Parse a regular expression. Some context-awareness is necessary, +// since a '/' inside a '[]' set does not end the expression. + +function tryCreateRegexp(src, flags, throwErrorAt, parser) { + try { + return new RegExp(src, flags) + } catch (e) { + if (throwErrorAt !== undefined) { + if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message) + throw e + } + } +} + +var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u") + +pp$7.readRegexp = function() { + var this$1 = this; + + var escaped, inClass, start = this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(start, "Unterminated regular expression") + var ch = this$1.input.charAt(this$1.pos) + if (lineBreak.test(ch)) this$1.raise(start, "Unterminated regular expression") + if (!escaped) { + if (ch === "[") inClass = true + else if (ch === "]" && inClass) inClass = false + else if (ch === "/" && !inClass) break + escaped = ch === "\\" + } else escaped = false + ++this$1.pos + } + var content = this.input.slice(start, this.pos) + ++this.pos + // Need to use `readWord1` because '\uXXXX' sequences are allowed + // here (don't ask). + var mods = this.readWord1() + var tmp = content, tmpFlags = "" + if (mods) { + var validFlags = /^[gim]*$/ + if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/ + if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag") + if (mods.indexOf("u") >= 0) { + if (regexpUnicodeSupport) { + tmpFlags = "u" + } else { + // Replace each astral symbol and every Unicode escape sequence that + // possibly represents an astral symbol or a paired surrogate with a + // single ASCII symbol to avoid throwing on regular expressions that + // are only valid in combination with the `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it would + // be replaced by `[x-b]` which throws an error. + tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) { + code = Number("0x" + code) + if (code > 0x10FFFF) this$1.raise(start + offset + 3, "Code point out of bounds") + return "x" + }) + tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x") + tmpFlags = tmpFlags.replace("u", "") + } + } + } + // Detect invalid regular expressions. + var value = null + // Rhino's regular expression parser is flaky and throws uncatchable exceptions, + // so don't do detection if we are running under Rhino + if (!isRhino) { + tryCreateRegexp(tmp, tmpFlags, start, this) + // Get a regular expression object for this pattern-flag pair, or `null` in + // case the current environment doesn't support the flags it uses. + value = tryCreateRegexp(content, mods) + } + return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value}) +} + +// Read an integer in the given radix. Return null if zero digits +// were read, the integer value otherwise. When `len` is given, this +// will return `null` unless the integer has exactly `len` digits. + +pp$7.readInt = function(radix, len) { + var this$1 = this; + + var start = this.pos, total = 0 + for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { + var code = this$1.input.charCodeAt(this$1.pos), val + if (code >= 97) val = code - 97 + 10 // a + else if (code >= 65) val = code - 65 + 10 // A + else if (code >= 48 && code <= 57) val = code - 48 // 0-9 + else val = Infinity + if (val >= radix) break + ++this$1.pos + total = total * radix + val + } + if (this.pos === start || len != null && this.pos - start !== len) return null + + return total +} + +pp$7.readRadixNumber = function(radix) { + this.pos += 2 // 0x + var val = this.readInt(radix) + if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix) + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + return this.finishToken(tt.num, val) +} + +// Read an integer, octal integer, or floating-point number. + +pp$7.readNumber = function(startsWithDot) { + var start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48 + if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number") + if (octal && this.pos == start + 1) octal = false + var next = this.input.charCodeAt(this.pos) + if (next === 46 && !octal) { // '.' + ++this.pos + this.readInt(10) + isFloat = true + next = this.input.charCodeAt(this.pos) + } + if ((next === 69 || next === 101) && !octal) { // 'eE' + next = this.input.charCodeAt(++this.pos) + if (next === 43 || next === 45) ++this.pos // '+-' + if (this.readInt(10) === null) this.raise(start, "Invalid number") + isFloat = true + } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + + var str = this.input.slice(start, this.pos), val + if (isFloat) val = parseFloat(str) + else if (!octal || str.length === 1) val = parseInt(str, 10) + else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number") + else val = parseInt(str, 8) + return this.finishToken(tt.num, val) +} + +// Read a string value, interpreting backslash-escapes. + +pp$7.readCodePoint = function() { + var ch = this.input.charCodeAt(this.pos), code + + if (ch === 123) { + if (this.options.ecmaVersion < 6) this.unexpected() + var codePos = ++this.pos + code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos) + ++this.pos + if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds") + } else { + code = this.readHexChar(4) + } + return code +} + +function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) return String.fromCharCode(code) + code -= 0x10000 + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) +} + +pp$7.readString = function(quote) { + var this$1 = this; + + var out = "", chunkStart = ++this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated string constant") + var ch = this$1.input.charCodeAt(this$1.pos) + if (ch === quote) break + if (ch === 92) { // '\' + out += this$1.input.slice(chunkStart, this$1.pos) + out += this$1.readEscapedChar(false) + chunkStart = this$1.pos + } else { + if (isNewLine(ch)) this$1.raise(this$1.start, "Unterminated string constant") + ++this$1.pos + } + } + out += this.input.slice(chunkStart, this.pos++) + return this.finishToken(tt.string, out) +} + +// Reads template string tokens. + +pp$7.readTmplToken = function() { + var this$1 = this; + + var out = "", chunkStart = this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated template") + var ch = this$1.input.charCodeAt(this$1.pos) + if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { // '`', '${' + if (this$1.pos === this$1.start && this$1.type === tt.template) { + if (ch === 36) { + this$1.pos += 2 + return this$1.finishToken(tt.dollarBraceL) + } else { + ++this$1.pos + return this$1.finishToken(tt.backQuote) + } + } + out += this$1.input.slice(chunkStart, this$1.pos) + return this$1.finishToken(tt.template, out) + } + if (ch === 92) { // '\' + out += this$1.input.slice(chunkStart, this$1.pos) + out += this$1.readEscapedChar(true) + chunkStart = this$1.pos + } else if (isNewLine(ch)) { + out += this$1.input.slice(chunkStart, this$1.pos) + ++this$1.pos + switch (ch) { + case 13: + if (this$1.input.charCodeAt(this$1.pos) === 10) ++this$1.pos + case 10: + out += "\n" + break + default: + out += String.fromCharCode(ch) + break + } + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + chunkStart = this$1.pos + } else { + ++this$1.pos + } + } +} + +// Used to read escaped characters + +pp$7.readEscapedChar = function(inTemplate) { + var ch = this.input.charCodeAt(++this.pos) + ++this.pos + switch (ch) { + case 110: return "\n" // 'n' -> '\n' + case 114: return "\r" // 'r' -> '\r' + case 120: return String.fromCharCode(this.readHexChar(2)) // 'x' + case 117: return codePointToString(this.readCodePoint()) // 'u' + case 116: return "\t" // 't' -> '\t' + case 98: return "\b" // 'b' -> '\b' + case 118: return "\u000b" // 'v' -> '\u000b' + case 102: return "\f" // 'f' -> '\f' + case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos // '\r\n' + case 10: // ' \n' + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine } + return "" + default: + if (ch >= 48 && ch <= 55) { + var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0] + var octal = parseInt(octalStr, 8) + if (octal > 255) { + octalStr = octalStr.slice(0, -1) + octal = parseInt(octalStr, 8) + } + if (octalStr !== "0" && (this.strict || inTemplate)) { + this.raise(this.pos - 2, "Octal literal in strict mode") + } + this.pos += octalStr.length - 1 + return String.fromCharCode(octal) + } + return String.fromCharCode(ch) + } +} + +// Used to read character escape sequences ('\x', '\u', '\U'). + +pp$7.readHexChar = function(len) { + var codePos = this.pos + var n = this.readInt(16, len) + if (n === null) this.raise(codePos, "Bad character escape sequence") + return n +} + +// Read an identifier, and return it as a string. Sets `this.containsEsc` +// to whether the word contained a '\u' escape. +// +// Incrementally adds only escaped chars, adding other chunks as-is +// as a micro-optimization. + +pp$7.readWord1 = function() { + var this$1 = this; + + this.containsEsc = false + var word = "", first = true, chunkStart = this.pos + var astral = this.options.ecmaVersion >= 6 + while (this.pos < this.input.length) { + var ch = this$1.fullCharCodeAtPos() + if (isIdentifierChar(ch, astral)) { + this$1.pos += ch <= 0xffff ? 1 : 2 + } else if (ch === 92) { // "\" + this$1.containsEsc = true + word += this$1.input.slice(chunkStart, this$1.pos) + var escStart = this$1.pos + if (this$1.input.charCodeAt(++this$1.pos) != 117) // "u" + this$1.raise(this$1.pos, "Expecting Unicode escape sequence \\uXXXX") + ++this$1.pos + var esc = this$1.readCodePoint() + if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) + this$1.raise(escStart, "Invalid Unicode escape") + word += codePointToString(esc) + chunkStart = this$1.pos + } else { + break + } + first = false + } + return word + this.input.slice(chunkStart, this.pos) +} + +// Read an identifier or keyword token. Will check for reserved +// words when necessary. + +pp$7.readWord = function() { + var word = this.readWord1() + var type = tt.name + if (this.keywords.test(word)) { + if (this.containsEsc) this.raiseRecoverable(this.start, "Escape sequence in keyword " + word) + type = keywordTypes[word] + } + return this.finishToken(type, word) +} + +// Acorn is a tiny, fast JavaScript parser written in JavaScript. +// +// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and +// various contributors and released under an MIT license. +// +// Git repositories for Acorn are available at +// +// http://marijnhaverbeke.nl/git/acorn +// https://github.com/ternjs/acorn.git +// +// Please use the [github bug tracker][ghbt] to report issues. +// +// [ghbt]: https://github.com/ternjs/acorn/issues +// +// This file defines the main parser interface. The library also comes +// with a [error-tolerant parser][dammit] and an +// [abstract syntax tree walker][walk], defined in other files. +// +// [dammit]: acorn_loose.js +// [walk]: util/walk.js + +var version = "4.0.11" + +// The main exported interface (under `self.acorn` when in the +// browser) is a `parse` function that takes a code string and +// returns an abstract syntax tree as specified by [Mozilla parser +// API][api]. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + +function parse(input, options) { + return new Parser(options, input).parse() +} + +// This function tries to parse a single expression at a given +// offset in a string. Useful for parsing mixed-language formats +// that embed JavaScript expressions. + +function parseExpressionAt(input, pos, options) { + var p = new Parser(options, input, pos) + p.nextToken() + return p.parseExpression() +} + +// Acorn is organized as a tokenizer and a recursive-descent parser. +// The `tokenizer` export provides an interface to the tokenizer. + +function tokenizer(input, options) { + return new Parser(options, input) +} + +// This is a terrible kludge to support the existing, pre-ES6 +// interface where the loose parser module retroactively adds exports +// to this module. +function addLooseExports(parse, Parser, plugins) { + parse_dammit = parse + LooseParser = Parser + pluginsLoose = plugins +} + +export { version, parse, parseExpressionAt, tokenizer, parse_dammit, LooseParser, pluginsLoose, addLooseExports, Parser, plugins, defaultOptions, Position, SourceLocation, getLineInfo, Node, TokenType, tt as tokTypes, keywordTypes, TokContext, types as tokContexts, isIdentifierChar, isIdentifierStart, Token, isNewLine, lineBreak, lineBreakG };
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.js new file mode 100644 index 000000000..d41050002 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.js @@ -0,0 +1,3433 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.acorn = global.acorn || {}))); +}(this, (function (exports) { 'use strict'; + +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000 + for (var i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; +// Map keyword names to token types. + +var keywordTypes = {} + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name + return keywordTypes[name] = new TokenType(name, options) +} + +var tt = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("</>", 7), + bitShift: binop("<</>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/ +var lineBreakG = new RegExp(lineBreak.source, "g") + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g + +function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line + this.column = col +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + var match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +function getOptions(opts) { + var options = {} + + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + + if (options.ecmaVersion >= 2015) + options.ecmaVersion -= 2009 + + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + var tokens = options.onToken + options.onToken = function (token) { return tokens.push(token); } + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + +// Registered plugins +var plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + var reserved = "" + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + if (reserved = reservedWords[v]) break + if (options.sourceType == "module") reserved += " await" + } + this.reservedWords = keywordRegexp(reserved) + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1 + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module" + this.strict = this.inModule || this.strictDirective(this.pos) + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0 + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) +}; + +var pp = Parser.prototype + +// ## Parser utilities + +var literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/ +pp.strictDirective = function(start) { + var this$1 = this; + + for (;;) { + skipWhiteSpace.lastIndex = start + start += skipWhiteSpace.exec(this$1.input)[0].length + var match = literal.exec(this$1.input.slice(start)) + if (!match) return false + if ((match[1] || match[2]) == "use strict") return true + start += match[0].length + } +} + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false + } +} + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true + } +} + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} + +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + if (!notNext) + this.next() + return true + } +} + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} + +var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1 +}; + +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) return + if (refDestructuringErrors.trailingComma > -1) + this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element") + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind + if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern") +} + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + var pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1 + if (!andThrow) return pos >= 0 + if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} + +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + this.raise(this.yieldPos, "Yield expression cannot be a default value") + if (this.awaitPos) + this.raise(this.awaitPos, "Await expression cannot be a default value") +} + +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + return this.isSimpleAssignTarget(expr.expression) + return expr.type === "Identifier" || expr.type === "MemberExpression" +} + +var pp$1 = Parser.prototype + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var this$1 = this; + + var exports = {} + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + var stmt = this$1.parseStatement(true, true, exports) + node.body.push(stmt) + } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; +pp$1.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + var ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async") + return false + + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node, false) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction() && declaration) { + this.next() + return this.parseFunctionStatement(node, true) + } + + var maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) + } +} + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() + } + + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + var lab = this$1.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp$1.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp$1.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + var isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init$1, true, kind) + this.finishNode(init$1, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) + return this.parseForIn(node, init$1) + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors + var init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.toAssignable(init) + this.checkLVal(init) + this.checkPatternErrors(refDestructuringErrors, true) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp$1.parseFunctionStatement = function(node, isAsync) { + this.next() + return this.parseFunction(node, true, false, isAsync) +} + +pp$1.isFunction = function() { + return this.type === tt._function || this.isAsyncFunction() +} + +pp$1.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.isFunction()) + node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null + return this.finishNode(node, "IfStatement") +} + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this$1.type === tt._case || this$1.type === tt._default) { + var isCase = this$1.type === tt._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) { + cur.test = this$1.parseExpression() + } else { + if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this$1.expect(tt.colon) + } else { + if (!cur) this$1.unexpected() + cur.consequent.push(this$1.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp$1.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +var empty = [] + +pp$1.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + var clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp$1.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp$1.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp$1.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp$1.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i = 0; i < this.labels.length; ++i) + if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") + var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { + var label = this$1.labels[i$1] + if (label.statementStart == node.start) { + label.statementStart = this$1.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + if (node.body.type == "ClassDeclaration" || + node.body.type == "VariableDeclaration" && (this.strict || node.body.kind != "var") || + node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) + this.raiseRecoverable(node.body.start, "Invalid labeled declaration") + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function() { + var this$1 = this; + + var node = this.startNode() + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + var stmt = this$1.parseStatement(true) + node.body.push(stmt) + } + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = [] + node.kind = kind + for (;;) { + var decl = this$1.startNode() + this$1.parseVarId(decl) + if (this$1.eat(tt.eq)) { + decl.init = this$1.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + if (!this$1.eat(tt.comma)) break + } + return node +} + +pp$1.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6 && !isAsync) + node.generator = this.eat(tt.star) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + if (isStatement == null) + isStatement = this.type == tt.name + if (isStatement) + node.id = this.parseIdent() + + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + if (!isStatement && this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp$1.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true) + this.checkYieldAwaitInDefaultParams() +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next() + if (isStatement == null) isStatement = this.type === tt.name + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + var classBody = this.startNode() + var hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this$1.eat(tt.semi)) continue + var method = this$1.startNode() + var isGenerator = this$1.eat(tt.star) + var isAsync = false + var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" + this$1.parsePropertyName(method) + method.static = isMaybeStatic && this$1.type !== tt.parenL + if (method.static) { + if (isGenerator) this$1.unexpected() + isGenerator = this$1.eat(tt.star) + this$1.parsePropertyName(method) + } + if (this$1.options.ecmaVersion >= 8 && !isGenerator && !method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this$1.type !== tt.parenL && + !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(method) + } + method.kind = "method" + var isGetSet = false + if (!method.computed) { + var key = method.key; + if (!isGenerator && !isAsync && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this$1.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") + if (isAsync) this$1.raise(key.start, "Constructor can't be an async method") + method.kind = "constructor" + hadConstructor = true + } + } + this$1.parseClassMethod(classBody, method, isGenerator, isAsync) + if (isGetSet) { + var paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + var start = method.value.start + if (method.kind === "get") + this$1.raiseRecoverable(start, "getter should have no params") + else + this$1.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this$1.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params") + } + } + } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} + +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} + +// Parses module export declaration. + +pp$1.parseExport = function(node, exports) { + var this$1 = this; + + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart) + var isAsync + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, false, isAsync) + } else if (this.type === tt._class) { + var cNode = this.startNode() + node.declaration = this.parseClass(cNode, null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + if (node.declaration.type === "VariableDeclaration") + this.checkVariableExport(exports, node.declaration.declarations) + else + this.checkExport(exports, node.declaration.id.name, node.declaration.id.start) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers(exports) + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (var i = 0; i < node.specifiers.length; i++) { + if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { + this$1.unexpected(node.specifiers[i].local.start) + } + } + + node.source = null + } + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp$1.checkExport = function(exports, name, pos) { + if (!exports) return + if (Object.prototype.hasOwnProperty.call(exports, name)) + this.raiseRecoverable(pos, "Duplicate export '" + name + "'") + exports[name] = true +} + +pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; + + var type = pat.type + if (type == "Identifier") + this.checkExport(exports, pat.name, pat.start) + else if (type == "ObjectPattern") + for (var i = 0; i < pat.properties.length; ++i) + this$1.checkPatternExport(exports, pat.properties[i].value) + else if (type == "ArrayPattern") + for (var i$1 = 0; i$1 < pat.elements.length; ++i$1) { + var elt = pat.elements[i$1] + if (elt) this$1.checkPatternExport(exports, elt) + } + else if (type == "AssignmentPattern") + this.checkPatternExport(exports, pat.left) + else if (type == "ParenthesizedExpression") + this.checkPatternExport(exports, pat.expression) +} + +pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; + + if (!exports) return + for (var i = 0; i < decls.length; i++) + this$1.checkPatternExport(exports, decls[i].id) +} + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" + || this.type.keyword === "const" + || this.type.keyword === "class" + || this.type.keyword === "function" + || this.isLet() + || this.isAsyncFunction() +} + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + + var nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node = this$1.startNode() + node.local = this$1.parseIdent(true) + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local + this$1.checkExport(exports, node.exported.name, node.exported.start) + nodes.push(this$1.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + var node$1 = this.startNode() + this.next() + this.expectContextual("as") + node$1.local = this.parseIdent() + this.checkLVal(node$1.local, true) + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node$2 = this$1.startNode() + node$2.imported = this$1.parseIdent(true) + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent() + } else { + node$2.local = node$2.imported + if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) + if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raiseRecoverable(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") + } + this$1.checkLVal(node$2.local, true) + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) + } + return nodes +} + +var pp$2 = Parser.prototype + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding) { + var this$1 = this; + + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + this.raise(node.start, "Can not use 'await' as identifier inside an async function") + break + + case "ObjectPattern": + case "ArrayPattern": + break + + case "ObjectExpression": + node.type = "ObjectPattern" + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i] + if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") + this$1.toAssignable(prop.value, isBinding) + } + break + + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + this.toAssignable(node.left, isBinding) + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break + + case "MemberExpression": + if (!isBinding) break + + default: + this.raise(node.start, "Assigning to rvalue") + } + } + return node +} + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length + if (end) { + var last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + var arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (var i = 0; i < end; i++) { + var elt = exprList[i] + if (elt) this$1.toAssignable(elt, isBinding) + } + return exprList +} + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} + +pp$2.parseRest = function(allowNonIdent) { + var node = this.startNode() + this.next() + + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() + + return this.finishNode(node, "RestElement") +} + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() + + case tt.bracketL: + var node = this.startNode() + this.next() + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") + + case tt.braceL: + return this.parseObj(true) + + default: + this.unexpected() + } +} + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this$1.expect(tt.comma) + if (allowEmpty && this$1.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === tt.ellipsis) { + var rest = this$1.parseRest(allowNonIdent) + this$1.parseBindingListItem(rest) + elts.push(rest) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + this$1.expect(close) + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) + this$1.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp$2.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp$2.checkLVal = function(expr, isBinding, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (var i = 0; i < expr.properties.length; i++) + this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { + var elem = expr.elements[i$1] + if (elem) this$1.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} + +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + +var pp$3 = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + var key = prop.key; + var name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + var other = propHash[name] + if (other) { + var isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + var node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + var ownDestructuringErrors = false, oldParenAssign = -1 + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign + refDestructuringErrors.parenthesizedAssign = -1 + } else { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + + var startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + var left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + var node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = -1 // reset because shorthand default was used correctly + this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) + } + if (oldParenAssign > -1) refDestructuringErrors.parenthesizedAssign = oldParenAssign + return left +} + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + var node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + var logical = this.type === tt.logicalOR || this.type === tt.logicalAND + var op = this.value + this.next() + var startPos = this.start, startLoc = this.startLoc + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr + if (this.inAsync && this.isContextual("await")) { + expr = this.parseAwait(refDestructuringErrors) + sawUnary = true + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.operator = this$1.value + node$1.prefix = false + node$1.argument = expr + this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$1, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprAtom(refDestructuringErrors) + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + var result = this.parseSubscripts(expr, startPos, startLoc) + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) refDestructuringErrors.parenthesizedAssign = -1 + if (refDestructuringErrors.parenthesizedBind >= result.start) refDestructuringErrors.parenthesizedBind = -1 + } + return result +} + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd == base.end && !this.canInsertSemicolon() + for (var computed;;) { + if ((computed = this$1.eat(tt.bracketL)) || this$1.eat(tt.dot)) { + var node = this$1.startNodeAt(startPos, startLoc) + node.object = base + node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true) + node.computed = !!computed + if (computed) this$1.expect(tt.bracketR) + base = this$1.finishNode(node, "MemberExpression") + } else if (!noCalls && this$1.eat(tt.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos + this$1.yieldPos = 0 + this$1.awaitPos = 0 + var exprList = this$1.parseExprList(tt.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors) + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(tt.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, false) + this$1.checkYieldAwaitInDefaultParams() + this$1.yieldPos = oldYieldPos + this$1.awaitPos = oldAwaitPos + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true) + this$1.yieldPos = oldYieldPos || this$1.yieldPos + this$1.awaitPos = oldAwaitPos || this$1.awaitPos + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.callee = base + node$1.arguments = exprList + base = this$1.finishNode(node$1, "CallExpression") + } else if (this$1.type === tt.backQuote) { + var node$2 = this$1.startNodeAt(startPos, startLoc) + node$2.tag = base + node$2.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$2, "TaggedTemplateExpression") + } else { + return base + } + } +} + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") + + case tt._this: + var type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + var startPos = this.start, startLoc = this.startLoc + var id = this.parseIdent(this.type !== tt.name) + if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) + return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) { + id = this.parseIdent() + if (this.canInsertSemicolon() || !this.eat(tt.arrow)) + this.unexpected() + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + + case tt.regexp: + var value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node + + case tt.num: case tt.string: + return this.parseLiteral(this.value) + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow) + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + refDestructuringErrors.parenthesizedAssign = start + if (refDestructuringErrors.parenthesizedBind < 0) + refDestructuringErrors.parenthesizedBind = start + } + return expr + + case tt.bracketL: + node = this.startNode() + this.next() + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._class: + return this.parseClass(this.startNode(), false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + this.unexpected() + } +} + +pp$3.parseLiteral = function(value) { + var node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} + +pp$3.parseParenExpression = function() { + this.expect(tt.parenL) + var val = this.parseExpression() + this.expect(tt.parenR) + return val +} + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8 + if (this.options.ecmaVersion >= 6) { + this.next() + + var innerStartPos = this.start, innerStartLoc = this.startLoc + var exprList = [], first = true, lastIsComma = false + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart + this.yieldPos = 0 + this.awaitPos = 0 + while (this.type !== tt.parenR) { + first ? first = false : this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(tt.parenR, true)) { + lastIsComma = true + break + } else if (this$1.type === tt.ellipsis) { + spreadStart = this$1.start + exprList.push(this$1.parseParenItem(this$1.parseRest())) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + break + } else { + if (this$1.type === tt.parenL && !innerParenStart) { + innerParenStart = this$1.start + } + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false) + this.checkYieldAwaitInDefaultParams() + if (innerParenStart) this.unexpected(innerParenStart) + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + this.yieldPos = oldYieldPos || this.yieldPos + this.awaitPos = oldAwaitPos || this.awaitPos + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] + } + } else { + val = this.parseParenExpression() + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +} + +pp$3.parseParenItem = function(item) { + return item +} + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = [] + +pp$3.parseNew = function() { + var node = this.startNode() + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) + else node.arguments = empty$1 + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp$3.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp$3.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.expect(tt.dollarBraceL) + node.expressions.push(this$1.parseExpression()) + this$1.expect(tt.braceR) + node.quasis.push(curElt = this$1.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var prop = this$1.startNode(), isGenerator, isAsync, startPos, startLoc + if (this$1.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this$1.start + startLoc = this$1.startLoc + } + if (!isPattern) + isGenerator = this$1.eat(tt.star) + } + this$1.parsePropertyName(prop) + if (!isPattern && this$1.options.ecmaVersion >= 8 && !isGenerator && !prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this$1.type !== tt.parenL && + this$1.type !== tt.colon && !this$1.canInsertSemicolon()) { + isAsync = true + this$1.parsePropertyName(prop, refDestructuringErrors) + } else { + isAsync = false + } + this$1.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) + this$1.checkPropClash(prop, propHash) + node.properties.push(this$1.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { + if ((isGenerator || isAsync) && this.type === tt.colon) + this.unexpected() + + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator, isAsync) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isAsync || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + var paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + var start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield") || + (this.inAsync && prop.key.name == "await")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8) + this.checkYieldAwaitInDefaultParams() + this.parseFunctionBody(node, false) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = false + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== tt.braceL + var oldStrict = this.strict, useStrict = false + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params) + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end) + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list") + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels + this.labels = [] + if (useStrict) this.strict = true + node.body = this.parseBlock(true) + node.expression = false + this.labels = oldLabels + } + + if (oldStrict || useStrict) { + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node) + this.strict = oldStrict + } else if (isArrowFunction || !this.isSimpleParamList(node.params)) { + this.checkParams(node) + } +} + +pp$3.isSimpleParamList = function(params) { + for (var i = 0; i < params.length; i++) + if (params[i].type !== "Identifier") return false + return true +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node) { + var this$1 = this; + + var nameHash = {} + for (var i = 0; i < node.params.length; i++) this$1.checkLVal(node.params[i], true, nameHash) +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(close)) break + } else first = false + + var elt + if (allowEmpty && this$1.type === tt.comma) + elt = null + else if (this$1.type === tt.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors) + if (refDestructuringErrors && this$1.type === tt.comma && refDestructuringErrors.trailingComma < 0) + refDestructuringErrors.trailingComma = this$1.start + } else { + elt = this$1.parseMaybeAssign(false, refDestructuringErrors) + } + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal) { + var node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + if (this.inAsync && this.value === "await") + this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + if (!this.yieldPos) this.yieldPos = this.start + + var node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +pp$3.parseAwait = function() { + if (!this.awaitPos) this.awaitPos = this.start + + var node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary(null, true) + return this.finishNode(node, "AwaitExpression") +} + +var pp$4 = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + var err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp$4.raiseRecoverable = pp$4.raise + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} + +var Node = function Node(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] +}; + +// Start an AST node, attaching a start offset. + +var pp$5 = Parser.prototype + +pp$5.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp$5.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp$5.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp$5.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} + +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override +}; + +var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), + f_expr: new TokContext("function", true) +} + +var pp$6 = Parser.prototype + +pp$6.initialContext = function() { + return [types.b_stat] +} + +pp$6.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + var parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp$6.updateContext = function(prevType) { + var update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} + +// Token-specific context update code + +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return + } + var out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] +}; + +// ## Tokenizer + +var pp$7 = Parser.prototype + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp$7.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp$7.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp$7[Symbol.iterator] = function () { + var self = this + return {next: function () { + var token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} + } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$7.curContext = function() { + return this.context[this.context.length - 1] +} + +// Read a single token, updating the parser object's token-related +// properties. + +pp$7.nextToken = function() { + var curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() + + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) + + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} + +pp$7.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() + + return this.getTokenFromCode(code) +} + +pp$7.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + var next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} + +pp$7.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition() + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + var match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine + this$1.lineStart = match.index + match[0].length + } + } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} + +pp$7.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos + var startLoc = this.options.onComment && this.curPosition() + var ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this$1.pos + ch = this$1.input.charCodeAt(this$1.pos) + } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$7.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos + } + case 10: case 8232: case 8233: + ++this$1.pos + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment() + break + case 47: + this$1.skipLineComment(2) + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos + } else { + break loop + } + } + } +} + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$7.finishToken = function(type, val) { + this.end = this.pos + if (this.options.locations) this.endLoc = this.curPosition() + var prevType = this.type + this.type = type + this.value = val + + this.updateContext(prevType) +} + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$7.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1) + if (next >= 48 && next <= 57) return this.readNumber(true) + var next2 = this.input.charCodeAt(this.pos + 2) + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3 + return this.finishToken(tt.ellipsis) + } else { + ++this.pos + return this.finishToken(tt.dot) + } +} + +pp$7.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1) + if (this.exprAllowed) {++this.pos; return this.readRegexp()} + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.slash, 1) +} + +pp$7.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + var tokentype = code === 42 ? tt.star : tt.modulo + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && next === 42) { + ++size + tokentype = tt.starstar + next = this.input.charCodeAt(this.pos + 2) + } + + if (next === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tokentype, size) +} + +pp$7.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) +} + +pp$7.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.bitwiseXOR, 1) +} + +pp$7.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) { + if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && + lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { + // A `-->` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `<!--`, an XML-style comment that should be interpreted as a line comment + this.skipLineComment(4) + this.skipSpace() + return this.nextToken() + } + if (next === 61) size = 2 + return this.finishOp(tt.relational, size) +} + +pp$7.readToken_eq_excl = function(code) { // '=!' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) + if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>' + this.pos += 2 + return this.finishToken(tt.arrow) + } + return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1) +} + +pp$7.getTokenFromCode = function(code) { + switch (code) { + // The interpretation of a dot depends on whether it is followed + // by a digit or another two dots. + case 46: // '.' + return this.readToken_dot() + + // Punctuation tokens. + case 40: ++this.pos; return this.finishToken(tt.parenL) + case 41: ++this.pos; return this.finishToken(tt.parenR) + case 59: ++this.pos; return this.finishToken(tt.semi) + case 44: ++this.pos; return this.finishToken(tt.comma) + case 91: ++this.pos; return this.finishToken(tt.bracketL) + case 93: ++this.pos; return this.finishToken(tt.bracketR) + case 123: ++this.pos; return this.finishToken(tt.braceL) + case 125: ++this.pos; return this.finishToken(tt.braceR) + case 58: ++this.pos; return this.finishToken(tt.colon) + case 63: ++this.pos; return this.finishToken(tt.question) + + case 96: // '`' + if (this.options.ecmaVersion < 6) break + ++this.pos + return this.finishToken(tt.backQuote) + + case 48: // '0' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 120 || next === 88) return this.readRadixNumber(16) // '0x', '0X' - hex number + if (this.options.ecmaVersion >= 6) { + if (next === 111 || next === 79) return this.readRadixNumber(8) // '0o', '0O' - octal number + if (next === 98 || next === 66) return this.readRadixNumber(2) // '0b', '0B' - binary number + } + // Anything else beginning with a digit is an integer, octal + // number, or float. + case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 + return this.readNumber(false) + + // Quotes produce strings. + case 34: case 39: // '"', "'" + return this.readString(code) + + // Operators are parsed inline in tiny state machines. '=' (61) is + // often referred to. `finishOp` simply skips the amount of + // characters it is given as second argument, and returns a token + // of the type given by its first argument. + + case 47: // '/' + return this.readToken_slash() + + case 37: case 42: // '%*' + return this.readToken_mult_modulo_exp(code) + + case 124: case 38: // '|&' + return this.readToken_pipe_amp(code) + + case 94: // '^' + return this.readToken_caret() + + case 43: case 45: // '+-' + return this.readToken_plus_min(code) + + case 60: case 62: // '<>' + return this.readToken_lt_gt(code) + + case 61: case 33: // '=!' + return this.readToken_eq_excl(code) + + case 126: // '~' + return this.finishOp(tt.prefix, 1) + } + + this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'") +} + +pp$7.finishOp = function(type, size) { + var str = this.input.slice(this.pos, this.pos + size) + this.pos += size + return this.finishToken(type, str) +} + +// Parse a regular expression. Some context-awareness is necessary, +// since a '/' inside a '[]' set does not end the expression. + +function tryCreateRegexp(src, flags, throwErrorAt, parser) { + try { + return new RegExp(src, flags) + } catch (e) { + if (throwErrorAt !== undefined) { + if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message) + throw e + } + } +} + +var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u") + +pp$7.readRegexp = function() { + var this$1 = this; + + var escaped, inClass, start = this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(start, "Unterminated regular expression") + var ch = this$1.input.charAt(this$1.pos) + if (lineBreak.test(ch)) this$1.raise(start, "Unterminated regular expression") + if (!escaped) { + if (ch === "[") inClass = true + else if (ch === "]" && inClass) inClass = false + else if (ch === "/" && !inClass) break + escaped = ch === "\\" + } else escaped = false + ++this$1.pos + } + var content = this.input.slice(start, this.pos) + ++this.pos + // Need to use `readWord1` because '\uXXXX' sequences are allowed + // here (don't ask). + var mods = this.readWord1() + var tmp = content, tmpFlags = "" + if (mods) { + var validFlags = /^[gim]*$/ + if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/ + if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag") + if (mods.indexOf("u") >= 0) { + if (regexpUnicodeSupport) { + tmpFlags = "u" + } else { + // Replace each astral symbol and every Unicode escape sequence that + // possibly represents an astral symbol or a paired surrogate with a + // single ASCII symbol to avoid throwing on regular expressions that + // are only valid in combination with the `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it would + // be replaced by `[x-b]` which throws an error. + tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (_match, code, offset) { + code = Number("0x" + code) + if (code > 0x10FFFF) this$1.raise(start + offset + 3, "Code point out of bounds") + return "x" + }) + tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x") + tmpFlags = tmpFlags.replace("u", "") + } + } + } + // Detect invalid regular expressions. + var value = null + // Rhino's regular expression parser is flaky and throws uncatchable exceptions, + // so don't do detection if we are running under Rhino + if (!isRhino) { + tryCreateRegexp(tmp, tmpFlags, start, this) + // Get a regular expression object for this pattern-flag pair, or `null` in + // case the current environment doesn't support the flags it uses. + value = tryCreateRegexp(content, mods) + } + return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value}) +} + +// Read an integer in the given radix. Return null if zero digits +// were read, the integer value otherwise. When `len` is given, this +// will return `null` unless the integer has exactly `len` digits. + +pp$7.readInt = function(radix, len) { + var this$1 = this; + + var start = this.pos, total = 0 + for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { + var code = this$1.input.charCodeAt(this$1.pos), val + if (code >= 97) val = code - 97 + 10 // a + else if (code >= 65) val = code - 65 + 10 // A + else if (code >= 48 && code <= 57) val = code - 48 // 0-9 + else val = Infinity + if (val >= radix) break + ++this$1.pos + total = total * radix + val + } + if (this.pos === start || len != null && this.pos - start !== len) return null + + return total +} + +pp$7.readRadixNumber = function(radix) { + this.pos += 2 // 0x + var val = this.readInt(radix) + if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix) + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + return this.finishToken(tt.num, val) +} + +// Read an integer, octal integer, or floating-point number. + +pp$7.readNumber = function(startsWithDot) { + var start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48 + if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number") + if (octal && this.pos == start + 1) octal = false + var next = this.input.charCodeAt(this.pos) + if (next === 46 && !octal) { // '.' + ++this.pos + this.readInt(10) + isFloat = true + next = this.input.charCodeAt(this.pos) + } + if ((next === 69 || next === 101) && !octal) { // 'eE' + next = this.input.charCodeAt(++this.pos) + if (next === 43 || next === 45) ++this.pos // '+-' + if (this.readInt(10) === null) this.raise(start, "Invalid number") + isFloat = true + } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + + var str = this.input.slice(start, this.pos), val + if (isFloat) val = parseFloat(str) + else if (!octal || str.length === 1) val = parseInt(str, 10) + else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number") + else val = parseInt(str, 8) + return this.finishToken(tt.num, val) +} + +// Read a string value, interpreting backslash-escapes. + +pp$7.readCodePoint = function() { + var ch = this.input.charCodeAt(this.pos), code + + if (ch === 123) { + if (this.options.ecmaVersion < 6) this.unexpected() + var codePos = ++this.pos + code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos) + ++this.pos + if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds") + } else { + code = this.readHexChar(4) + } + return code +} + +function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) return String.fromCharCode(code) + code -= 0x10000 + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) +} + +pp$7.readString = function(quote) { + var this$1 = this; + + var out = "", chunkStart = ++this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated string constant") + var ch = this$1.input.charCodeAt(this$1.pos) + if (ch === quote) break + if (ch === 92) { // '\' + out += this$1.input.slice(chunkStart, this$1.pos) + out += this$1.readEscapedChar(false) + chunkStart = this$1.pos + } else { + if (isNewLine(ch)) this$1.raise(this$1.start, "Unterminated string constant") + ++this$1.pos + } + } + out += this.input.slice(chunkStart, this.pos++) + return this.finishToken(tt.string, out) +} + +// Reads template string tokens. + +pp$7.readTmplToken = function() { + var this$1 = this; + + var out = "", chunkStart = this.pos + for (;;) { + if (this$1.pos >= this$1.input.length) this$1.raise(this$1.start, "Unterminated template") + var ch = this$1.input.charCodeAt(this$1.pos) + if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { // '`', '${' + if (this$1.pos === this$1.start && this$1.type === tt.template) { + if (ch === 36) { + this$1.pos += 2 + return this$1.finishToken(tt.dollarBraceL) + } else { + ++this$1.pos + return this$1.finishToken(tt.backQuote) + } + } + out += this$1.input.slice(chunkStart, this$1.pos) + return this$1.finishToken(tt.template, out) + } + if (ch === 92) { // '\' + out += this$1.input.slice(chunkStart, this$1.pos) + out += this$1.readEscapedChar(true) + chunkStart = this$1.pos + } else if (isNewLine(ch)) { + out += this$1.input.slice(chunkStart, this$1.pos) + ++this$1.pos + switch (ch) { + case 13: + if (this$1.input.charCodeAt(this$1.pos) === 10) ++this$1.pos + case 10: + out += "\n" + break + default: + out += String.fromCharCode(ch) + break + } + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + chunkStart = this$1.pos + } else { + ++this$1.pos + } + } +} + +// Used to read escaped characters + +pp$7.readEscapedChar = function(inTemplate) { + var ch = this.input.charCodeAt(++this.pos) + ++this.pos + switch (ch) { + case 110: return "\n" // 'n' -> '\n' + case 114: return "\r" // 'r' -> '\r' + case 120: return String.fromCharCode(this.readHexChar(2)) // 'x' + case 117: return codePointToString(this.readCodePoint()) // 'u' + case 116: return "\t" // 't' -> '\t' + case 98: return "\b" // 'b' -> '\b' + case 118: return "\u000b" // 'v' -> '\u000b' + case 102: return "\f" // 'f' -> '\f' + case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos // '\r\n' + case 10: // ' \n' + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine } + return "" + default: + if (ch >= 48 && ch <= 55) { + var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0] + var octal = parseInt(octalStr, 8) + if (octal > 255) { + octalStr = octalStr.slice(0, -1) + octal = parseInt(octalStr, 8) + } + if (octalStr !== "0" && (this.strict || inTemplate)) { + this.raise(this.pos - 2, "Octal literal in strict mode") + } + this.pos += octalStr.length - 1 + return String.fromCharCode(octal) + } + return String.fromCharCode(ch) + } +} + +// Used to read character escape sequences ('\x', '\u', '\U'). + +pp$7.readHexChar = function(len) { + var codePos = this.pos + var n = this.readInt(16, len) + if (n === null) this.raise(codePos, "Bad character escape sequence") + return n +} + +// Read an identifier, and return it as a string. Sets `this.containsEsc` +// to whether the word contained a '\u' escape. +// +// Incrementally adds only escaped chars, adding other chunks as-is +// as a micro-optimization. + +pp$7.readWord1 = function() { + var this$1 = this; + + this.containsEsc = false + var word = "", first = true, chunkStart = this.pos + var astral = this.options.ecmaVersion >= 6 + while (this.pos < this.input.length) { + var ch = this$1.fullCharCodeAtPos() + if (isIdentifierChar(ch, astral)) { + this$1.pos += ch <= 0xffff ? 1 : 2 + } else if (ch === 92) { // "\" + this$1.containsEsc = true + word += this$1.input.slice(chunkStart, this$1.pos) + var escStart = this$1.pos + if (this$1.input.charCodeAt(++this$1.pos) != 117) // "u" + this$1.raise(this$1.pos, "Expecting Unicode escape sequence \\uXXXX") + ++this$1.pos + var esc = this$1.readCodePoint() + if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) + this$1.raise(escStart, "Invalid Unicode escape") + word += codePointToString(esc) + chunkStart = this$1.pos + } else { + break + } + first = false + } + return word + this.input.slice(chunkStart, this.pos) +} + +// Read an identifier or keyword token. Will check for reserved +// words when necessary. + +pp$7.readWord = function() { + var word = this.readWord1() + var type = tt.name + if (this.keywords.test(word)) { + if (this.containsEsc) this.raiseRecoverable(this.start, "Escape sequence in keyword " + word) + type = keywordTypes[word] + } + return this.finishToken(type, word) +} + +// Acorn is a tiny, fast JavaScript parser written in JavaScript. +// +// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and +// various contributors and released under an MIT license. +// +// Git repositories for Acorn are available at +// +// http://marijnhaverbeke.nl/git/acorn +// https://github.com/ternjs/acorn.git +// +// Please use the [github bug tracker][ghbt] to report issues. +// +// [ghbt]: https://github.com/ternjs/acorn/issues +// +// This file defines the main parser interface. The library also comes +// with a [error-tolerant parser][dammit] and an +// [abstract syntax tree walker][walk], defined in other files. +// +// [dammit]: acorn_loose.js +// [walk]: util/walk.js + +var version = "4.0.11" + +// The main exported interface (under `self.acorn` when in the +// browser) is a `parse` function that takes a code string and +// returns an abstract syntax tree as specified by [Mozilla parser +// API][api]. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + +function parse(input, options) { + return new Parser(options, input).parse() +} + +// This function tries to parse a single expression at a given +// offset in a string. Useful for parsing mixed-language formats +// that embed JavaScript expressions. + +function parseExpressionAt(input, pos, options) { + var p = new Parser(options, input, pos) + p.nextToken() + return p.parseExpression() +} + +// Acorn is organized as a tokenizer and a recursive-descent parser. +// The `tokenizer` export provides an interface to the tokenizer. + +function tokenizer(input, options) { + return new Parser(options, input) +} + +// This is a terrible kludge to support the existing, pre-ES6 +// interface where the loose parser module retroactively adds exports +// to this module. +function addLooseExports(parse, Parser, plugins) { + exports.parse_dammit = parse + exports.LooseParser = Parser + exports.pluginsLoose = plugins +} + +exports.version = version; +exports.parse = parse; +exports.parseExpressionAt = parseExpressionAt; +exports.tokenizer = tokenizer; +exports.addLooseExports = addLooseExports; +exports.Parser = Parser; +exports.plugins = plugins; +exports.defaultOptions = defaultOptions; +exports.Position = Position; +exports.SourceLocation = SourceLocation; +exports.getLineInfo = getLineInfo; +exports.Node = Node; +exports.TokenType = TokenType; +exports.tokTypes = tt; +exports.keywordTypes = keywordTypes; +exports.TokContext = TokContext; +exports.tokContexts = types; +exports.isIdentifierChar = isIdentifierChar; +exports.isIdentifierStart = isIdentifierStart; +exports.Token = Token; +exports.isNewLine = isNewLine; +exports.lineBreak = lineBreak; +exports.lineBreakG = lineBreakG; + +Object.defineProperty(exports, '__esModule', { value: true }); + +})));
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.es.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.es.js new file mode 100644 index 000000000..91c0e6d27 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.es.js @@ -0,0 +1,1364 @@ +import { defaultOptions, addLooseExports, SourceLocation, tokTypes, tokenizer, Node, lineBreak, isNewLine, getLineInfo, Token, lineBreakG } from './acorn'; + +// Registered plugins +var pluginsLoose = {} + +var LooseParser = function LooseParser(input, options) { + if ( options === void 0 ) options = {}; + + this.toks = tokenizer(input, options) + this.options = this.toks.options + this.input = this.toks.input + this.tok = this.last = {type: tokTypes.eof, start: 0, end: 0} + if (this.options.locations) { + var here = this.toks.curPosition() + this.tok.loc = new SourceLocation(this.toks, here, here) + } + this.ahead = [] // Tokens ahead + this.context = [] // Indentation contexted + this.curIndent = 0 + this.curLineStart = 0 + this.nextLineStart = this.lineEnd(this.curLineStart) + 1 + this.inAsync = false + // Load plugins + this.options.pluginsLoose = options.pluginsLoose || {} + this.loadPlugins(this.options.pluginsLoose) +}; + +LooseParser.prototype.startNode = function startNode () { + return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) +}; + +LooseParser.prototype.storeCurrentPos = function storeCurrentPos () { + return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start +}; + +LooseParser.prototype.startNodeAt = function startNodeAt (pos) { + if (this.options.locations) { + return new Node(this.toks, pos[0], pos[1]) + } else { + return new Node(this.toks, pos) + } +}; + +LooseParser.prototype.finishNode = function finishNode (node, type) { + node.type = type + node.end = this.last.end + if (this.options.locations) + node.loc.end = this.last.loc.end + if (this.options.ranges) + node.range[1] = this.last.end + return node +}; + +LooseParser.prototype.dummyNode = function dummyNode (type) { + var dummy = this.startNode() + dummy.type = type + dummy.end = dummy.start + if (this.options.locations) + dummy.loc.end = dummy.loc.start + if (this.options.ranges) + dummy.range[1] = dummy.start + this.last = {type: tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc} + return dummy +}; + +LooseParser.prototype.dummyIdent = function dummyIdent () { + var dummy = this.dummyNode("Identifier") + dummy.name = "✖" + return dummy +}; + +LooseParser.prototype.dummyString = function dummyString () { + var dummy = this.dummyNode("Literal") + dummy.value = dummy.raw = "✖" + return dummy +}; + +LooseParser.prototype.eat = function eat (type) { + if (this.tok.type === type) { + this.next() + return true + } else { + return false + } +}; + +LooseParser.prototype.isContextual = function isContextual (name) { + return this.tok.type === tokTypes.name && this.tok.value === name +}; + +LooseParser.prototype.eatContextual = function eatContextual (name) { + return this.tok.value === name && this.eat(tokTypes.name) +}; + +LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () { + return this.tok.type === tokTypes.eof || this.tok.type === tokTypes.braceR || + lineBreak.test(this.input.slice(this.last.end, this.tok.start)) +}; + +LooseParser.prototype.semicolon = function semicolon () { + return this.eat(tokTypes.semi) +}; + +LooseParser.prototype.expect = function expect (type) { + var this$1 = this; + + if (this.eat(type)) return true + for (var i = 1; i <= 2; i++) { + if (this$1.lookAhead(i).type == type) { + for (var j = 0; j < i; j++) this$1.next() + return true + } + } +}; + +LooseParser.prototype.pushCx = function pushCx () { + this.context.push(this.curIndent) +}; + +LooseParser.prototype.popCx = function popCx () { + this.curIndent = this.context.pop() +}; + +LooseParser.prototype.lineEnd = function lineEnd (pos) { + while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos + return pos +}; + +LooseParser.prototype.indentationAfter = function indentationAfter (pos) { + var this$1 = this; + + for (var count = 0;; ++pos) { + var ch = this$1.input.charCodeAt(pos) + if (ch === 32) ++count + else if (ch === 9) count += this$1.options.tabSize + else return count + } +}; + +LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) { + if (this.tok.type === closeTok || this.tok.type === tokTypes.eof) return true + return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && + (!blockHeuristic || this.nextLineStart >= this.input.length || + this.indentationAfter(this.nextLineStart) < indent) +}; + +LooseParser.prototype.tokenStartsLine = function tokenStartsLine () { + var this$1 = this; + + for (var p = this.tok.start - 1; p >= this.curLineStart; --p) { + var ch = this$1.input.charCodeAt(p) + if (ch !== 9 && ch !== 32) return false + } + return true +}; + +LooseParser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +LooseParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = pluginsLoose[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +var lp = LooseParser.prototype + +function isSpace(ch) { + return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch) +} + +lp.next = function() { + var this$1 = this; + + this.last = this.tok + if (this.ahead.length) + this.tok = this.ahead.shift() + else + this.tok = this.readToken() + + if (this.tok.start >= this.nextLineStart) { + while (this.tok.start >= this.nextLineStart) { + this$1.curLineStart = this$1.nextLineStart + this$1.nextLineStart = this$1.lineEnd(this$1.curLineStart) + 1 + } + this.curIndent = this.indentationAfter(this.curLineStart) + } +} + +lp.readToken = function() { + var this$1 = this; + + for (;;) { + try { + this$1.toks.next() + if (this$1.toks.type === tokTypes.dot && + this$1.input.substr(this$1.toks.end, 1) === "." && + this$1.options.ecmaVersion >= 6) { + this$1.toks.end++ + this$1.toks.type = tokTypes.ellipsis + } + return new Token(this$1.toks) + } catch(e) { + if (!(e instanceof SyntaxError)) throw e + + // Try to skip some text, based on the error message, and then continue + var msg = e.message, pos = e.raisedAt, replace = true + if (/unterminated/i.test(msg)) { + pos = this$1.lineEnd(e.pos + 1) + if (/string/.test(msg)) { + replace = {start: e.pos, end: pos, type: tokTypes.string, value: this$1.input.slice(e.pos + 1, pos)} + } else if (/regular expr/i.test(msg)) { + var re = this$1.input.slice(e.pos, pos) + try { re = new RegExp(re) } catch(e) {} + replace = {start: e.pos, end: pos, type: tokTypes.regexp, value: re} + } else if (/template/.test(msg)) { + replace = {start: e.pos, end: pos, + type: tokTypes.template, + value: this$1.input.slice(e.pos, pos)} + } else { + replace = false + } + } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) { + while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos + } else if (/character escape|expected hexadecimal/i.test(msg)) { + while (pos < this.input.length) { + var ch = this$1.input.charCodeAt(pos++) + if (ch === 34 || ch === 39 || isNewLine(ch)) break + } + } else if (/unexpected character/i.test(msg)) { + pos++ + replace = false + } else if (/regular expression/i.test(msg)) { + replace = true + } else { + throw e + } + this$1.resetTo(pos) + if (replace === true) replace = {start: pos, end: pos, type: tokTypes.name, value: "✖"} + if (replace) { + if (this$1.options.locations) + replace.loc = new SourceLocation( + this$1.toks, + getLineInfo(this$1.input, replace.start), + getLineInfo(this$1.input, replace.end)) + return replace + } + } + } +} + +lp.resetTo = function(pos) { + var this$1 = this; + + this.toks.pos = pos + var ch = this.input.charAt(pos - 1) + this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || + /[enwfd]/.test(ch) && + /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos)) + + if (this.options.locations) { + this.toks.curLine = 1 + this.toks.lineStart = lineBreakG.lastIndex = 0 + var match + while ((match = lineBreakG.exec(this.input)) && match.index < pos) { + ++this$1.toks.curLine + this$1.toks.lineStart = match.index + match[0].length + } + } +} + +lp.lookAhead = function(n) { + var this$1 = this; + + while (n > this.ahead.length) + this$1.ahead.push(this$1.readToken()) + return this.ahead[n - 1] +} + +function isDummy(node) { return node.name == "✖" } + +var lp$1 = LooseParser.prototype + +lp$1.parseTopLevel = function() { + var this$1 = this; + + var node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0) + node.body = [] + while (this.tok.type !== tokTypes.eof) node.body.push(this$1.parseStatement()) + this.last = this.tok + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +lp$1.parseStatement = function() { + var this$1 = this; + + var starttype = this.tok.type, node = this.startNode(), kind + + if (this.toks.isLet()) { + starttype = tokTypes._var + kind = "let" + } + + switch (starttype) { + case tokTypes._break: case tokTypes._continue: + this.next() + var isBreak = starttype === tokTypes._break + if (this.semicolon() || this.canInsertSemicolon()) { + node.label = null + } else { + node.label = this.tok.type === tokTypes.name ? this.parseIdent() : null + this.semicolon() + } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + + case tokTypes._debugger: + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") + + case tokTypes._do: + this.next() + node.body = this.parseStatement() + node.test = this.eat(tokTypes._while) ? this.parseParenExpression() : this.dummyIdent() + this.semicolon() + return this.finishNode(node, "DoWhileStatement") + + case tokTypes._for: + this.next() + this.pushCx() + this.expect(tokTypes.parenL) + if (this.tok.type === tokTypes.semi) return this.parseFor(node, null) + var isLet = this.toks.isLet() + if (isLet || this.tok.type === tokTypes._var || this.tok.type === tokTypes._const) { + var init$1 = this.parseVar(true, isLet ? "let" : this.tok.value) + if (init$1.declarations.length === 1 && (this.tok.type === tokTypes._in || this.isContextual("of"))) { + return this.parseForIn(node, init$1) + } + return this.parseFor(node, init$1) + } + var init = this.parseExpression(true) + if (this.tok.type === tokTypes._in || this.isContextual("of")) + return this.parseForIn(node, this.toAssignable(init)) + return this.parseFor(node, init) + + case tokTypes._function: + this.next() + return this.parseFunction(node, true) + + case tokTypes._if: + this.next() + node.test = this.parseParenExpression() + node.consequent = this.parseStatement() + node.alternate = this.eat(tokTypes._else) ? this.parseStatement() : null + return this.finishNode(node, "IfStatement") + + case tokTypes._return: + this.next() + if (this.eat(tokTypes.semi) || this.canInsertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") + + case tokTypes._switch: + var blockIndent = this.curIndent, line = this.curLineStart + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.pushCx() + this.expect(tokTypes.braceL) + + var cur + while (!this.closes(tokTypes.braceR, blockIndent, line, true)) { + if (this$1.tok.type === tokTypes._case || this$1.tok.type === tokTypes._default) { + var isCase = this$1.tok.type === tokTypes._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) cur.test = this$1.parseExpression() + else cur.test = null + this$1.expect(tokTypes.colon) + } else { + if (!cur) { + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + cur.test = null + } + cur.consequent.push(this$1.parseStatement()) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.popCx() + this.eat(tokTypes.braceR) + return this.finishNode(node, "SwitchStatement") + + case tokTypes._throw: + this.next() + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") + + case tokTypes._try: + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.tok.type === tokTypes._catch) { + var clause = this.startNode() + this.next() + this.expect(tokTypes.parenL) + clause.param = this.toAssignable(this.parseExprAtom(), true) + this.expect(tokTypes.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tokTypes._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) return node.block + return this.finishNode(node, "TryStatement") + + case tokTypes._var: + case tokTypes._const: + return this.parseVar(false, kind || this.tok.value) + + case tokTypes._while: + this.next() + node.test = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WhileStatement") + + case tokTypes._with: + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WithStatement") + + case tokTypes.braceL: + return this.parseBlock() + + case tokTypes.semi: + this.next() + return this.finishNode(node, "EmptyStatement") + + case tokTypes._class: + return this.parseClass(true) + + case tokTypes._import: + return this.parseImport() + + case tokTypes._export: + return this.parseExport() + + default: + if (this.toks.isAsyncFunction()) { + this.next() + this.next() + return this.parseFunction(node, true, true) + } + var expr = this.parseExpression() + if (isDummy(expr)) { + this.next() + if (this.tok.type === tokTypes.eof) return this.finishNode(node, "EmptyStatement") + return this.parseStatement() + } else if (starttype === tokTypes.name && expr.type === "Identifier" && this.eat(tokTypes.colon)) { + node.body = this.parseStatement() + node.label = expr + return this.finishNode(node, "LabeledStatement") + } else { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") + } + } +} + +lp$1.parseBlock = function() { + var this$1 = this; + + var node = this.startNode() + this.pushCx() + this.expect(tokTypes.braceL) + var blockIndent = this.curIndent, line = this.curLineStart + node.body = [] + while (!this.closes(tokTypes.braceR, blockIndent, line, true)) + node.body.push(this$1.parseStatement()) + this.popCx() + this.eat(tokTypes.braceR) + return this.finishNode(node, "BlockStatement") +} + +lp$1.parseFor = function(node, init) { + node.init = init + node.test = node.update = null + if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.semi) node.test = this.parseExpression() + if (this.eat(tokTypes.semi) && this.tok.type !== tokTypes.parenR) node.update = this.parseExpression() + this.popCx() + this.expect(tokTypes.parenR) + node.body = this.parseStatement() + return this.finishNode(node, "ForStatement") +} + +lp$1.parseForIn = function(node, init) { + var type = this.tok.type === tokTypes._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.popCx() + this.expect(tokTypes.parenR) + node.body = this.parseStatement() + return this.finishNode(node, type) +} + +lp$1.parseVar = function(noIn, kind) { + var this$1 = this; + + var node = this.startNode() + node.kind = kind + this.next() + node.declarations = [] + do { + var decl = this$1.startNode() + decl.id = this$1.options.ecmaVersion >= 6 ? this$1.toAssignable(this$1.parseExprAtom(), true) : this$1.parseIdent() + decl.init = this$1.eat(tokTypes.eq) ? this$1.parseMaybeAssign(noIn) : null + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + } while (this.eat(tokTypes.comma)) + if (!node.declarations.length) { + var decl$1 = this.startNode() + decl$1.id = this.dummyIdent() + node.declarations.push(this.finishNode(decl$1, "VariableDeclarator")) + } + if (!noIn) this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +lp$1.parseClass = function(isStatement) { + var this$1 = this; + + var node = this.startNode() + this.next() + if (isStatement == null) isStatement = this.tok.type === tokTypes.name + if (this.tok.type === tokTypes.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + else node.id = null + node.superClass = this.eat(tokTypes._extends) ? this.parseExpression() : null + node.body = this.startNode() + node.body.body = [] + this.pushCx() + var indent = this.curIndent + 1, line = this.curLineStart + this.eat(tokTypes.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(tokTypes.braceR, indent, line)) { + if (this$1.semicolon()) continue + var method = this$1.startNode(), isGenerator, isAsync + if (this$1.options.ecmaVersion >= 6) { + method.static = false + isGenerator = this$1.eat(tokTypes.star) + } + this$1.parsePropertyName(method) + if (isDummy(method.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(tokTypes.comma); continue } + if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" && + (this$1.tok.type != tokTypes.parenL && this$1.tok.type != tokTypes.braceL)) { + method.static = true + isGenerator = this$1.eat(tokTypes.star) + this$1.parsePropertyName(method) + } else { + method.static = false + } + if (!method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this$1.tok.type !== tokTypes.parenL && + !this$1.canInsertSemicolon()) { + this$1.parsePropertyName(method) + isAsync = true + } else { + isAsync = false + } + if (this$1.options.ecmaVersion >= 5 && method.key.type === "Identifier" && + !method.computed && (method.key.name === "get" || method.key.name === "set") && + this$1.tok.type !== tokTypes.parenL && this$1.tok.type !== tokTypes.braceL) { + method.kind = method.key.name + this$1.parsePropertyName(method) + method.value = this$1.parseMethod(false) + } else { + if (!method.computed && !method.static && !isGenerator && !isAsync && ( + method.key.type === "Identifier" && method.key.name === "constructor" || + method.key.type === "Literal" && method.key.value === "constructor")) { + method.kind = "constructor" + } else { + method.kind = "method" + } + method.value = this$1.parseMethod(isGenerator, isAsync) + } + node.body.body.push(this$1.finishNode(method, "MethodDefinition")) + } + this.popCx() + if (!this.eat(tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + this.semicolon() + this.finishNode(node.body, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +lp$1.parseFunction = function(node, isStatement, isAsync) { + var oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) { + node.generator = this.eat(tokTypes.star) + } + if (this.options.ecmaVersion >= 8) { + node.async = !!isAsync + } + if (isStatement == null) isStatement = this.tok.type === tokTypes.name + if (this.tok.type === tokTypes.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.body = this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +lp$1.parseExport = function() { + var node = this.startNode() + this.next() + if (this.eat(tokTypes.star)) { + node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tokTypes._default)) { + // export default (function foo() {}) // This is FunctionExpression. + var isAsync + if (this.tok.type === tokTypes._function || (isAsync = this.toks.isAsyncFunction())) { + var fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, isAsync) + } else if (this.tok.type === tokTypes._class) { + node.declaration = this.parseClass(null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) { + node.declaration = this.parseStatement() + node.specifiers = [] + node.source = null + } else { + node.declaration = null + node.specifiers = this.parseExportSpecifierList() + node.source = this.eatContextual("from") ? this.parseExprAtom() : null + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +lp$1.parseImport = function() { + var node = this.startNode() + this.next() + if (this.tok.type === tokTypes.string) { + node.specifiers = [] + node.source = this.parseExprAtom() + node.kind = '' + } else { + var elt + if (this.tok.type === tokTypes.name && this.tok.value !== "from") { + elt = this.startNode() + elt.local = this.parseIdent() + this.finishNode(elt, "ImportDefaultSpecifier") + this.eat(tokTypes.comma) + } + node.specifiers = this.parseImportSpecifierList() + node.source = this.eatContextual("from") && this.tok.type == tokTypes.string ? this.parseExprAtom() : this.dummyString() + if (elt) node.specifiers.unshift(elt) + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +lp$1.parseImportSpecifierList = function() { + var this$1 = this; + + var elts = [] + if (this.tok.type === tokTypes.star) { + var elt = this.startNode() + this.next() + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent() + elts.push(this.finishNode(elt, "ImportNamespaceSpecifier")) + } else { + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(tokTypes.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var elt$1 = this$1.startNode() + if (this$1.eat(tokTypes.star)) { + elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : this$1.dummyIdent() + this$1.finishNode(elt$1, "ImportNamespaceSpecifier") + } else { + if (this$1.isContextual("from")) break + elt$1.imported = this$1.parseIdent() + if (isDummy(elt$1.imported)) break + elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : elt$1.imported + this$1.finishNode(elt$1, "ImportSpecifier") + } + elts.push(elt$1) + this$1.eat(tokTypes.comma) + } + this.eat(tokTypes.braceR) + this.popCx() + } + return elts +} + +lp$1.parseExportSpecifierList = function() { + var this$1 = this; + + var elts = [] + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(tokTypes.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this$1.isContextual("from")) break + var elt = this$1.startNode() + elt.local = this$1.parseIdent() + if (isDummy(elt.local)) break + elt.exported = this$1.eatContextual("as") ? this$1.parseIdent() : elt.local + this$1.finishNode(elt, "ExportSpecifier") + elts.push(elt) + this$1.eat(tokTypes.comma) + } + this.eat(tokTypes.braceR) + this.popCx() + return elts +} + +var lp$2 = LooseParser.prototype + +lp$2.checkLVal = function(expr) { + if (!expr) return expr + switch (expr.type) { + case "Identifier": + case "MemberExpression": + return expr + + case "ParenthesizedExpression": + expr.expression = this.checkLVal(expr.expression) + return expr + + default: + return this.dummyIdent() + } +} + +lp$2.parseExpression = function(noIn) { + var this$1 = this; + + var start = this.storeCurrentPos() + var expr = this.parseMaybeAssign(noIn) + if (this.tok.type === tokTypes.comma) { + var node = this.startNodeAt(start) + node.expressions = [expr] + while (this.eat(tokTypes.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +lp$2.parseParenExpression = function() { + this.pushCx() + this.expect(tokTypes.parenL) + var val = this.parseExpression() + this.popCx() + this.expect(tokTypes.parenR) + return val +} + +lp$2.parseMaybeAssign = function(noIn) { + if (this.toks.isContextual("yield")) { + var node = this.startNode() + this.next() + if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != tokTypes.star && !this.tok.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tokTypes.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") + } + + var start = this.storeCurrentPos() + var left = this.parseMaybeConditional(noIn) + if (this.tok.type.isAssign) { + var node$1 = this.startNodeAt(start) + node$1.operator = this.tok.value + node$1.left = this.tok.type === tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left) + this.next() + node$1.right = this.parseMaybeAssign(noIn) + return this.finishNode(node$1, "AssignmentExpression") + } + return left +} + +lp$2.parseMaybeConditional = function(noIn) { + var start = this.storeCurrentPos() + var expr = this.parseExprOps(noIn) + if (this.eat(tokTypes.question)) { + var node = this.startNodeAt(start) + node.test = expr + node.consequent = this.parseMaybeAssign() + node.alternate = this.expect(tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent() + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +lp$2.parseExprOps = function(noIn) { + var start = this.storeCurrentPos() + var indent = this.curIndent, line = this.curLineStart + return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line) +} + +lp$2.parseExprOp = function(left, start, minPrec, noIn, indent, line) { + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left + var prec = this.tok.type.binop + if (prec != null && (!noIn || this.tok.type !== tokTypes._in)) { + if (prec > minPrec) { + var node = this.startNodeAt(start) + node.left = left + node.operator = this.tok.value + this.next() + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) { + node.right = this.dummyIdent() + } else { + var rightStart = this.storeCurrentPos() + node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line) + } + this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression") + return this.parseExprOp(node, start, minPrec, noIn, indent, line) + } + } + return left +} + +lp$2.parseMaybeUnary = function(sawUnary) { + var this$1 = this; + + var start = this.storeCurrentPos(), expr + if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) { + expr = this.parseAwait() + sawUnary = true + } else if (this.tok.type.prefix) { + var node = this.startNode(), update = this.tok.type === tokTypes.incDec + if (!update) sawUnary = true + node.operator = this.tok.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(true) + if (update) node.argument = this.checkLVal(node.argument) + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else if (this.tok.type === tokTypes.ellipsis) { + var node$1 = this.startNode() + this.next() + node$1.argument = this.parseMaybeUnary(sawUnary) + expr = this.finishNode(node$1, "SpreadElement") + } else { + expr = this.parseExprSubscripts() + while (this.tok.type.postfix && !this.canInsertSemicolon()) { + var node$2 = this$1.startNodeAt(start) + node$2.operator = this$1.tok.value + node$2.prefix = false + node$2.argument = this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$2, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tokTypes.starstar)) { + var node$3 = this.startNodeAt(start) + node$3.operator = "**" + node$3.left = expr + node$3.right = this.parseMaybeUnary(false) + return this.finishNode(node$3, "BinaryExpression") + } + + return expr +} + +lp$2.parseExprSubscripts = function() { + var start = this.storeCurrentPos() + return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart) +} + +lp$2.parseSubscripts = function(base, start, noCalls, startIndent, line) { + var this$1 = this; + + for (;;) { + if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) { + if (this$1.tok.type == tokTypes.dot && this$1.curIndent == startIndent) + --startIndent + else + return base + } + + var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon() + + if (this$1.eat(tokTypes.dot)) { + var node = this$1.startNodeAt(start) + node.object = base + if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) + node.property = this$1.dummyIdent() + else + node.property = this$1.parsePropertyAccessor() || this$1.dummyIdent() + node.computed = false + base = this$1.finishNode(node, "MemberExpression") + } else if (this$1.tok.type == tokTypes.bracketL) { + this$1.pushCx() + this$1.next() + var node$1 = this$1.startNodeAt(start) + node$1.object = base + node$1.property = this$1.parseExpression() + node$1.computed = true + this$1.popCx() + this$1.expect(tokTypes.bracketR) + base = this$1.finishNode(node$1, "MemberExpression") + } else if (!noCalls && this$1.tok.type == tokTypes.parenL) { + var exprList = this$1.parseExprList(tokTypes.parenR) + if (maybeAsyncArrow && this$1.eat(tokTypes.arrow)) + return this$1.parseArrowExpression(this$1.startNodeAt(start), exprList, true) + var node$2 = this$1.startNodeAt(start) + node$2.callee = base + node$2.arguments = exprList + base = this$1.finishNode(node$2, "CallExpression") + } else if (this$1.tok.type == tokTypes.backQuote) { + var node$3 = this$1.startNodeAt(start) + node$3.tag = base + node$3.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$3, "TaggedTemplateExpression") + } else { + return base + } + } +} + +lp$2.parseExprAtom = function() { + var node + switch (this.tok.type) { + case tokTypes._this: + case tokTypes._super: + var type = this.tok.type === tokTypes._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tokTypes.name: + var start = this.storeCurrentPos() + var id = this.parseIdent() + var isAsync = false + if (id.name === "async" && !this.canInsertSemicolon()) { + if (this.eat(tokTypes._function)) + return this.parseFunction(this.startNodeAt(start), false, true) + if (this.tok.type === tokTypes.name) { + id = this.parseIdent() + isAsync = true + } + } + return this.eat(tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id + + case tokTypes.regexp: + node = this.startNode() + var val = this.tok.value + node.regex = {pattern: val.pattern, flags: val.flags} + node.value = val.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case tokTypes.num: case tokTypes.string: + node = this.startNode() + node.value = this.tok.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case tokTypes._null: case tokTypes._true: case tokTypes._false: + node = this.startNode() + node.value = this.tok.type === tokTypes._null ? null : this.tok.type === tokTypes._true + node.raw = this.tok.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tokTypes.parenL: + var parenStart = this.storeCurrentPos() + this.next() + var inner = this.parseExpression() + this.expect(tokTypes.parenR) + if (this.eat(tokTypes.arrow)) { + // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy. + var params = inner.expressions || [inner] + if (params.length && isDummy(params[params.length - 1])) + params.pop() + return this.parseArrowExpression(this.startNodeAt(parenStart), params) + } + if (this.options.preserveParens) { + var par = this.startNodeAt(parenStart) + par.expression = inner + inner = this.finishNode(par, "ParenthesizedExpression") + } + return inner + + case tokTypes.bracketL: + node = this.startNode() + node.elements = this.parseExprList(tokTypes.bracketR, true) + return this.finishNode(node, "ArrayExpression") + + case tokTypes.braceL: + return this.parseObj() + + case tokTypes._class: + return this.parseClass(false) + + case tokTypes._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tokTypes._new: + return this.parseNew() + + case tokTypes.backQuote: + return this.parseTemplate() + + default: + return this.dummyIdent() + } +} + +lp$2.parseNew = function() { + var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tokTypes.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + return this.finishNode(node, "MetaProperty") + } + var start = this.storeCurrentPos() + node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line) + if (this.tok.type == tokTypes.parenL) { + node.arguments = this.parseExprList(tokTypes.parenR) + } else { + node.arguments = [] + } + return this.finishNode(node, "NewExpression") +} + +lp$2.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, '\n'), + cooked: this.tok.value + } + this.next() + elem.tail = this.tok.type === tokTypes.backQuote + return this.finishNode(elem, "TemplateElement") +} + +lp$2.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.next() + node.expressions.push(this$1.parseExpression()) + if (this$1.expect(tokTypes.braceR)) { + curElt = this$1.parseTemplateElement() + } else { + curElt = this$1.startNode() + curElt.value = {cooked: '', raw: ''} + curElt.tail = true + this$1.finishNode(curElt, "TemplateElement") + } + node.quasis.push(curElt) + } + this.expect(tokTypes.backQuote) + return this.finishNode(node, "TemplateLiteral") +} + +lp$2.parseObj = function() { + var this$1 = this; + + var node = this.startNode() + node.properties = [] + this.pushCx() + var indent = this.curIndent + 1, line = this.curLineStart + this.eat(tokTypes.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(tokTypes.braceR, indent, line)) { + var prop = this$1.startNode(), isGenerator, isAsync, start + if (this$1.options.ecmaVersion >= 6) { + start = this$1.storeCurrentPos() + prop.method = false + prop.shorthand = false + isGenerator = this$1.eat(tokTypes.star) + } + this$1.parsePropertyName(prop) + if (!prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this$1.tok.type !== tokTypes.parenL && + this$1.tok.type !== tokTypes.colon && !this$1.canInsertSemicolon()) { + this$1.parsePropertyName(prop) + isAsync = true + } else { + isAsync = false + } + if (isDummy(prop.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(tokTypes.comma); continue } + if (this$1.eat(tokTypes.colon)) { + prop.kind = "init" + prop.value = this$1.parseMaybeAssign() + } else if (this$1.options.ecmaVersion >= 6 && (this$1.tok.type === tokTypes.parenL || this$1.tok.type === tokTypes.braceL)) { + prop.kind = "init" + prop.method = true + prop.value = this$1.parseMethod(isGenerator, isAsync) + } else if (this$1.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && + !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && + (this$1.tok.type != tokTypes.comma && this$1.tok.type != tokTypes.braceR)) { + prop.kind = prop.key.name + this$1.parsePropertyName(prop) + prop.value = this$1.parseMethod(false) + } else { + prop.kind = "init" + if (this$1.options.ecmaVersion >= 6) { + if (this$1.eat(tokTypes.eq)) { + var assign = this$1.startNodeAt(start) + assign.operator = "=" + assign.left = prop.key + assign.right = this$1.parseMaybeAssign() + prop.value = this$1.finishNode(assign, "AssignmentExpression") + } else { + prop.value = prop.key + } + } else { + prop.value = this$1.dummyIdent() + } + prop.shorthand = true + } + node.properties.push(this$1.finishNode(prop, "Property")) + this$1.eat(tokTypes.comma) + } + this.popCx() + if (!this.eat(tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return this.finishNode(node, "ObjectExpression") +} + +lp$2.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tokTypes.bracketL)) { + prop.computed = true + prop.key = this.parseExpression() + this.expect(tokTypes.bracketR) + return + } else { + prop.computed = false + } + } + var key = (this.tok.type === tokTypes.num || this.tok.type === tokTypes.string) ? this.parseExprAtom() : this.parseIdent() + prop.key = key || this.dummyIdent() +} + +lp$2.parsePropertyAccessor = function() { + if (this.tok.type === tokTypes.name || this.tok.type.keyword) return this.parseIdent() +} + +lp$2.parseIdent = function() { + var name = this.tok.type === tokTypes.name ? this.tok.value : this.tok.type.keyword + if (!name) return this.dummyIdent() + var node = this.startNode() + this.next() + node.name = name + return this.finishNode(node, "Identifier") +} + +lp$2.initFunction = function(node) { + node.id = null + node.params = [] + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Convert existing expression atom to assignable pattern +// if possible. + +lp$2.toAssignable = function(node, binding) { + var this$1 = this; + + if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) { + // Okay + } else if (node.type == "ParenthesizedExpression") { + node.expression = this.toAssignable(node.expression, binding) + } else if (this.options.ecmaVersion < 6) { + return this.dummyIdent() + } else if (node.type == "ObjectExpression") { + node.type = "ObjectPattern" + var props = node.properties + for (var i = 0; i < props.length; i++) + props[i].value = this$1.toAssignable(props[i].value, binding) + } else if (node.type == "ArrayExpression") { + node.type = "ArrayPattern" + this.toAssignableList(node.elements, binding) + } else if (node.type == "SpreadElement") { + node.type = "RestElement" + node.argument = this.toAssignable(node.argument, binding) + } else if (node.type == "AssignmentExpression") { + node.type = "AssignmentPattern" + delete node.operator + } else { + return this.dummyIdent() + } + return node +} + +lp$2.toAssignableList = function(exprList, binding) { + var this$1 = this; + + for (var i = 0; i < exprList.length; i++) + exprList[i] = this$1.toAssignable(exprList[i], binding) + return exprList +} + +lp$2.parseFunctionParams = function(params) { + params = this.parseExprList(tokTypes.parenR) + return this.toAssignableList(params, true) +} + +lp$2.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = !!isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tokTypes.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "FunctionExpression") +} + +lp$2.parseArrowExpression = function(node, params, isAsync) { + var oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.toAssignableList(params, true) + node.expression = this.tok.type !== tokTypes.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "ArrowFunctionExpression") +} + +lp$2.parseExprList = function(close, allowEmpty) { + var this$1 = this; + + this.pushCx() + var indent = this.curIndent, line = this.curLineStart, elts = [] + this.next() // Opening bracket + while (!this.closes(close, indent + 1, line)) { + if (this$1.eat(tokTypes.comma)) { + elts.push(allowEmpty ? null : this$1.dummyIdent()) + continue + } + var elt = this$1.parseMaybeAssign() + if (isDummy(elt)) { + if (this$1.closes(close, indent, line)) break + this$1.next() + } else { + elts.push(elt) + } + this$1.eat(tokTypes.comma) + } + this.popCx() + if (!this.eat(close)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return elts +} + +lp$2.parseAwait = function() { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary() + return this.finishNode(node, "AwaitExpression") +} + +// Acorn: Loose parser +// +// This module provides an alternative parser (`parse_dammit`) that +// exposes that same interface as `parse`, but will try to parse +// anything as JavaScript, repairing syntax error the best it can. +// There are circumstances in which it will raise an error and give +// up, but they are very rare. The resulting AST will be a mostly +// valid JavaScript AST (as per the [Mozilla parser API][api], except +// that: +// +// - Return outside functions is allowed +// +// - Label consistency (no conflicts, break only to existing labels) +// is not enforced. +// +// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever +// the parser got too confused to return anything meaningful. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API +// +// The expected use for this is to *first* try `acorn.parse`, and only +// if that fails switch to `parse_dammit`. The loose parser might +// parse badly indented code incorrectly, so **don't** use it as +// your default parser. +// +// Quite a lot of acorn.js is duplicated here. The alternative was to +// add a *lot* of extra cruft to that file, making it less readable +// and slower. Copying and editing the code allowed me to make +// invasive changes and simplifications without creating a complicated +// tangle. + +defaultOptions.tabSize = 4 + +function parse_dammit(input, options) { + var p = new LooseParser(input, options) + p.next() + return p.parseTopLevel() +} + +addLooseExports(parse_dammit, LooseParser, pluginsLoose) + +export { parse_dammit, LooseParser, pluginsLoose };
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.js new file mode 100644 index 000000000..f8eab1ae3 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.js @@ -0,0 +1,1374 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./acorn')) : + typeof define === 'function' && define.amd ? define(['exports', './acorn'], factory) : + (factory((global.acorn = global.acorn || {}, global.acorn.loose = global.acorn.loose || {}),global.acorn)); +}(this, (function (exports,__acorn) { 'use strict'; + +// Registered plugins +var pluginsLoose = {} + +var LooseParser = function LooseParser(input, options) { + if ( options === void 0 ) options = {}; + + this.toks = __acorn.tokenizer(input, options) + this.options = this.toks.options + this.input = this.toks.input + this.tok = this.last = {type: __acorn.tokTypes.eof, start: 0, end: 0} + if (this.options.locations) { + var here = this.toks.curPosition() + this.tok.loc = new __acorn.SourceLocation(this.toks, here, here) + } + this.ahead = [] // Tokens ahead + this.context = [] // Indentation contexted + this.curIndent = 0 + this.curLineStart = 0 + this.nextLineStart = this.lineEnd(this.curLineStart) + 1 + this.inAsync = false + // Load plugins + this.options.pluginsLoose = options.pluginsLoose || {} + this.loadPlugins(this.options.pluginsLoose) +}; + +LooseParser.prototype.startNode = function startNode () { + return new __acorn.Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) +}; + +LooseParser.prototype.storeCurrentPos = function storeCurrentPos () { + return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start +}; + +LooseParser.prototype.startNodeAt = function startNodeAt (pos) { + if (this.options.locations) { + return new __acorn.Node(this.toks, pos[0], pos[1]) + } else { + return new __acorn.Node(this.toks, pos) + } +}; + +LooseParser.prototype.finishNode = function finishNode (node, type) { + node.type = type + node.end = this.last.end + if (this.options.locations) + node.loc.end = this.last.loc.end + if (this.options.ranges) + node.range[1] = this.last.end + return node +}; + +LooseParser.prototype.dummyNode = function dummyNode (type) { + var dummy = this.startNode() + dummy.type = type + dummy.end = dummy.start + if (this.options.locations) + dummy.loc.end = dummy.loc.start + if (this.options.ranges) + dummy.range[1] = dummy.start + this.last = {type: __acorn.tokTypes.name, start: dummy.start, end: dummy.start, loc: dummy.loc} + return dummy +}; + +LooseParser.prototype.dummyIdent = function dummyIdent () { + var dummy = this.dummyNode("Identifier") + dummy.name = "✖" + return dummy +}; + +LooseParser.prototype.dummyString = function dummyString () { + var dummy = this.dummyNode("Literal") + dummy.value = dummy.raw = "✖" + return dummy +}; + +LooseParser.prototype.eat = function eat (type) { + if (this.tok.type === type) { + this.next() + return true + } else { + return false + } +}; + +LooseParser.prototype.isContextual = function isContextual (name) { + return this.tok.type === __acorn.tokTypes.name && this.tok.value === name +}; + +LooseParser.prototype.eatContextual = function eatContextual (name) { + return this.tok.value === name && this.eat(__acorn.tokTypes.name) +}; + +LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon () { + return this.tok.type === __acorn.tokTypes.eof || this.tok.type === __acorn.tokTypes.braceR || + __acorn.lineBreak.test(this.input.slice(this.last.end, this.tok.start)) +}; + +LooseParser.prototype.semicolon = function semicolon () { + return this.eat(__acorn.tokTypes.semi) +}; + +LooseParser.prototype.expect = function expect (type) { + var this$1 = this; + + if (this.eat(type)) return true + for (var i = 1; i <= 2; i++) { + if (this$1.lookAhead(i).type == type) { + for (var j = 0; j < i; j++) this$1.next() + return true + } + } +}; + +LooseParser.prototype.pushCx = function pushCx () { + this.context.push(this.curIndent) +}; + +LooseParser.prototype.popCx = function popCx () { + this.curIndent = this.context.pop() +}; + +LooseParser.prototype.lineEnd = function lineEnd (pos) { + while (pos < this.input.length && !__acorn.isNewLine(this.input.charCodeAt(pos))) ++pos + return pos +}; + +LooseParser.prototype.indentationAfter = function indentationAfter (pos) { + var this$1 = this; + + for (var count = 0;; ++pos) { + var ch = this$1.input.charCodeAt(pos) + if (ch === 32) ++count + else if (ch === 9) count += this$1.options.tabSize + else return count + } +}; + +LooseParser.prototype.closes = function closes (closeTok, indent, line, blockHeuristic) { + if (this.tok.type === closeTok || this.tok.type === __acorn.tokTypes.eof) return true + return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && + (!blockHeuristic || this.nextLineStart >= this.input.length || + this.indentationAfter(this.nextLineStart) < indent) +}; + +LooseParser.prototype.tokenStartsLine = function tokenStartsLine () { + var this$1 = this; + + for (var p = this.tok.start - 1; p >= this.curLineStart; --p) { + var ch = this$1.input.charCodeAt(p) + if (ch !== 9 && ch !== 32) return false + } + return true +}; + +LooseParser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +LooseParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = pluginsLoose[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +var lp = LooseParser.prototype + +function isSpace(ch) { + return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || __acorn.isNewLine(ch) +} + +lp.next = function() { + var this$1 = this; + + this.last = this.tok + if (this.ahead.length) + this.tok = this.ahead.shift() + else + this.tok = this.readToken() + + if (this.tok.start >= this.nextLineStart) { + while (this.tok.start >= this.nextLineStart) { + this$1.curLineStart = this$1.nextLineStart + this$1.nextLineStart = this$1.lineEnd(this$1.curLineStart) + 1 + } + this.curIndent = this.indentationAfter(this.curLineStart) + } +} + +lp.readToken = function() { + var this$1 = this; + + for (;;) { + try { + this$1.toks.next() + if (this$1.toks.type === __acorn.tokTypes.dot && + this$1.input.substr(this$1.toks.end, 1) === "." && + this$1.options.ecmaVersion >= 6) { + this$1.toks.end++ + this$1.toks.type = __acorn.tokTypes.ellipsis + } + return new __acorn.Token(this$1.toks) + } catch(e) { + if (!(e instanceof SyntaxError)) throw e + + // Try to skip some text, based on the error message, and then continue + var msg = e.message, pos = e.raisedAt, replace = true + if (/unterminated/i.test(msg)) { + pos = this$1.lineEnd(e.pos + 1) + if (/string/.test(msg)) { + replace = {start: e.pos, end: pos, type: __acorn.tokTypes.string, value: this$1.input.slice(e.pos + 1, pos)} + } else if (/regular expr/i.test(msg)) { + var re = this$1.input.slice(e.pos, pos) + try { re = new RegExp(re) } catch(e) {} + replace = {start: e.pos, end: pos, type: __acorn.tokTypes.regexp, value: re} + } else if (/template/.test(msg)) { + replace = {start: e.pos, end: pos, + type: __acorn.tokTypes.template, + value: this$1.input.slice(e.pos, pos)} + } else { + replace = false + } + } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) { + while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos + } else if (/character escape|expected hexadecimal/i.test(msg)) { + while (pos < this.input.length) { + var ch = this$1.input.charCodeAt(pos++) + if (ch === 34 || ch === 39 || __acorn.isNewLine(ch)) break + } + } else if (/unexpected character/i.test(msg)) { + pos++ + replace = false + } else if (/regular expression/i.test(msg)) { + replace = true + } else { + throw e + } + this$1.resetTo(pos) + if (replace === true) replace = {start: pos, end: pos, type: __acorn.tokTypes.name, value: "✖"} + if (replace) { + if (this$1.options.locations) + replace.loc = new __acorn.SourceLocation( + this$1.toks, + __acorn.getLineInfo(this$1.input, replace.start), + __acorn.getLineInfo(this$1.input, replace.end)) + return replace + } + } + } +} + +lp.resetTo = function(pos) { + var this$1 = this; + + this.toks.pos = pos + var ch = this.input.charAt(pos - 1) + this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || + /[enwfd]/.test(ch) && + /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos)) + + if (this.options.locations) { + this.toks.curLine = 1 + this.toks.lineStart = __acorn.lineBreakG.lastIndex = 0 + var match + while ((match = __acorn.lineBreakG.exec(this.input)) && match.index < pos) { + ++this$1.toks.curLine + this$1.toks.lineStart = match.index + match[0].length + } + } +} + +lp.lookAhead = function(n) { + var this$1 = this; + + while (n > this.ahead.length) + this$1.ahead.push(this$1.readToken()) + return this.ahead[n - 1] +} + +function isDummy(node) { return node.name == "✖" } + +var lp$1 = LooseParser.prototype + +lp$1.parseTopLevel = function() { + var this$1 = this; + + var node = this.startNodeAt(this.options.locations ? [0, __acorn.getLineInfo(this.input, 0)] : 0) + node.body = [] + while (this.tok.type !== __acorn.tokTypes.eof) node.body.push(this$1.parseStatement()) + this.last = this.tok + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +lp$1.parseStatement = function() { + var this$1 = this; + + var starttype = this.tok.type, node = this.startNode(), kind + + if (this.toks.isLet()) { + starttype = __acorn.tokTypes._var + kind = "let" + } + + switch (starttype) { + case __acorn.tokTypes._break: case __acorn.tokTypes._continue: + this.next() + var isBreak = starttype === __acorn.tokTypes._break + if (this.semicolon() || this.canInsertSemicolon()) { + node.label = null + } else { + node.label = this.tok.type === __acorn.tokTypes.name ? this.parseIdent() : null + this.semicolon() + } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + + case __acorn.tokTypes._debugger: + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") + + case __acorn.tokTypes._do: + this.next() + node.body = this.parseStatement() + node.test = this.eat(__acorn.tokTypes._while) ? this.parseParenExpression() : this.dummyIdent() + this.semicolon() + return this.finishNode(node, "DoWhileStatement") + + case __acorn.tokTypes._for: + this.next() + this.pushCx() + this.expect(__acorn.tokTypes.parenL) + if (this.tok.type === __acorn.tokTypes.semi) return this.parseFor(node, null) + var isLet = this.toks.isLet() + if (isLet || this.tok.type === __acorn.tokTypes._var || this.tok.type === __acorn.tokTypes._const) { + var init$1 = this.parseVar(true, isLet ? "let" : this.tok.value) + if (init$1.declarations.length === 1 && (this.tok.type === __acorn.tokTypes._in || this.isContextual("of"))) { + return this.parseForIn(node, init$1) + } + return this.parseFor(node, init$1) + } + var init = this.parseExpression(true) + if (this.tok.type === __acorn.tokTypes._in || this.isContextual("of")) + return this.parseForIn(node, this.toAssignable(init)) + return this.parseFor(node, init) + + case __acorn.tokTypes._function: + this.next() + return this.parseFunction(node, true) + + case __acorn.tokTypes._if: + this.next() + node.test = this.parseParenExpression() + node.consequent = this.parseStatement() + node.alternate = this.eat(__acorn.tokTypes._else) ? this.parseStatement() : null + return this.finishNode(node, "IfStatement") + + case __acorn.tokTypes._return: + this.next() + if (this.eat(__acorn.tokTypes.semi) || this.canInsertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") + + case __acorn.tokTypes._switch: + var blockIndent = this.curIndent, line = this.curLineStart + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.pushCx() + this.expect(__acorn.tokTypes.braceL) + + var cur + while (!this.closes(__acorn.tokTypes.braceR, blockIndent, line, true)) { + if (this$1.tok.type === __acorn.tokTypes._case || this$1.tok.type === __acorn.tokTypes._default) { + var isCase = this$1.tok.type === __acorn.tokTypes._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) cur.test = this$1.parseExpression() + else cur.test = null + this$1.expect(__acorn.tokTypes.colon) + } else { + if (!cur) { + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + cur.test = null + } + cur.consequent.push(this$1.parseStatement()) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.popCx() + this.eat(__acorn.tokTypes.braceR) + return this.finishNode(node, "SwitchStatement") + + case __acorn.tokTypes._throw: + this.next() + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") + + case __acorn.tokTypes._try: + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.tok.type === __acorn.tokTypes._catch) { + var clause = this.startNode() + this.next() + this.expect(__acorn.tokTypes.parenL) + clause.param = this.toAssignable(this.parseExprAtom(), true) + this.expect(__acorn.tokTypes.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(__acorn.tokTypes._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) return node.block + return this.finishNode(node, "TryStatement") + + case __acorn.tokTypes._var: + case __acorn.tokTypes._const: + return this.parseVar(false, kind || this.tok.value) + + case __acorn.tokTypes._while: + this.next() + node.test = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WhileStatement") + + case __acorn.tokTypes._with: + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WithStatement") + + case __acorn.tokTypes.braceL: + return this.parseBlock() + + case __acorn.tokTypes.semi: + this.next() + return this.finishNode(node, "EmptyStatement") + + case __acorn.tokTypes._class: + return this.parseClass(true) + + case __acorn.tokTypes._import: + return this.parseImport() + + case __acorn.tokTypes._export: + return this.parseExport() + + default: + if (this.toks.isAsyncFunction()) { + this.next() + this.next() + return this.parseFunction(node, true, true) + } + var expr = this.parseExpression() + if (isDummy(expr)) { + this.next() + if (this.tok.type === __acorn.tokTypes.eof) return this.finishNode(node, "EmptyStatement") + return this.parseStatement() + } else if (starttype === __acorn.tokTypes.name && expr.type === "Identifier" && this.eat(__acorn.tokTypes.colon)) { + node.body = this.parseStatement() + node.label = expr + return this.finishNode(node, "LabeledStatement") + } else { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") + } + } +} + +lp$1.parseBlock = function() { + var this$1 = this; + + var node = this.startNode() + this.pushCx() + this.expect(__acorn.tokTypes.braceL) + var blockIndent = this.curIndent, line = this.curLineStart + node.body = [] + while (!this.closes(__acorn.tokTypes.braceR, blockIndent, line, true)) + node.body.push(this$1.parseStatement()) + this.popCx() + this.eat(__acorn.tokTypes.braceR) + return this.finishNode(node, "BlockStatement") +} + +lp$1.parseFor = function(node, init) { + node.init = init + node.test = node.update = null + if (this.eat(__acorn.tokTypes.semi) && this.tok.type !== __acorn.tokTypes.semi) node.test = this.parseExpression() + if (this.eat(__acorn.tokTypes.semi) && this.tok.type !== __acorn.tokTypes.parenR) node.update = this.parseExpression() + this.popCx() + this.expect(__acorn.tokTypes.parenR) + node.body = this.parseStatement() + return this.finishNode(node, "ForStatement") +} + +lp$1.parseForIn = function(node, init) { + var type = this.tok.type === __acorn.tokTypes._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.popCx() + this.expect(__acorn.tokTypes.parenR) + node.body = this.parseStatement() + return this.finishNode(node, type) +} + +lp$1.parseVar = function(noIn, kind) { + var this$1 = this; + + var node = this.startNode() + node.kind = kind + this.next() + node.declarations = [] + do { + var decl = this$1.startNode() + decl.id = this$1.options.ecmaVersion >= 6 ? this$1.toAssignable(this$1.parseExprAtom(), true) : this$1.parseIdent() + decl.init = this$1.eat(__acorn.tokTypes.eq) ? this$1.parseMaybeAssign(noIn) : null + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + } while (this.eat(__acorn.tokTypes.comma)) + if (!node.declarations.length) { + var decl$1 = this.startNode() + decl$1.id = this.dummyIdent() + node.declarations.push(this.finishNode(decl$1, "VariableDeclarator")) + } + if (!noIn) this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +lp$1.parseClass = function(isStatement) { + var this$1 = this; + + var node = this.startNode() + this.next() + if (isStatement == null) isStatement = this.tok.type === __acorn.tokTypes.name + if (this.tok.type === __acorn.tokTypes.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + else node.id = null + node.superClass = this.eat(__acorn.tokTypes._extends) ? this.parseExpression() : null + node.body = this.startNode() + node.body.body = [] + this.pushCx() + var indent = this.curIndent + 1, line = this.curLineStart + this.eat(__acorn.tokTypes.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(__acorn.tokTypes.braceR, indent, line)) { + if (this$1.semicolon()) continue + var method = this$1.startNode(), isGenerator, isAsync + if (this$1.options.ecmaVersion >= 6) { + method.static = false + isGenerator = this$1.eat(__acorn.tokTypes.star) + } + this$1.parsePropertyName(method) + if (isDummy(method.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(__acorn.tokTypes.comma); continue } + if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" && + (this$1.tok.type != __acorn.tokTypes.parenL && this$1.tok.type != __acorn.tokTypes.braceL)) { + method.static = true + isGenerator = this$1.eat(__acorn.tokTypes.star) + this$1.parsePropertyName(method) + } else { + method.static = false + } + if (!method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this$1.tok.type !== __acorn.tokTypes.parenL && + !this$1.canInsertSemicolon()) { + this$1.parsePropertyName(method) + isAsync = true + } else { + isAsync = false + } + if (this$1.options.ecmaVersion >= 5 && method.key.type === "Identifier" && + !method.computed && (method.key.name === "get" || method.key.name === "set") && + this$1.tok.type !== __acorn.tokTypes.parenL && this$1.tok.type !== __acorn.tokTypes.braceL) { + method.kind = method.key.name + this$1.parsePropertyName(method) + method.value = this$1.parseMethod(false) + } else { + if (!method.computed && !method.static && !isGenerator && !isAsync && ( + method.key.type === "Identifier" && method.key.name === "constructor" || + method.key.type === "Literal" && method.key.value === "constructor")) { + method.kind = "constructor" + } else { + method.kind = "method" + } + method.value = this$1.parseMethod(isGenerator, isAsync) + } + node.body.body.push(this$1.finishNode(method, "MethodDefinition")) + } + this.popCx() + if (!this.eat(__acorn.tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + this.semicolon() + this.finishNode(node.body, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +lp$1.parseFunction = function(node, isStatement, isAsync) { + var oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) { + node.generator = this.eat(__acorn.tokTypes.star) + } + if (this.options.ecmaVersion >= 8) { + node.async = !!isAsync + } + if (isStatement == null) isStatement = this.tok.type === __acorn.tokTypes.name + if (this.tok.type === __acorn.tokTypes.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.body = this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +lp$1.parseExport = function() { + var node = this.startNode() + this.next() + if (this.eat(__acorn.tokTypes.star)) { + node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(__acorn.tokTypes._default)) { + // export default (function foo() {}) // This is FunctionExpression. + var isAsync + if (this.tok.type === __acorn.tokTypes._function || (isAsync = this.toks.isAsyncFunction())) { + var fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, isAsync) + } else if (this.tok.type === __acorn.tokTypes._class) { + node.declaration = this.parseClass(null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) { + node.declaration = this.parseStatement() + node.specifiers = [] + node.source = null + } else { + node.declaration = null + node.specifiers = this.parseExportSpecifierList() + node.source = this.eatContextual("from") ? this.parseExprAtom() : null + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +lp$1.parseImport = function() { + var node = this.startNode() + this.next() + if (this.tok.type === __acorn.tokTypes.string) { + node.specifiers = [] + node.source = this.parseExprAtom() + node.kind = '' + } else { + var elt + if (this.tok.type === __acorn.tokTypes.name && this.tok.value !== "from") { + elt = this.startNode() + elt.local = this.parseIdent() + this.finishNode(elt, "ImportDefaultSpecifier") + this.eat(__acorn.tokTypes.comma) + } + node.specifiers = this.parseImportSpecifierList() + node.source = this.eatContextual("from") && this.tok.type == __acorn.tokTypes.string ? this.parseExprAtom() : this.dummyString() + if (elt) node.specifiers.unshift(elt) + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +lp$1.parseImportSpecifierList = function() { + var this$1 = this; + + var elts = [] + if (this.tok.type === __acorn.tokTypes.star) { + var elt = this.startNode() + this.next() + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent() + elts.push(this.finishNode(elt, "ImportNamespaceSpecifier")) + } else { + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(__acorn.tokTypes.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(__acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + var elt$1 = this$1.startNode() + if (this$1.eat(__acorn.tokTypes.star)) { + elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : this$1.dummyIdent() + this$1.finishNode(elt$1, "ImportNamespaceSpecifier") + } else { + if (this$1.isContextual("from")) break + elt$1.imported = this$1.parseIdent() + if (isDummy(elt$1.imported)) break + elt$1.local = this$1.eatContextual("as") ? this$1.parseIdent() : elt$1.imported + this$1.finishNode(elt$1, "ImportSpecifier") + } + elts.push(elt$1) + this$1.eat(__acorn.tokTypes.comma) + } + this.eat(__acorn.tokTypes.braceR) + this.popCx() + } + return elts +} + +lp$1.parseExportSpecifierList = function() { + var this$1 = this; + + var elts = [] + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(__acorn.tokTypes.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(__acorn.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this$1.isContextual("from")) break + var elt = this$1.startNode() + elt.local = this$1.parseIdent() + if (isDummy(elt.local)) break + elt.exported = this$1.eatContextual("as") ? this$1.parseIdent() : elt.local + this$1.finishNode(elt, "ExportSpecifier") + elts.push(elt) + this$1.eat(__acorn.tokTypes.comma) + } + this.eat(__acorn.tokTypes.braceR) + this.popCx() + return elts +} + +var lp$2 = LooseParser.prototype + +lp$2.checkLVal = function(expr) { + if (!expr) return expr + switch (expr.type) { + case "Identifier": + case "MemberExpression": + return expr + + case "ParenthesizedExpression": + expr.expression = this.checkLVal(expr.expression) + return expr + + default: + return this.dummyIdent() + } +} + +lp$2.parseExpression = function(noIn) { + var this$1 = this; + + var start = this.storeCurrentPos() + var expr = this.parseMaybeAssign(noIn) + if (this.tok.type === __acorn.tokTypes.comma) { + var node = this.startNodeAt(start) + node.expressions = [expr] + while (this.eat(__acorn.tokTypes.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +lp$2.parseParenExpression = function() { + this.pushCx() + this.expect(__acorn.tokTypes.parenL) + var val = this.parseExpression() + this.popCx() + this.expect(__acorn.tokTypes.parenR) + return val +} + +lp$2.parseMaybeAssign = function(noIn) { + if (this.toks.isContextual("yield")) { + var node = this.startNode() + this.next() + if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != __acorn.tokTypes.star && !this.tok.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(__acorn.tokTypes.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") + } + + var start = this.storeCurrentPos() + var left = this.parseMaybeConditional(noIn) + if (this.tok.type.isAssign) { + var node$1 = this.startNodeAt(start) + node$1.operator = this.tok.value + node$1.left = this.tok.type === __acorn.tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left) + this.next() + node$1.right = this.parseMaybeAssign(noIn) + return this.finishNode(node$1, "AssignmentExpression") + } + return left +} + +lp$2.parseMaybeConditional = function(noIn) { + var start = this.storeCurrentPos() + var expr = this.parseExprOps(noIn) + if (this.eat(__acorn.tokTypes.question)) { + var node = this.startNodeAt(start) + node.test = expr + node.consequent = this.parseMaybeAssign() + node.alternate = this.expect(__acorn.tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent() + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +lp$2.parseExprOps = function(noIn) { + var start = this.storeCurrentPos() + var indent = this.curIndent, line = this.curLineStart + return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line) +} + +lp$2.parseExprOp = function(left, start, minPrec, noIn, indent, line) { + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left + var prec = this.tok.type.binop + if (prec != null && (!noIn || this.tok.type !== __acorn.tokTypes._in)) { + if (prec > minPrec) { + var node = this.startNodeAt(start) + node.left = left + node.operator = this.tok.value + this.next() + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) { + node.right = this.dummyIdent() + } else { + var rightStart = this.storeCurrentPos() + node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line) + } + this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression") + return this.parseExprOp(node, start, minPrec, noIn, indent, line) + } + } + return left +} + +lp$2.parseMaybeUnary = function(sawUnary) { + var this$1 = this; + + var start = this.storeCurrentPos(), expr + if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) { + expr = this.parseAwait() + sawUnary = true + } else if (this.tok.type.prefix) { + var node = this.startNode(), update = this.tok.type === __acorn.tokTypes.incDec + if (!update) sawUnary = true + node.operator = this.tok.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(true) + if (update) node.argument = this.checkLVal(node.argument) + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else if (this.tok.type === __acorn.tokTypes.ellipsis) { + var node$1 = this.startNode() + this.next() + node$1.argument = this.parseMaybeUnary(sawUnary) + expr = this.finishNode(node$1, "SpreadElement") + } else { + expr = this.parseExprSubscripts() + while (this.tok.type.postfix && !this.canInsertSemicolon()) { + var node$2 = this$1.startNodeAt(start) + node$2.operator = this$1.tok.value + node$2.prefix = false + node$2.argument = this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$2, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(__acorn.tokTypes.starstar)) { + var node$3 = this.startNodeAt(start) + node$3.operator = "**" + node$3.left = expr + node$3.right = this.parseMaybeUnary(false) + return this.finishNode(node$3, "BinaryExpression") + } + + return expr +} + +lp$2.parseExprSubscripts = function() { + var start = this.storeCurrentPos() + return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart) +} + +lp$2.parseSubscripts = function(base, start, noCalls, startIndent, line) { + var this$1 = this; + + for (;;) { + if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) { + if (this$1.tok.type == __acorn.tokTypes.dot && this$1.curIndent == startIndent) + --startIndent + else + return base + } + + var maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this$1.canInsertSemicolon() + + if (this$1.eat(__acorn.tokTypes.dot)) { + var node = this$1.startNodeAt(start) + node.object = base + if (this$1.curLineStart != line && this$1.curIndent <= startIndent && this$1.tokenStartsLine()) + node.property = this$1.dummyIdent() + else + node.property = this$1.parsePropertyAccessor() || this$1.dummyIdent() + node.computed = false + base = this$1.finishNode(node, "MemberExpression") + } else if (this$1.tok.type == __acorn.tokTypes.bracketL) { + this$1.pushCx() + this$1.next() + var node$1 = this$1.startNodeAt(start) + node$1.object = base + node$1.property = this$1.parseExpression() + node$1.computed = true + this$1.popCx() + this$1.expect(__acorn.tokTypes.bracketR) + base = this$1.finishNode(node$1, "MemberExpression") + } else if (!noCalls && this$1.tok.type == __acorn.tokTypes.parenL) { + var exprList = this$1.parseExprList(__acorn.tokTypes.parenR) + if (maybeAsyncArrow && this$1.eat(__acorn.tokTypes.arrow)) + return this$1.parseArrowExpression(this$1.startNodeAt(start), exprList, true) + var node$2 = this$1.startNodeAt(start) + node$2.callee = base + node$2.arguments = exprList + base = this$1.finishNode(node$2, "CallExpression") + } else if (this$1.tok.type == __acorn.tokTypes.backQuote) { + var node$3 = this$1.startNodeAt(start) + node$3.tag = base + node$3.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$3, "TaggedTemplateExpression") + } else { + return base + } + } +} + +lp$2.parseExprAtom = function() { + var node + switch (this.tok.type) { + case __acorn.tokTypes._this: + case __acorn.tokTypes._super: + var type = this.tok.type === __acorn.tokTypes._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case __acorn.tokTypes.name: + var start = this.storeCurrentPos() + var id = this.parseIdent() + var isAsync = false + if (id.name === "async" && !this.canInsertSemicolon()) { + if (this.eat(__acorn.tokTypes._function)) + return this.parseFunction(this.startNodeAt(start), false, true) + if (this.tok.type === __acorn.tokTypes.name) { + id = this.parseIdent() + isAsync = true + } + } + return this.eat(__acorn.tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id + + case __acorn.tokTypes.regexp: + node = this.startNode() + var val = this.tok.value + node.regex = {pattern: val.pattern, flags: val.flags} + node.value = val.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case __acorn.tokTypes.num: case __acorn.tokTypes.string: + node = this.startNode() + node.value = this.tok.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case __acorn.tokTypes._null: case __acorn.tokTypes._true: case __acorn.tokTypes._false: + node = this.startNode() + node.value = this.tok.type === __acorn.tokTypes._null ? null : this.tok.type === __acorn.tokTypes._true + node.raw = this.tok.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case __acorn.tokTypes.parenL: + var parenStart = this.storeCurrentPos() + this.next() + var inner = this.parseExpression() + this.expect(__acorn.tokTypes.parenR) + if (this.eat(__acorn.tokTypes.arrow)) { + // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy. + var params = inner.expressions || [inner] + if (params.length && isDummy(params[params.length - 1])) + params.pop() + return this.parseArrowExpression(this.startNodeAt(parenStart), params) + } + if (this.options.preserveParens) { + var par = this.startNodeAt(parenStart) + par.expression = inner + inner = this.finishNode(par, "ParenthesizedExpression") + } + return inner + + case __acorn.tokTypes.bracketL: + node = this.startNode() + node.elements = this.parseExprList(__acorn.tokTypes.bracketR, true) + return this.finishNode(node, "ArrayExpression") + + case __acorn.tokTypes.braceL: + return this.parseObj() + + case __acorn.tokTypes._class: + return this.parseClass(false) + + case __acorn.tokTypes._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case __acorn.tokTypes._new: + return this.parseNew() + + case __acorn.tokTypes.backQuote: + return this.parseTemplate() + + default: + return this.dummyIdent() + } +} + +lp$2.parseNew = function() { + var node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(__acorn.tokTypes.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + return this.finishNode(node, "MetaProperty") + } + var start = this.storeCurrentPos() + node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line) + if (this.tok.type == __acorn.tokTypes.parenL) { + node.arguments = this.parseExprList(__acorn.tokTypes.parenR) + } else { + node.arguments = [] + } + return this.finishNode(node, "NewExpression") +} + +lp$2.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, '\n'), + cooked: this.tok.value + } + this.next() + elem.tail = this.tok.type === __acorn.tokTypes.backQuote + return this.finishNode(elem, "TemplateElement") +} + +lp$2.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.next() + node.expressions.push(this$1.parseExpression()) + if (this$1.expect(__acorn.tokTypes.braceR)) { + curElt = this$1.parseTemplateElement() + } else { + curElt = this$1.startNode() + curElt.value = {cooked: '', raw: ''} + curElt.tail = true + this$1.finishNode(curElt, "TemplateElement") + } + node.quasis.push(curElt) + } + this.expect(__acorn.tokTypes.backQuote) + return this.finishNode(node, "TemplateLiteral") +} + +lp$2.parseObj = function() { + var this$1 = this; + + var node = this.startNode() + node.properties = [] + this.pushCx() + var indent = this.curIndent + 1, line = this.curLineStart + this.eat(__acorn.tokTypes.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(__acorn.tokTypes.braceR, indent, line)) { + var prop = this$1.startNode(), isGenerator, isAsync, start + if (this$1.options.ecmaVersion >= 6) { + start = this$1.storeCurrentPos() + prop.method = false + prop.shorthand = false + isGenerator = this$1.eat(__acorn.tokTypes.star) + } + this$1.parsePropertyName(prop) + if (!prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this$1.tok.type !== __acorn.tokTypes.parenL && + this$1.tok.type !== __acorn.tokTypes.colon && !this$1.canInsertSemicolon()) { + this$1.parsePropertyName(prop) + isAsync = true + } else { + isAsync = false + } + if (isDummy(prop.key)) { if (isDummy(this$1.parseMaybeAssign())) this$1.next(); this$1.eat(__acorn.tokTypes.comma); continue } + if (this$1.eat(__acorn.tokTypes.colon)) { + prop.kind = "init" + prop.value = this$1.parseMaybeAssign() + } else if (this$1.options.ecmaVersion >= 6 && (this$1.tok.type === __acorn.tokTypes.parenL || this$1.tok.type === __acorn.tokTypes.braceL)) { + prop.kind = "init" + prop.method = true + prop.value = this$1.parseMethod(isGenerator, isAsync) + } else if (this$1.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && + !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && + (this$1.tok.type != __acorn.tokTypes.comma && this$1.tok.type != __acorn.tokTypes.braceR)) { + prop.kind = prop.key.name + this$1.parsePropertyName(prop) + prop.value = this$1.parseMethod(false) + } else { + prop.kind = "init" + if (this$1.options.ecmaVersion >= 6) { + if (this$1.eat(__acorn.tokTypes.eq)) { + var assign = this$1.startNodeAt(start) + assign.operator = "=" + assign.left = prop.key + assign.right = this$1.parseMaybeAssign() + prop.value = this$1.finishNode(assign, "AssignmentExpression") + } else { + prop.value = prop.key + } + } else { + prop.value = this$1.dummyIdent() + } + prop.shorthand = true + } + node.properties.push(this$1.finishNode(prop, "Property")) + this$1.eat(__acorn.tokTypes.comma) + } + this.popCx() + if (!this.eat(__acorn.tokTypes.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return this.finishNode(node, "ObjectExpression") +} + +lp$2.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(__acorn.tokTypes.bracketL)) { + prop.computed = true + prop.key = this.parseExpression() + this.expect(__acorn.tokTypes.bracketR) + return + } else { + prop.computed = false + } + } + var key = (this.tok.type === __acorn.tokTypes.num || this.tok.type === __acorn.tokTypes.string) ? this.parseExprAtom() : this.parseIdent() + prop.key = key || this.dummyIdent() +} + +lp$2.parsePropertyAccessor = function() { + if (this.tok.type === __acorn.tokTypes.name || this.tok.type.keyword) return this.parseIdent() +} + +lp$2.parseIdent = function() { + var name = this.tok.type === __acorn.tokTypes.name ? this.tok.value : this.tok.type.keyword + if (!name) return this.dummyIdent() + var node = this.startNode() + this.next() + node.name = name + return this.finishNode(node, "Identifier") +} + +lp$2.initFunction = function(node) { + node.id = null + node.params = [] + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Convert existing expression atom to assignable pattern +// if possible. + +lp$2.toAssignable = function(node, binding) { + var this$1 = this; + + if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) { + // Okay + } else if (node.type == "ParenthesizedExpression") { + node.expression = this.toAssignable(node.expression, binding) + } else if (this.options.ecmaVersion < 6) { + return this.dummyIdent() + } else if (node.type == "ObjectExpression") { + node.type = "ObjectPattern" + var props = node.properties + for (var i = 0; i < props.length; i++) + props[i].value = this$1.toAssignable(props[i].value, binding) + } else if (node.type == "ArrayExpression") { + node.type = "ArrayPattern" + this.toAssignableList(node.elements, binding) + } else if (node.type == "SpreadElement") { + node.type = "RestElement" + node.argument = this.toAssignable(node.argument, binding) + } else if (node.type == "AssignmentExpression") { + node.type = "AssignmentPattern" + delete node.operator + } else { + return this.dummyIdent() + } + return node +} + +lp$2.toAssignableList = function(exprList, binding) { + var this$1 = this; + + for (var i = 0; i < exprList.length; i++) + exprList[i] = this$1.toAssignable(exprList[i], binding) + return exprList +} + +lp$2.parseFunctionParams = function(params) { + params = this.parseExprList(__acorn.tokTypes.parenR) + return this.toAssignableList(params, true) +} + +lp$2.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = !!isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== __acorn.tokTypes.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "FunctionExpression") +} + +lp$2.parseArrowExpression = function(node, params, isAsync) { + var oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.toAssignableList(params, true) + node.expression = this.tok.type !== __acorn.tokTypes.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "ArrowFunctionExpression") +} + +lp$2.parseExprList = function(close, allowEmpty) { + var this$1 = this; + + this.pushCx() + var indent = this.curIndent, line = this.curLineStart, elts = [] + this.next() // Opening bracket + while (!this.closes(close, indent + 1, line)) { + if (this$1.eat(__acorn.tokTypes.comma)) { + elts.push(allowEmpty ? null : this$1.dummyIdent()) + continue + } + var elt = this$1.parseMaybeAssign() + if (isDummy(elt)) { + if (this$1.closes(close, indent, line)) break + this$1.next() + } else { + elts.push(elt) + } + this$1.eat(__acorn.tokTypes.comma) + } + this.popCx() + if (!this.eat(close)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return elts +} + +lp$2.parseAwait = function() { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary() + return this.finishNode(node, "AwaitExpression") +} + +// Acorn: Loose parser +// +// This module provides an alternative parser (`parse_dammit`) that +// exposes that same interface as `parse`, but will try to parse +// anything as JavaScript, repairing syntax error the best it can. +// There are circumstances in which it will raise an error and give +// up, but they are very rare. The resulting AST will be a mostly +// valid JavaScript AST (as per the [Mozilla parser API][api], except +// that: +// +// - Return outside functions is allowed +// +// - Label consistency (no conflicts, break only to existing labels) +// is not enforced. +// +// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever +// the parser got too confused to return anything meaningful. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API +// +// The expected use for this is to *first* try `acorn.parse`, and only +// if that fails switch to `parse_dammit`. The loose parser might +// parse badly indented code incorrectly, so **don't** use it as +// your default parser. +// +// Quite a lot of acorn.js is duplicated here. The alternative was to +// add a *lot* of extra cruft to that file, making it less readable +// and slower. Copying and editing the code allowed me to make +// invasive changes and simplifications without creating a complicated +// tangle. + +__acorn.defaultOptions.tabSize = 4 + +function parse_dammit(input, options) { + var p = new LooseParser(input, options) + p.next() + return p.parseTopLevel() +} + +__acorn.addLooseExports(parse_dammit, LooseParser, pluginsLoose) + +exports.parse_dammit = parse_dammit; +exports.LooseParser = LooseParser; +exports.pluginsLoose = pluginsLoose; + +Object.defineProperty(exports, '__esModule', { value: true }); + +})));
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.es.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.es.js new file mode 100644 index 000000000..b717ed996 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.es.js @@ -0,0 +1,342 @@ +// AST walker module for Mozilla Parser API compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All Parser API node types +// can be used to identify node types, as well as Expression, +// Statement, and ScopeBody, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +function simple(node, visitors, base, state, override) { + if (!base) base = exports.base + ;(function c(node, st, override) { + var type = override || node.type, found = visitors[type] + base[type](node, st, c) + if (found) found(node, st) + })(node, state, override) +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, base, state) { + if (!base) base = exports.base + var ancestors = [] + ;(function c(node, st, override) { + var type = override || node.type, found = visitors[type] + var isNew = node != ancestors[ancestors.length - 1] + if (isNew) ancestors.push(node) + base[type](node, st, c) + if (found) found(node, st || ancestors, ancestors) + if (isNew) ancestors.pop() + })(node, state) +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +function recursive(node, state, funcs, base, override) { + var visitor = funcs ? exports.make(funcs, base) : base + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c) + })(node, state, override) +} + +function makeTest(test) { + if (typeof test == "string") + return function (type) { return type == test; } + else if (!test) + return function () { return true; } + else + return test +} + +var Found = function Found(node, state) { this.node = node; this.state = state }; + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +function findNodeAt(node, start, end, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + var type = override || node.type + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + base[type](node, st, c) + if ((start == null || node.start == start) && + (end == null || node.end == end) && + test(type, node)) + throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + var type = override || node.type + if (node.start > pos || node.end < pos) return + base[type](node, st, c) + if (test(type, node)) throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node after a given position. +function findNodeAfter(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + if (node.end < pos) return + var type = override || node.type + if (node.start >= pos && test(type, node)) throw new Found(node, st) + base[type](node, st, c) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node before a given position. +function findNodeBefore(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + var max + ;(function c(node, st, override) { + if (node.start > pos) return + var type = override || node.type + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + max = new Found(node, st) + base[type](node, st, c) + })(node, state) + return max +} + +// Fallback to an Object.create polyfill for older environments. +var create = Object.create || function(proto) { + function Ctor() {} + Ctor.prototype = proto + return new Ctor +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +function make(funcs, base) { + if (!base) base = exports.base + var visitor = create(base) + for (var type in funcs) visitor[type] = funcs[type] + return visitor +} + +function skipThrough(node, st, c) { c(node, st) } +function ignore(_node, _st, _c) {} + +// Node walkers. + +var base = {} + +base.Program = base.BlockStatement = function (node, st, c) { + for (var i = 0; i < node.body.length; ++i) + c(node.body[i], st, "Statement") +} +base.Statement = skipThrough +base.EmptyStatement = ignore +base.ExpressionStatement = base.ParenthesizedExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); } +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression") + c(node.consequent, st, "Statement") + if (node.alternate) c(node.alternate, st, "Statement") +} +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); } +base.BreakStatement = base.ContinueStatement = ignore +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression") + c(node.body, st, "Statement") +} +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression") + for (var i = 0; i < node.cases.length; ++i) { + var cs = node.cases[i] + if (cs.test) c(cs.test, st, "Expression") + for (var j = 0; j < cs.consequent.length; ++j) + c(cs.consequent[j], st, "Statement") + } +} +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) c(node.argument, st, "Expression") +} +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); } +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement") + if (node.handler) c(node.handler, st) + if (node.finalizer) c(node.finalizer, st, "Statement") +} +base.CatchClause = function (node, st, c) { + c(node.param, st, "Pattern") + c(node.body, st, "ScopeBody") +} +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression") + c(node.body, st, "Statement") +} +base.ForStatement = function (node, st, c) { + if (node.init) c(node.init, st, "ForInit") + if (node.test) c(node.test, st, "Expression") + if (node.update) c(node.update, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit") + c(node.right, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInit = function (node, st, c) { + if (node.type == "VariableDeclaration") c(node, st) + else c(node, st, "Expression") +} +base.DebuggerStatement = ignore + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); } +base.VariableDeclaration = function (node, st, c) { + for (var i = 0; i < node.declarations.length; ++i) + c(node.declarations[i], st) +} +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern") + if (node.init) c(node.init, st, "Expression") +} + +base.Function = function (node, st, c) { + if (node.id) c(node.id, st, "Pattern") + for (var i = 0; i < node.params.length; i++) + c(node.params[i], st, "Pattern") + c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody") +} +// FIXME drop these node types in next major version +// (They are awkward, and in ES6 every block can be a scope.) +base.ScopeBody = function (node, st, c) { return c(node, st, "Statement"); } +base.ScopeExpression = function (node, st, c) { return c(node, st, "Expression"); } + +base.Pattern = function (node, st, c) { + if (node.type == "Identifier") + c(node, st, "VariablePattern") + else if (node.type == "MemberExpression") + c(node, st, "MemberPattern") + else + c(node, st) +} +base.VariablePattern = ignore +base.MemberPattern = skipThrough +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); } +base.ArrayPattern = function (node, st, c) { + for (var i = 0; i < node.elements.length; ++i) { + var elt = node.elements[i] + if (elt) c(elt, st, "Pattern") + } +} +base.ObjectPattern = function (node, st, c) { + for (var i = 0; i < node.properties.length; ++i) + c(node.properties[i].value, st, "Pattern") +} + +base.Expression = skipThrough +base.ThisExpression = base.Super = base.MetaProperty = ignore +base.ArrayExpression = function (node, st, c) { + for (var i = 0; i < node.elements.length; ++i) { + var elt = node.elements[i] + if (elt) c(elt, st, "Expression") + } +} +base.ObjectExpression = function (node, st, c) { + for (var i = 0; i < node.properties.length; ++i) + c(node.properties[i], st) +} +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration +base.SequenceExpression = base.TemplateLiteral = function (node, st, c) { + for (var i = 0; i < node.expressions.length; ++i) + c(node.expressions[i], st, "Expression") +} +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression") +} +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression") + c(node.right, st, "Expression") +} +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern") + c(node.right, st, "Expression") +} +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression") + c(node.consequent, st, "Expression") + c(node.alternate, st, "Expression") +} +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression") + if (node.arguments) for (var i = 0; i < node.arguments.length; ++i) + c(node.arguments[i], st, "Expression") +} +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression") + if (node.computed) c(node.property, st, "Expression") +} +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression") + if (node.source) c(node.source, st, "Expression") +} +base.ExportAllDeclaration = function (node, st, c) { + c(node.source, st, "Expression") +} +base.ImportDeclaration = function (node, st, c) { + for (var i = 0; i < node.specifiers.length; i++) + c(node.specifiers[i], st) + c(node.source, st, "Expression") +} +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression") + c(node.quasi, st) +} +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); } +base.Class = function (node, st, c) { + if (node.id) c(node.id, st, "Pattern") + if (node.superClass) c(node.superClass, st, "Expression") + for (var i = 0; i < node.body.body.length; i++) + c(node.body.body[i], st) +} +base.MethodDefinition = base.Property = function (node, st, c) { + if (node.computed) c(node.key, st, "Expression") + c(node.value, st, "Expression") +} + +export { simple, ancestor, recursive, findNodeAt, findNodeAround, findNodeAfter, findNodeBefore, make, base };
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.js b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.js new file mode 100644 index 000000000..3c9c59487 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.js @@ -0,0 +1,360 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.acorn = global.acorn || {}, global.acorn.walk = global.acorn.walk || {}))); +}(this, (function (exports) { 'use strict'; + +// AST walker module for Mozilla Parser API compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All Parser API node types +// can be used to identify node types, as well as Expression, +// Statement, and ScopeBody, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +function simple(node, visitors, base, state, override) { + if (!base) base = exports.base + ;(function c(node, st, override) { + var type = override || node.type, found = visitors[type] + base[type](node, st, c) + if (found) found(node, st) + })(node, state, override) +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, base, state) { + if (!base) base = exports.base + var ancestors = [] + ;(function c(node, st, override) { + var type = override || node.type, found = visitors[type] + var isNew = node != ancestors[ancestors.length - 1] + if (isNew) ancestors.push(node) + base[type](node, st, c) + if (found) found(node, st || ancestors, ancestors) + if (isNew) ancestors.pop() + })(node, state) +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +function recursive(node, state, funcs, base, override) { + var visitor = funcs ? exports.make(funcs, base) : base + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c) + })(node, state, override) +} + +function makeTest(test) { + if (typeof test == "string") + return function (type) { return type == test; } + else if (!test) + return function () { return true; } + else + return test +} + +var Found = function Found(node, state) { this.node = node; this.state = state }; + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +function findNodeAt(node, start, end, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + var type = override || node.type + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + base[type](node, st, c) + if ((start == null || node.start == start) && + (end == null || node.end == end) && + test(type, node)) + throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + var type = override || node.type + if (node.start > pos || node.end < pos) return + base[type](node, st, c) + if (test(type, node)) throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node after a given position. +function findNodeAfter(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + if (node.end < pos) return + var type = override || node.type + if (node.start >= pos && test(type, node)) throw new Found(node, st) + base[type](node, st, c) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node before a given position. +function findNodeBefore(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + var max + ;(function c(node, st, override) { + if (node.start > pos) return + var type = override || node.type + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + max = new Found(node, st) + base[type](node, st, c) + })(node, state) + return max +} + +// Fallback to an Object.create polyfill for older environments. +var create = Object.create || function(proto) { + function Ctor() {} + Ctor.prototype = proto + return new Ctor +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +function make(funcs, base) { + if (!base) base = exports.base + var visitor = create(base) + for (var type in funcs) visitor[type] = funcs[type] + return visitor +} + +function skipThrough(node, st, c) { c(node, st) } +function ignore(_node, _st, _c) {} + +// Node walkers. + +var base = {} + +base.Program = base.BlockStatement = function (node, st, c) { + for (var i = 0; i < node.body.length; ++i) + c(node.body[i], st, "Statement") +} +base.Statement = skipThrough +base.EmptyStatement = ignore +base.ExpressionStatement = base.ParenthesizedExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); } +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression") + c(node.consequent, st, "Statement") + if (node.alternate) c(node.alternate, st, "Statement") +} +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); } +base.BreakStatement = base.ContinueStatement = ignore +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression") + c(node.body, st, "Statement") +} +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression") + for (var i = 0; i < node.cases.length; ++i) { + var cs = node.cases[i] + if (cs.test) c(cs.test, st, "Expression") + for (var j = 0; j < cs.consequent.length; ++j) + c(cs.consequent[j], st, "Statement") + } +} +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) c(node.argument, st, "Expression") +} +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); } +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement") + if (node.handler) c(node.handler, st) + if (node.finalizer) c(node.finalizer, st, "Statement") +} +base.CatchClause = function (node, st, c) { + c(node.param, st, "Pattern") + c(node.body, st, "ScopeBody") +} +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression") + c(node.body, st, "Statement") +} +base.ForStatement = function (node, st, c) { + if (node.init) c(node.init, st, "ForInit") + if (node.test) c(node.test, st, "Expression") + if (node.update) c(node.update, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit") + c(node.right, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInit = function (node, st, c) { + if (node.type == "VariableDeclaration") c(node, st) + else c(node, st, "Expression") +} +base.DebuggerStatement = ignore + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); } +base.VariableDeclaration = function (node, st, c) { + for (var i = 0; i < node.declarations.length; ++i) + c(node.declarations[i], st) +} +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern") + if (node.init) c(node.init, st, "Expression") +} + +base.Function = function (node, st, c) { + if (node.id) c(node.id, st, "Pattern") + for (var i = 0; i < node.params.length; i++) + c(node.params[i], st, "Pattern") + c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody") +} +// FIXME drop these node types in next major version +// (They are awkward, and in ES6 every block can be a scope.) +base.ScopeBody = function (node, st, c) { return c(node, st, "Statement"); } +base.ScopeExpression = function (node, st, c) { return c(node, st, "Expression"); } + +base.Pattern = function (node, st, c) { + if (node.type == "Identifier") + c(node, st, "VariablePattern") + else if (node.type == "MemberExpression") + c(node, st, "MemberPattern") + else + c(node, st) +} +base.VariablePattern = ignore +base.MemberPattern = skipThrough +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); } +base.ArrayPattern = function (node, st, c) { + for (var i = 0; i < node.elements.length; ++i) { + var elt = node.elements[i] + if (elt) c(elt, st, "Pattern") + } +} +base.ObjectPattern = function (node, st, c) { + for (var i = 0; i < node.properties.length; ++i) + c(node.properties[i].value, st, "Pattern") +} + +base.Expression = skipThrough +base.ThisExpression = base.Super = base.MetaProperty = ignore +base.ArrayExpression = function (node, st, c) { + for (var i = 0; i < node.elements.length; ++i) { + var elt = node.elements[i] + if (elt) c(elt, st, "Expression") + } +} +base.ObjectExpression = function (node, st, c) { + for (var i = 0; i < node.properties.length; ++i) + c(node.properties[i], st) +} +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration +base.SequenceExpression = base.TemplateLiteral = function (node, st, c) { + for (var i = 0; i < node.expressions.length; ++i) + c(node.expressions[i], st, "Expression") +} +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression") +} +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression") + c(node.right, st, "Expression") +} +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern") + c(node.right, st, "Expression") +} +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression") + c(node.consequent, st, "Expression") + c(node.alternate, st, "Expression") +} +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression") + if (node.arguments) for (var i = 0; i < node.arguments.length; ++i) + c(node.arguments[i], st, "Expression") +} +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression") + if (node.computed) c(node.property, st, "Expression") +} +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression") + if (node.source) c(node.source, st, "Expression") +} +base.ExportAllDeclaration = function (node, st, c) { + c(node.source, st, "Expression") +} +base.ImportDeclaration = function (node, st, c) { + for (var i = 0; i < node.specifiers.length; i++) + c(node.specifiers[i], st) + c(node.source, st, "Expression") +} +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression") + c(node.quasi, st) +} +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); } +base.Class = function (node, st, c) { + if (node.id) c(node.id, st, "Pattern") + if (node.superClass) c(node.superClass, st, "Expression") + for (var i = 0; i < node.body.body.length; i++) + c(node.body.body[i], st) +} +base.MethodDefinition = base.Property = function (node, st, c) { + if (node.computed) c(node.key, st, "Expression") + c(node.value, st, "Expression") +} + +exports.simple = simple; +exports.ancestor = ancestor; +exports.recursive = recursive; +exports.findNodeAt = findNodeAt; +exports.findNodeAround = findNodeAround; +exports.findNodeAfter = findNodeAfter; +exports.findNodeBefore = findNodeBefore; +exports.make = make; +exports.base = base; + +Object.defineProperty(exports, '__esModule', { value: true }); + +})));
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/package.json b/node_modules/acorn-dynamic-import/node_modules/acorn/package.json new file mode 100644 index 000000000..29a32a787 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/package.json @@ -0,0 +1,46 @@ +{ + "name": "acorn", + "description": "ECMAScript parser", + "homepage": "https://github.com/ternjs/acorn", + "main": "dist/acorn.js", + "jsnext:main": "dist/acorn.es.js", + "version": "4.0.11", + "engines": { + "node": ">=0.4.0" + }, + "maintainers": [ + { + "name": "Marijn Haverbeke", + "email": "marijnh@gmail.com", + "web": "http://marijnhaverbeke.nl" + }, + { + "name": "Ingvar Stepanyan", + "email": "me@rreverser.com", + "web": "http://rreverser.com/" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/ternjs/acorn.git" + }, + "license": "MIT", + "scripts": { + "prepublish": "npm test", + "test": "node test/run.js", + "pretest": "npm run build", + "build": "npm run build:main && npm run build:walk && npm run build:loose && npm run build:bin", + "build:main": "rollup -c rollup/config.main.js", + "build:walk": "rollup -c rollup/config.walk.js", + "build:loose": "rollup -c rollup/config.loose.js", + "build:bin": "rollup -c rollup/config.bin.js" + }, + "bin": { + "acorn": "./bin/acorn" + }, + "devDependencies": { + "rollup": "^0.34.1", + "rollup-plugin-buble": "^0.11.0", + "unicode-9.0.0": "^0.7.0" + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/bin/acorn.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/bin/acorn.js new file mode 100644 index 000000000..62e0dad18 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/bin/acorn.js @@ -0,0 +1,60 @@ +import {basename} from "path" +import {readFileSync as readFile} from "fs" +import * as acorn from "acorn" + +let infile, forceFile, silent = false, compact = false, tokenize = false +const options = {} + +function help(status) { + const print = (status == 0) ? console.log : console.error + print("usage: " + basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]") + print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]") + process.exit(status) +} + +for (let i = 2; i < process.argv.length; ++i) { + const arg = process.argv[i] + if ((arg == "-" || arg[0] != "-") && !infile) infile = arg + else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i] + else if (arg == "--locations") options.locations = true + else if (arg == "--allow-hash-bang") options.allowHashBang = true + else if (arg == "--silent") silent = true + else if (arg == "--compact") compact = true + else if (arg == "--help") help(0) + else if (arg == "--tokenize") tokenize = true + else if (arg == "--module") options.sourceType = 'module' + else { + let match = arg.match(/^--ecma(\d+)$/) + if (match) + options.ecmaVersion = +match[1] + else + help(1) + } +} + +function run(code) { + let result + if (!tokenize) { + try { result = acorn.parse(code, options) } + catch(e) { console.error(e.message); process.exit(1) } + } else { + result = [] + let tokenizer = acorn.tokenizer(code, options), token + while (true) { + try { token = tokenizer.getToken() } + catch(e) { console.error(e.message); process.exit(1) } + result.push(token) + if (token.type == acorn.tokTypes.eof) break + } + } + if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)) +} + +if (forceFile || infile && infile != "-") { + run(readFile(infile, "utf8")) +} else { + let code = "" + process.stdin.resume() + process.stdin.on("data", chunk => code += chunk) + process.stdin.on("end", () => run(code)) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/expression.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/expression.js new file mode 100644 index 000000000..bbcd9daf3 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/expression.js @@ -0,0 +1,819 @@ +// A recursive descent parser operates by defining functions for all +// syntactic elements, and recursively calling those, each function +// advancing the input stream and returning an AST node. Precedence +// of constructs (for example, the fact that `!x[1]` means `!(x[1])` +// instead of `(!x)[1]` is handled by the fact that the parser +// function that parses unary prefix operators is called first, and +// in turn calls the function that parses `[]` subscripts — that +// way, it'll receive the node for `x[1]` already parsed, and wraps +// *that* in the unary operator node. +// +// Acorn uses an [operator precedence parser][opp] to handle binary +// operator precedence, because it is much more compact than using +// the technique outlined above, which uses different, nesting +// functions to specify precedence, for all of the ten binary +// precedence levels that JavaScript defines. +// +// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + +import {types as tt} from "./tokentype" +import {Parser} from "./state" +import {DestructuringErrors} from "./parseutil" + +const pp = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + let {key} = prop, name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + let {kind} = prop + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + let other = propHash[name] + if (other) { + let isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp.parseExpression = function(noIn, refDestructuringErrors) { + let startPos = this.start, startLoc = this.startLoc + let expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + let node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + let ownDestructuringErrors = false, oldParenAssign = -1 + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign + refDestructuringErrors.parenthesizedAssign = -1 + } else { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + + let startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + let left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + let node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = -1 // reset because shorthand default was used correctly + this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) + } + if (oldParenAssign > -1) refDestructuringErrors.parenthesizedAssign = oldParenAssign + return left +} + +// Parse a ternary conditional (`?:`) operator. + +pp.parseMaybeConditional = function(noIn, refDestructuringErrors) { + let startPos = this.start, startLoc = this.startLoc + let expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + let node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp.parseExprOps = function(noIn, refDestructuringErrors) { + let startPos = this.start, startLoc = this.startLoc + let expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + let prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + let logical = this.type === tt.logicalOR || this.type === tt.logicalAND + let op = this.value + this.next() + let startPos = this.start, startLoc = this.startLoc + let right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + let node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp.buildBinary = function(startPos, startLoc, left, right, op, logical) { + let node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + let startPos = this.start, startLoc = this.startLoc, expr + if (this.inAsync && this.isContextual("await")) { + expr = this.parseAwait(refDestructuringErrors) + sawUnary = true + } else if (this.type.prefix) { + let node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + let node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.prefix = false + node.argument = expr + this.checkLVal(expr) + this.next() + expr = this.finishNode(node, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp.parseExprSubscripts = function(refDestructuringErrors) { + let startPos = this.start, startLoc = this.startLoc + let expr = this.parseExprAtom(refDestructuringErrors) + let skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + let result = this.parseSubscripts(expr, startPos, startLoc) + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) refDestructuringErrors.parenthesizedAssign = -1 + if (refDestructuringErrors.parenthesizedBind >= result.start) refDestructuringErrors.parenthesizedBind = -1 + } + return result +} + +pp.parseSubscripts = function(base, startPos, startLoc, noCalls) { + let maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd == base.end && !this.canInsertSemicolon() + for (let computed;;) { + if ((computed = this.eat(tt.bracketL)) || this.eat(tt.dot)) { + let node = this.startNodeAt(startPos, startLoc) + node.object = base + node.property = computed ? this.parseExpression() : this.parseIdent(true) + node.computed = !!computed + if (computed) this.expect(tt.bracketR) + base = this.finishNode(node, "MemberExpression") + } else if (!noCalls && this.eat(tt.parenL)) { + let refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos + this.yieldPos = 0 + this.awaitPos = 0 + let exprList = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors) + if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false) + this.checkYieldAwaitInDefaultParams() + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true) + } + this.checkExpressionErrors(refDestructuringErrors, true) + this.yieldPos = oldYieldPos || this.yieldPos + this.awaitPos = oldAwaitPos || this.awaitPos + let node = this.startNodeAt(startPos, startLoc) + node.callee = base + node.arguments = exprList + base = this.finishNode(node, "CallExpression") + } else if (this.type === tt.backQuote) { + let node = this.startNodeAt(startPos, startLoc) + node.tag = base + node.quasi = this.parseTemplate() + base = this.finishNode(node, "TaggedTemplateExpression") + } else { + return base + } + } +} + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp.parseExprAtom = function(refDestructuringErrors) { + let node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") + + case tt._this: + let type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + let startPos = this.start, startLoc = this.startLoc + let id = this.parseIdent(this.type !== tt.name) + if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function)) + return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) { + id = this.parseIdent() + if (this.canInsertSemicolon() || !this.eat(tt.arrow)) + this.unexpected() + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + + case tt.regexp: + let value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node + + case tt.num: case tt.string: + return this.parseLiteral(this.value) + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + let start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow) + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + refDestructuringErrors.parenthesizedAssign = start + if (refDestructuringErrors.parenthesizedBind < 0) + refDestructuringErrors.parenthesizedBind = start + } + return expr + + case tt.bracketL: + node = this.startNode() + this.next() + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._class: + return this.parseClass(this.startNode(), false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + this.unexpected() + } +} + +pp.parseLiteral = function(value) { + let node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} + +pp.parseParenExpression = function() { + this.expect(tt.parenL) + let val = this.parseExpression() + this.expect(tt.parenR) + return val +} + +pp.parseParenAndDistinguishExpression = function(canBeArrow) { + let startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8 + if (this.options.ecmaVersion >= 6) { + this.next() + + let innerStartPos = this.start, innerStartLoc = this.startLoc + let exprList = [], first = true, lastIsComma = false + let refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart + this.yieldPos = 0 + this.awaitPos = 0 + while (this.type !== tt.parenR) { + first ? first = false : this.expect(tt.comma) + if (allowTrailingComma && this.afterTrailingComma(tt.parenR, true)) { + lastIsComma = true + break + } else if (this.type === tt.ellipsis) { + spreadStart = this.start + exprList.push(this.parseParenItem(this.parseRest())) + if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element") + break + } else { + if (this.type === tt.parenL && !innerParenStart) { + innerParenStart = this.start + } + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)) + } + } + let innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false) + this.checkYieldAwaitInDefaultParams() + if (innerParenStart) this.unexpected(innerParenStart) + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + this.yieldPos = oldYieldPos || this.yieldPos + this.awaitPos = oldAwaitPos || this.awaitPos + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] + } + } else { + val = this.parseParenExpression() + } + + if (this.options.preserveParens) { + let par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +} + +pp.parseParenItem = function(item) { + return item +} + +pp.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +const empty = [] + +pp.parseNew = function() { + let node = this.startNode() + let meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + let startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false) + else node.arguments = empty + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp.parseTemplateElement = function() { + let elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp.parseTemplate = function() { + let node = this.startNode() + this.next() + node.expressions = [] + let curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this.expect(tt.dollarBraceL) + node.expressions.push(this.parseExpression()) + this.expect(tt.braceR) + node.quasis.push(curElt = this.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp.parseObj = function(isPattern, refDestructuringErrors) { + let node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this.expect(tt.comma) + if (this.afterTrailingComma(tt.braceR)) break + } else first = false + + let prop = this.startNode(), isGenerator, isAsync, startPos, startLoc + if (this.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this.start + startLoc = this.startLoc + } + if (!isPattern) + isGenerator = this.eat(tt.star) + } + this.parsePropertyName(prop) + if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && !prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this.type !== tt.parenL && + this.type !== tt.colon && !this.canInsertSemicolon()) { + isAsync = true + this.parsePropertyName(prop, refDestructuringErrors) + } else { + isAsync = false + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) + this.checkPropClash(prop, propHash) + node.properties.push(this.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { + if ((isGenerator || isAsync) && this.type === tt.colon) + this.unexpected() + + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator, isAsync) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isAsync || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + let paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + let start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield") || + (this.inAsync && prop.key.name == "await")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Parse object or class method. + +pp.parseMethod = function(isGenerator, isAsync) { + let node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8) + this.checkYieldAwaitInDefaultParams() + this.parseFunctionBody(node, false) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp.parseArrowExpression = function(node, params, isAsync) { + let oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + this.inGenerator = false + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp.parseFunctionBody = function(node, isArrowFunction) { + let isExpression = isArrowFunction && this.type !== tt.braceL + let oldStrict = this.strict, useStrict = false + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + let nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params) + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end) + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list") + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + let oldLabels = this.labels + this.labels = [] + if (useStrict) this.strict = true + node.body = this.parseBlock(true) + node.expression = false + this.labels = oldLabels + } + + if (oldStrict || useStrict) { + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node) + this.strict = oldStrict + } else if (isArrowFunction || !this.isSimpleParamList(node.params)) { + this.checkParams(node) + } +} + +pp.isSimpleParamList = function(params) { + for (let i = 0; i < params.length; i++) + if (params[i].type !== "Identifier") return false + return true +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp.checkParams = function(node) { + let nameHash = {} + for (let i = 0; i < node.params.length; i++) this.checkLVal(node.params[i], true, nameHash) +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + let elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this.expect(tt.comma) + if (allowTrailingComma && this.afterTrailingComma(close)) break + } else first = false + + let elt + if (allowEmpty && this.type === tt.comma) + elt = null + else if (this.type === tt.ellipsis) { + elt = this.parseSpread(refDestructuringErrors) + if (refDestructuringErrors && this.type === tt.comma && refDestructuringErrors.trailingComma < 0) + refDestructuringErrors.trailingComma = this.start + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors) + } + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp.parseIdent = function(liberal) { + let node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + if (this.inAsync && this.value === "await") + this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp.parseYield = function() { + if (!this.yieldPos) this.yieldPos = this.start + + let node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +pp.parseAwait = function() { + if (!this.awaitPos) this.awaitPos = this.start + + let node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary(null, true) + return this.finishNode(node, "AwaitExpression") +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/identifier.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/identifier.js new file mode 100644 index 000000000..c65a24cf5 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/identifier.js @@ -0,0 +1,81 @@ +// Reserved word lists for various dialects of the language + +export const reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +export const keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + let pos = 0x10000 + for (let i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +export function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +export function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/index.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/index.js new file mode 100644 index 000000000..3f93d1e53 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/index.js @@ -0,0 +1,77 @@ +// Acorn is a tiny, fast JavaScript parser written in JavaScript. +// +// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and +// various contributors and released under an MIT license. +// +// Git repositories for Acorn are available at +// +// http://marijnhaverbeke.nl/git/acorn +// https://github.com/ternjs/acorn.git +// +// Please use the [github bug tracker][ghbt] to report issues. +// +// [ghbt]: https://github.com/ternjs/acorn/issues +// +// This file defines the main parser interface. The library also comes +// with a [error-tolerant parser][dammit] and an +// [abstract syntax tree walker][walk], defined in other files. +// +// [dammit]: acorn_loose.js +// [walk]: util/walk.js + +import {Parser} from "./state" +import "./parseutil" +import "./statement" +import "./lval" +import "./expression" +import "./location" + +export {Parser, plugins} from "./state" +export {defaultOptions} from "./options" +export {Position, SourceLocation, getLineInfo} from "./locutil" +export {Node} from "./node" +export {TokenType, types as tokTypes, keywords as keywordTypes} from "./tokentype" +export {TokContext, types as tokContexts} from "./tokencontext" +export {isIdentifierChar, isIdentifierStart} from "./identifier" +export {Token} from "./tokenize" +export {isNewLine, lineBreak, lineBreakG} from "./whitespace" + +export const version = "4.0.11" + +// The main exported interface (under `self.acorn` when in the +// browser) is a `parse` function that takes a code string and +// returns an abstract syntax tree as specified by [Mozilla parser +// API][api]. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + +export function parse(input, options) { + return new Parser(options, input).parse() +} + +// This function tries to parse a single expression at a given +// offset in a string. Useful for parsing mixed-language formats +// that embed JavaScript expressions. + +export function parseExpressionAt(input, pos, options) { + let p = new Parser(options, input, pos) + p.nextToken() + return p.parseExpression() +} + +// Acorn is organized as a tokenizer and a recursive-descent parser. +// The `tokenizer` export provides an interface to the tokenizer. + +export function tokenizer(input, options) { + return new Parser(options, input) +} + +// This is a terrible kludge to support the existing, pre-ES6 +// interface where the loose parser module retroactively adds exports +// to this module. +export let parse_dammit, LooseParser, pluginsLoose +export function addLooseExports(parse, Parser, plugins) { + parse_dammit = parse + LooseParser = Parser + pluginsLoose = plugins +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/location.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/location.js new file mode 100644 index 000000000..99e71234c --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/location.js @@ -0,0 +1,26 @@ +import {Parser} from "./state" +import {Position, getLineInfo} from "./locutil" + +const pp = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp.raise = function(pos, message) { + let loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + let err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp.raiseRecoverable = pp.raise + +pp.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/locutil.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/locutil.js new file mode 100644 index 000000000..5a9465e01 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/locutil.js @@ -0,0 +1,42 @@ +import {lineBreakG} from "./whitespace" + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +export class Position { + constructor(line, col) { + this.line = line + this.column = col + } + + offset(n) { + return new Position(this.line, this.column + n) + } +} + +export class SourceLocation { + constructor(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile + } +} + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +export function getLineInfo(input, offset) { + for (let line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + let match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/expression.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/expression.js new file mode 100644 index 000000000..321ca6640 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/expression.js @@ -0,0 +1,562 @@ +import {LooseParser} from "./state" +import {isDummy} from "./parseutil" +import {tokTypes as tt} from "../index" + +const lp = LooseParser.prototype + +lp.checkLVal = function(expr) { + if (!expr) return expr + switch (expr.type) { + case "Identifier": + case "MemberExpression": + return expr + + case "ParenthesizedExpression": + expr.expression = this.checkLVal(expr.expression) + return expr + + default: + return this.dummyIdent() + } +} + +lp.parseExpression = function(noIn) { + let start = this.storeCurrentPos() + let expr = this.parseMaybeAssign(noIn) + if (this.tok.type === tt.comma) { + let node = this.startNodeAt(start) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +lp.parseParenExpression = function() { + this.pushCx() + this.expect(tt.parenL) + let val = this.parseExpression() + this.popCx() + this.expect(tt.parenR) + return val +} + +lp.parseMaybeAssign = function(noIn) { + if (this.toks.isContextual("yield")) { + let node = this.startNode() + this.next() + if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != tt.star && !this.tok.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") + } + + let start = this.storeCurrentPos() + let left = this.parseMaybeConditional(noIn) + if (this.tok.type.isAssign) { + let node = this.startNodeAt(start) + node.operator = this.tok.value + node.left = this.tok.type === tt.eq ? this.toAssignable(left) : this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } + return left +} + +lp.parseMaybeConditional = function(noIn) { + let start = this.storeCurrentPos() + let expr = this.parseExprOps(noIn) + if (this.eat(tt.question)) { + let node = this.startNodeAt(start) + node.test = expr + node.consequent = this.parseMaybeAssign() + node.alternate = this.expect(tt.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent() + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +lp.parseExprOps = function(noIn) { + let start = this.storeCurrentPos() + let indent = this.curIndent, line = this.curLineStart + return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line) +} + +lp.parseExprOp = function(left, start, minPrec, noIn, indent, line) { + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left + let prec = this.tok.type.binop + if (prec != null && (!noIn || this.tok.type !== tt._in)) { + if (prec > minPrec) { + let node = this.startNodeAt(start) + node.left = left + node.operator = this.tok.value + this.next() + if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) { + node.right = this.dummyIdent() + } else { + let rightStart = this.storeCurrentPos() + node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line) + } + this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression") + return this.parseExprOp(node, start, minPrec, noIn, indent, line) + } + } + return left +} + +lp.parseMaybeUnary = function(sawUnary) { + let start = this.storeCurrentPos(), expr + if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) { + expr = this.parseAwait() + sawUnary = true + } else if (this.tok.type.prefix) { + let node = this.startNode(), update = this.tok.type === tt.incDec + if (!update) sawUnary = true + node.operator = this.tok.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(true) + if (update) node.argument = this.checkLVal(node.argument) + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else if (this.tok.type === tt.ellipsis) { + let node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary(sawUnary) + expr = this.finishNode(node, "SpreadElement") + } else { + expr = this.parseExprSubscripts() + while (this.tok.type.postfix && !this.canInsertSemicolon()) { + let node = this.startNodeAt(start) + node.operator = this.tok.value + node.prefix = false + node.argument = this.checkLVal(expr) + this.next() + expr = this.finishNode(node, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) { + let node = this.startNodeAt(start) + node.operator = "**" + node.left = expr + node.right = this.parseMaybeUnary(false) + return this.finishNode(node, "BinaryExpression") + } + + return expr +} + +lp.parseExprSubscripts = function() { + let start = this.storeCurrentPos() + return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart) +} + +lp.parseSubscripts = function(base, start, noCalls, startIndent, line) { + for (;;) { + if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) { + if (this.tok.type == tt.dot && this.curIndent == startIndent) + --startIndent + else + return base + } + + let maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon() + + if (this.eat(tt.dot)) { + let node = this.startNodeAt(start) + node.object = base + if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) + node.property = this.dummyIdent() + else + node.property = this.parsePropertyAccessor() || this.dummyIdent() + node.computed = false + base = this.finishNode(node, "MemberExpression") + } else if (this.tok.type == tt.bracketL) { + this.pushCx() + this.next() + let node = this.startNodeAt(start) + node.object = base + node.property = this.parseExpression() + node.computed = true + this.popCx() + this.expect(tt.bracketR) + base = this.finishNode(node, "MemberExpression") + } else if (!noCalls && this.tok.type == tt.parenL) { + let exprList = this.parseExprList(tt.parenR) + if (maybeAsyncArrow && this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(start), exprList, true) + let node = this.startNodeAt(start) + node.callee = base + node.arguments = exprList + base = this.finishNode(node, "CallExpression") + } else if (this.tok.type == tt.backQuote) { + let node = this.startNodeAt(start) + node.tag = base + node.quasi = this.parseTemplate() + base = this.finishNode(node, "TaggedTemplateExpression") + } else { + return base + } + } +} + +lp.parseExprAtom = function() { + let node + switch (this.tok.type) { + case tt._this: + case tt._super: + let type = this.tok.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + let start = this.storeCurrentPos() + let id = this.parseIdent() + let isAsync = false + if (id.name === "async" && !this.canInsertSemicolon()) { + if (this.eat(tt._function)) + return this.parseFunction(this.startNodeAt(start), false, true) + if (this.tok.type === tt.name) { + id = this.parseIdent() + isAsync = true + } + } + return this.eat(tt.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id + + case tt.regexp: + node = this.startNode() + let val = this.tok.value + node.regex = {pattern: val.pattern, flags: val.flags} + node.value = val.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case tt.num: case tt.string: + node = this.startNode() + node.value = this.tok.value + node.raw = this.input.slice(this.tok.start, this.tok.end) + this.next() + return this.finishNode(node, "Literal") + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.tok.type === tt._null ? null : this.tok.type === tt._true + node.raw = this.tok.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + let parenStart = this.storeCurrentPos() + this.next() + let inner = this.parseExpression() + this.expect(tt.parenR) + if (this.eat(tt.arrow)) { + // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy. + let params = inner.expressions || [inner] + if (params.length && isDummy(params[params.length - 1])) + params.pop() + return this.parseArrowExpression(this.startNodeAt(parenStart), params) + } + if (this.options.preserveParens) { + let par = this.startNodeAt(parenStart) + par.expression = inner + inner = this.finishNode(par, "ParenthesizedExpression") + } + return inner + + case tt.bracketL: + node = this.startNode() + node.elements = this.parseExprList(tt.bracketR, true) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj() + + case tt._class: + return this.parseClass(false) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + return this.dummyIdent() + } +} + +lp.parseNew = function() { + let node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart + let meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + return this.finishNode(node, "MetaProperty") + } + let start = this.storeCurrentPos() + node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line) + if (this.tok.type == tt.parenL) { + node.arguments = this.parseExprList(tt.parenR) + } else { + node.arguments = [] + } + return this.finishNode(node, "NewExpression") +} + +lp.parseTemplateElement = function() { + let elem = this.startNode() + elem.value = { + raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, '\n'), + cooked: this.tok.value + } + this.next() + elem.tail = this.tok.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +lp.parseTemplate = function() { + let node = this.startNode() + this.next() + node.expressions = [] + let curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this.next() + node.expressions.push(this.parseExpression()) + if (this.expect(tt.braceR)) { + curElt = this.parseTemplateElement() + } else { + curElt = this.startNode() + curElt.value = {cooked: '', raw: ''} + curElt.tail = true + this.finishNode(curElt, "TemplateElement") + } + node.quasis.push(curElt) + } + this.expect(tt.backQuote) + return this.finishNode(node, "TemplateLiteral") +} + +lp.parseObj = function() { + let node = this.startNode() + node.properties = [] + this.pushCx() + let indent = this.curIndent + 1, line = this.curLineStart + this.eat(tt.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(tt.braceR, indent, line)) { + let prop = this.startNode(), isGenerator, isAsync, start + if (this.options.ecmaVersion >= 6) { + start = this.storeCurrentPos() + prop.method = false + prop.shorthand = false + isGenerator = this.eat(tt.star) + } + this.parsePropertyName(prop) + if (!prop.computed && + prop.key.type === "Identifier" && prop.key.name === "async" && this.tok.type !== tt.parenL && + this.tok.type !== tt.colon && !this.canInsertSemicolon()) { + this.parsePropertyName(prop) + isAsync = true + } else { + isAsync = false + } + if (isDummy(prop.key)) { if (isDummy(this.parseMaybeAssign())) this.next(); this.eat(tt.comma); continue } + if (this.eat(tt.colon)) { + prop.kind = "init" + prop.value = this.parseMaybeAssign() + } else if (this.options.ecmaVersion >= 6 && (this.tok.type === tt.parenL || this.tok.type === tt.braceL)) { + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator, isAsync) + } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && + !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && + (this.tok.type != tt.comma && this.tok.type != tt.braceR)) { + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + } else { + prop.kind = "init" + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.eq)) { + let assign = this.startNodeAt(start) + assign.operator = "=" + assign.left = prop.key + assign.right = this.parseMaybeAssign() + prop.value = this.finishNode(assign, "AssignmentExpression") + } else { + prop.value = prop.key + } + } else { + prop.value = this.dummyIdent() + } + prop.shorthand = true + } + node.properties.push(this.finishNode(prop, "Property")) + this.eat(tt.comma) + } + this.popCx() + if (!this.eat(tt.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return this.finishNode(node, "ObjectExpression") +} + +lp.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseExpression() + this.expect(tt.bracketR) + return + } else { + prop.computed = false + } + } + let key = (this.tok.type === tt.num || this.tok.type === tt.string) ? this.parseExprAtom() : this.parseIdent() + prop.key = key || this.dummyIdent() +} + +lp.parsePropertyAccessor = function() { + if (this.tok.type === tt.name || this.tok.type.keyword) return this.parseIdent() +} + +lp.parseIdent = function() { + let name = this.tok.type === tt.name ? this.tok.value : this.tok.type.keyword + if (!name) return this.dummyIdent() + let node = this.startNode() + this.next() + node.name = name + return this.finishNode(node, "Identifier") +} + +lp.initFunction = function(node) { + node.id = null + node.params = [] + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } + if (this.options.ecmaVersion >= 8) + node.async = false +} + +// Convert existing expression atom to assignable pattern +// if possible. + +lp.toAssignable = function(node, binding) { + if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) { + // Okay + } else if (node.type == "ParenthesizedExpression") { + node.expression = this.toAssignable(node.expression, binding) + } else if (this.options.ecmaVersion < 6) { + return this.dummyIdent() + } else if (node.type == "ObjectExpression") { + node.type = "ObjectPattern" + let props = node.properties + for (let i = 0; i < props.length; i++) + props[i].value = this.toAssignable(props[i].value, binding) + } else if (node.type == "ArrayExpression") { + node.type = "ArrayPattern" + this.toAssignableList(node.elements, binding) + } else if (node.type == "SpreadElement") { + node.type = "RestElement" + node.argument = this.toAssignable(node.argument, binding) + } else if (node.type == "AssignmentExpression") { + node.type = "AssignmentPattern" + delete node.operator + } else { + return this.dummyIdent() + } + return node +} + +lp.toAssignableList = function(exprList, binding) { + for (let i = 0; i < exprList.length; i++) + exprList[i] = this.toAssignable(exprList[i], binding) + return exprList +} + +lp.parseFunctionParams = function(params) { + params = this.parseExprList(tt.parenR) + return this.toAssignableList(params, true) +} + +lp.parseMethod = function(isGenerator, isAsync) { + let node = this.startNode(), oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = !!isGenerator + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tt.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "FunctionExpression") +} + +lp.parseArrowExpression = function(node, params, isAsync) { + let oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + this.inAsync = node.async + node.params = this.toAssignableList(params, true) + node.expression = this.tok.type !== tt.braceL + node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, "ArrowFunctionExpression") +} + +lp.parseExprList = function(close, allowEmpty) { + this.pushCx() + let indent = this.curIndent, line = this.curLineStart, elts = [] + this.next() // Opening bracket + while (!this.closes(close, indent + 1, line)) { + if (this.eat(tt.comma)) { + elts.push(allowEmpty ? null : this.dummyIdent()) + continue + } + let elt = this.parseMaybeAssign() + if (isDummy(elt)) { + if (this.closes(close, indent, line)) break + this.next() + } else { + elts.push(elt) + } + this.eat(tt.comma) + } + this.popCx() + if (!this.eat(close)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + return elts +} + +lp.parseAwait = function() { + let node = this.startNode() + this.next() + node.argument = this.parseMaybeUnary() + return this.finishNode(node, "AwaitExpression") +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/index.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/index.js new file mode 100644 index 000000000..98bbf4b3b --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/index.js @@ -0,0 +1,48 @@ +// Acorn: Loose parser +// +// This module provides an alternative parser (`parse_dammit`) that +// exposes that same interface as `parse`, but will try to parse +// anything as JavaScript, repairing syntax error the best it can. +// There are circumstances in which it will raise an error and give +// up, but they are very rare. The resulting AST will be a mostly +// valid JavaScript AST (as per the [Mozilla parser API][api], except +// that: +// +// - Return outside functions is allowed +// +// - Label consistency (no conflicts, break only to existing labels) +// is not enforced. +// +// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever +// the parser got too confused to return anything meaningful. +// +// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API +// +// The expected use for this is to *first* try `acorn.parse`, and only +// if that fails switch to `parse_dammit`. The loose parser might +// parse badly indented code incorrectly, so **don't** use it as +// your default parser. +// +// Quite a lot of acorn.js is duplicated here. The alternative was to +// add a *lot* of extra cruft to that file, making it less readable +// and slower. Copying and editing the code allowed me to make +// invasive changes and simplifications without creating a complicated +// tangle. + +import {addLooseExports, defaultOptions} from "../index" +import {LooseParser, pluginsLoose} from "./state" +import "./tokenize" +import "./statement" +import "./expression" + +export {LooseParser, pluginsLoose} from "./state" + +defaultOptions.tabSize = 4 + +export function parse_dammit(input, options) { + let p = new LooseParser(input, options) + p.next() + return p.parseTopLevel() +} + +addLooseExports(parse_dammit, LooseParser, pluginsLoose) diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/parseutil.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/parseutil.js new file mode 100644 index 000000000..c5ee096a1 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/parseutil.js @@ -0,0 +1 @@ +export function isDummy(node) { return node.name == "✖" }
\ No newline at end of file diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/state.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/state.js new file mode 100644 index 000000000..18987aa22 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/state.js @@ -0,0 +1,161 @@ +import {tokenizer, SourceLocation, tokTypes as tt, Node, lineBreak, isNewLine} from "../index" + +// Registered plugins +export const pluginsLoose = {} + +export class LooseParser { + constructor(input, options = {}) { + this.toks = tokenizer(input, options) + this.options = this.toks.options + this.input = this.toks.input + this.tok = this.last = {type: tt.eof, start: 0, end: 0} + if (this.options.locations) { + let here = this.toks.curPosition() + this.tok.loc = new SourceLocation(this.toks, here, here) + } + this.ahead = [] // Tokens ahead + this.context = [] // Indentation contexted + this.curIndent = 0 + this.curLineStart = 0 + this.nextLineStart = this.lineEnd(this.curLineStart) + 1 + this.inAsync = false + // Load plugins + this.options.pluginsLoose = options.pluginsLoose || {} + this.loadPlugins(this.options.pluginsLoose) + } + + startNode() { + return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null) + } + + storeCurrentPos() { + return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start + } + + startNodeAt(pos) { + if (this.options.locations) { + return new Node(this.toks, pos[0], pos[1]) + } else { + return new Node(this.toks, pos) + } + } + + finishNode(node, type) { + node.type = type + node.end = this.last.end + if (this.options.locations) + node.loc.end = this.last.loc.end + if (this.options.ranges) + node.range[1] = this.last.end + return node + } + + dummyNode(type) { + let dummy = this.startNode() + dummy.type = type + dummy.end = dummy.start + if (this.options.locations) + dummy.loc.end = dummy.loc.start + if (this.options.ranges) + dummy.range[1] = dummy.start + this.last = {type: tt.name, start: dummy.start, end: dummy.start, loc: dummy.loc} + return dummy + } + + dummyIdent() { + let dummy = this.dummyNode("Identifier") + dummy.name = "✖" + return dummy + } + + dummyString() { + let dummy = this.dummyNode("Literal") + dummy.value = dummy.raw = "✖" + return dummy + } + + eat(type) { + if (this.tok.type === type) { + this.next() + return true + } else { + return false + } + } + + isContextual(name) { + return this.tok.type === tt.name && this.tok.value === name + } + + eatContextual(name) { + return this.tok.value === name && this.eat(tt.name) + } + + canInsertSemicolon() { + return this.tok.type === tt.eof || this.tok.type === tt.braceR || + lineBreak.test(this.input.slice(this.last.end, this.tok.start)) + } + + semicolon() { + return this.eat(tt.semi) + } + + expect(type) { + if (this.eat(type)) return true + for (let i = 1; i <= 2; i++) { + if (this.lookAhead(i).type == type) { + for (let j = 0; j < i; j++) this.next() + return true + } + } + } + + pushCx() { + this.context.push(this.curIndent) + } + + popCx() { + this.curIndent = this.context.pop() + } + + lineEnd(pos) { + while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos + return pos + } + + indentationAfter(pos) { + for (let count = 0;; ++pos) { + let ch = this.input.charCodeAt(pos) + if (ch === 32) ++count + else if (ch === 9) count += this.options.tabSize + else return count + } + } + + closes(closeTok, indent, line, blockHeuristic) { + if (this.tok.type === closeTok || this.tok.type === tt.eof) return true + return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && + (!blockHeuristic || this.nextLineStart >= this.input.length || + this.indentationAfter(this.nextLineStart) < indent) + } + + tokenStartsLine() { + for (let p = this.tok.start - 1; p >= this.curLineStart; --p) { + let ch = this.input.charCodeAt(p) + if (ch !== 9 && ch !== 32) return false + } + return true + } + + extend(name, f) { + this[name] = f(this[name]) + } + + loadPlugins(pluginConfigs) { + for (let name in pluginConfigs) { + let plugin = pluginsLoose[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this, pluginConfigs[name]) + } + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/statement.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/statement.js new file mode 100644 index 000000000..f4a3b1f65 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/statement.js @@ -0,0 +1,450 @@ +import {LooseParser} from "./state" +import {isDummy} from "./parseutil" +import {getLineInfo, tokTypes as tt} from "../index" + +const lp = LooseParser.prototype + +lp.parseTopLevel = function() { + let node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0) + node.body = [] + while (this.tok.type !== tt.eof) node.body.push(this.parseStatement()) + this.last = this.tok + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +lp.parseStatement = function() { + let starttype = this.tok.type, node = this.startNode(), kind + + if (this.toks.isLet()) { + starttype = tt._var + kind = "let" + } + + switch (starttype) { + case tt._break: case tt._continue: + this.next() + let isBreak = starttype === tt._break + if (this.semicolon() || this.canInsertSemicolon()) { + node.label = null + } else { + node.label = this.tok.type === tt.name ? this.parseIdent() : null + this.semicolon() + } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + + case tt._debugger: + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") + + case tt._do: + this.next() + node.body = this.parseStatement() + node.test = this.eat(tt._while) ? this.parseParenExpression() : this.dummyIdent() + this.semicolon() + return this.finishNode(node, "DoWhileStatement") + + case tt._for: + this.next() + this.pushCx() + this.expect(tt.parenL) + if (this.tok.type === tt.semi) return this.parseFor(node, null) + let isLet = this.toks.isLet() + if (isLet || this.tok.type === tt._var || this.tok.type === tt._const) { + let init = this.parseVar(true, isLet ? "let" : this.tok.value) + if (init.declarations.length === 1 && (this.tok.type === tt._in || this.isContextual("of"))) { + return this.parseForIn(node, init) + } + return this.parseFor(node, init) + } + let init = this.parseExpression(true) + if (this.tok.type === tt._in || this.isContextual("of")) + return this.parseForIn(node, this.toAssignable(init)) + return this.parseFor(node, init) + + case tt._function: + this.next() + return this.parseFunction(node, true) + + case tt._if: + this.next() + node.test = this.parseParenExpression() + node.consequent = this.parseStatement() + node.alternate = this.eat(tt._else) ? this.parseStatement() : null + return this.finishNode(node, "IfStatement") + + case tt._return: + this.next() + if (this.eat(tt.semi) || this.canInsertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") + + case tt._switch: + let blockIndent = this.curIndent, line = this.curLineStart + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.pushCx() + this.expect(tt.braceL) + + let cur + while (!this.closes(tt.braceR, blockIndent, line, true)) { + if (this.tok.type === tt._case || this.tok.type === tt._default) { + let isCase = this.tok.type === tt._case + if (cur) this.finishNode(cur, "SwitchCase") + node.cases.push(cur = this.startNode()) + cur.consequent = [] + this.next() + if (isCase) cur.test = this.parseExpression() + else cur.test = null + this.expect(tt.colon) + } else { + if (!cur) { + node.cases.push(cur = this.startNode()) + cur.consequent = [] + cur.test = null + } + cur.consequent.push(this.parseStatement()) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.popCx() + this.eat(tt.braceR) + return this.finishNode(node, "SwitchStatement") + + case tt._throw: + this.next() + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") + + case tt._try: + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.tok.type === tt._catch) { + let clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.toAssignable(this.parseExprAtom(), true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) return node.block + return this.finishNode(node, "TryStatement") + + case tt._var: + case tt._const: + return this.parseVar(false, kind || this.tok.value) + + case tt._while: + this.next() + node.test = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WhileStatement") + + case tt._with: + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement() + return this.finishNode(node, "WithStatement") + + case tt.braceL: + return this.parseBlock() + + case tt.semi: + this.next() + return this.finishNode(node, "EmptyStatement") + + case tt._class: + return this.parseClass(true) + + case tt._import: + return this.parseImport() + + case tt._export: + return this.parseExport() + + default: + if (this.toks.isAsyncFunction()) { + this.next() + this.next() + return this.parseFunction(node, true, true) + } + let expr = this.parseExpression() + if (isDummy(expr)) { + this.next() + if (this.tok.type === tt.eof) return this.finishNode(node, "EmptyStatement") + return this.parseStatement() + } else if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) { + node.body = this.parseStatement() + node.label = expr + return this.finishNode(node, "LabeledStatement") + } else { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") + } + } +} + +lp.parseBlock = function() { + let node = this.startNode() + this.pushCx() + this.expect(tt.braceL) + let blockIndent = this.curIndent, line = this.curLineStart + node.body = [] + while (!this.closes(tt.braceR, blockIndent, line, true)) + node.body.push(this.parseStatement()) + this.popCx() + this.eat(tt.braceR) + return this.finishNode(node, "BlockStatement") +} + +lp.parseFor = function(node, init) { + node.init = init + node.test = node.update = null + if (this.eat(tt.semi) && this.tok.type !== tt.semi) node.test = this.parseExpression() + if (this.eat(tt.semi) && this.tok.type !== tt.parenR) node.update = this.parseExpression() + this.popCx() + this.expect(tt.parenR) + node.body = this.parseStatement() + return this.finishNode(node, "ForStatement") +} + +lp.parseForIn = function(node, init) { + let type = this.tok.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.popCx() + this.expect(tt.parenR) + node.body = this.parseStatement() + return this.finishNode(node, type) +} + +lp.parseVar = function(noIn, kind) { + let node = this.startNode() + node.kind = kind + this.next() + node.declarations = [] + do { + let decl = this.startNode() + decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent() + decl.init = this.eat(tt.eq) ? this.parseMaybeAssign(noIn) : null + node.declarations.push(this.finishNode(decl, "VariableDeclarator")) + } while (this.eat(tt.comma)) + if (!node.declarations.length) { + let decl = this.startNode() + decl.id = this.dummyIdent() + node.declarations.push(this.finishNode(decl, "VariableDeclarator")) + } + if (!noIn) this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +lp.parseClass = function(isStatement) { + let node = this.startNode() + this.next() + if (isStatement == null) isStatement = this.tok.type === tt.name + if (this.tok.type === tt.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + else node.id = null + node.superClass = this.eat(tt._extends) ? this.parseExpression() : null + node.body = this.startNode() + node.body.body = [] + this.pushCx() + let indent = this.curIndent + 1, line = this.curLineStart + this.eat(tt.braceL) + if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart } + while (!this.closes(tt.braceR, indent, line)) { + if (this.semicolon()) continue + let method = this.startNode(), isGenerator, isAsync + if (this.options.ecmaVersion >= 6) { + method.static = false + isGenerator = this.eat(tt.star) + } + this.parsePropertyName(method) + if (isDummy(method.key)) { if (isDummy(this.parseMaybeAssign())) this.next(); this.eat(tt.comma); continue } + if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" && + (this.tok.type != tt.parenL && this.tok.type != tt.braceL)) { + method.static = true + isGenerator = this.eat(tt.star) + this.parsePropertyName(method) + } else { + method.static = false + } + if (!method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this.tok.type !== tt.parenL && + !this.canInsertSemicolon()) { + this.parsePropertyName(method) + isAsync = true + } else { + isAsync = false + } + if (this.options.ecmaVersion >= 5 && method.key.type === "Identifier" && + !method.computed && (method.key.name === "get" || method.key.name === "set") && + this.tok.type !== tt.parenL && this.tok.type !== tt.braceL) { + method.kind = method.key.name + this.parsePropertyName(method) + method.value = this.parseMethod(false) + } else { + if (!method.computed && !method.static && !isGenerator && !isAsync && ( + method.key.type === "Identifier" && method.key.name === "constructor" || + method.key.type === "Literal" && method.key.value === "constructor")) { + method.kind = "constructor" + } else { + method.kind = "method" + } + method.value = this.parseMethod(isGenerator, isAsync) + } + node.body.body.push(this.finishNode(method, "MethodDefinition")) + } + this.popCx() + if (!this.eat(tt.braceR)) { + // If there is no closing brace, make the node span to the start + // of the next token (this is useful for Tern) + this.last.end = this.tok.start + if (this.options.locations) this.last.loc.end = this.tok.loc.start + } + this.semicolon() + this.finishNode(node.body, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +lp.parseFunction = function(node, isStatement, isAsync) { + let oldInAsync = this.inAsync + this.initFunction(node) + if (this.options.ecmaVersion >= 6) { + node.generator = this.eat(tt.star) + } + if (this.options.ecmaVersion >= 8) { + node.async = !!isAsync + } + if (isStatement == null) isStatement = this.tok.type === tt.name + if (this.tok.type === tt.name) node.id = this.parseIdent() + else if (isStatement) node.id = this.dummyIdent() + this.inAsync = node.async + node.params = this.parseFunctionParams() + node.body = this.parseBlock() + this.inAsync = oldInAsync + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +lp.parseExport = function() { + let node = this.startNode() + this.next() + if (this.eat(tt.star)) { + node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { + // export default (function foo() {}) // This is FunctionExpression. + let isAsync + if (this.tok.type === tt._function || (isAsync = this.toks.isAsyncFunction())) { + let fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, isAsync) + } else if (this.tok.type === tt._class) { + node.declaration = this.parseClass(null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) { + node.declaration = this.parseStatement() + node.specifiers = [] + node.source = null + } else { + node.declaration = null + node.specifiers = this.parseExportSpecifierList() + node.source = this.eatContextual("from") ? this.parseExprAtom() : null + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +lp.parseImport = function() { + let node = this.startNode() + this.next() + if (this.tok.type === tt.string) { + node.specifiers = [] + node.source = this.parseExprAtom() + node.kind = '' + } else { + let elt + if (this.tok.type === tt.name && this.tok.value !== "from") { + elt = this.startNode() + elt.local = this.parseIdent() + this.finishNode(elt, "ImportDefaultSpecifier") + this.eat(tt.comma) + } + node.specifiers = this.parseImportSpecifierList() + node.source = this.eatContextual("from") && this.tok.type == tt.string ? this.parseExprAtom() : this.dummyString() + if (elt) node.specifiers.unshift(elt) + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +lp.parseImportSpecifierList = function() { + let elts = [] + if (this.tok.type === tt.star) { + let elt = this.startNode() + this.next() + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent() + elts.push(this.finishNode(elt, "ImportNamespaceSpecifier")) + } else { + let indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(tt.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + let elt = this.startNode() + if (this.eat(tt.star)) { + elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent() + this.finishNode(elt, "ImportNamespaceSpecifier") + } else { + if (this.isContextual("from")) break + elt.imported = this.parseIdent() + if (isDummy(elt.imported)) break + elt.local = this.eatContextual("as") ? this.parseIdent() : elt.imported + this.finishNode(elt, "ImportSpecifier") + } + elts.push(elt) + this.eat(tt.comma) + } + this.eat(tt.braceR) + this.popCx() + } + return elts +} + +lp.parseExportSpecifierList = function() { + let elts = [] + let indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart + this.pushCx() + this.eat(tt.braceL) + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart + while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this.isContextual("from")) break + let elt = this.startNode() + elt.local = this.parseIdent() + if (isDummy(elt.local)) break + elt.exported = this.eatContextual("as") ? this.parseIdent() : elt.local + this.finishNode(elt, "ExportSpecifier") + elts.push(elt) + this.eat(tt.comma) + } + this.eat(tt.braceR) + this.popCx() + return elts +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/tokenize.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/tokenize.js new file mode 100644 index 000000000..c08be9778 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/tokenize.js @@ -0,0 +1,108 @@ +import {tokTypes as tt, Token, isNewLine, SourceLocation, getLineInfo, lineBreakG} from "../index" +import {LooseParser} from "./state" + +const lp = LooseParser.prototype + +function isSpace(ch) { + return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch) +} + +lp.next = function() { + this.last = this.tok + if (this.ahead.length) + this.tok = this.ahead.shift() + else + this.tok = this.readToken() + + if (this.tok.start >= this.nextLineStart) { + while (this.tok.start >= this.nextLineStart) { + this.curLineStart = this.nextLineStart + this.nextLineStart = this.lineEnd(this.curLineStart) + 1 + } + this.curIndent = this.indentationAfter(this.curLineStart) + } +} + +lp.readToken = function() { + for (;;) { + try { + this.toks.next() + if (this.toks.type === tt.dot && + this.input.substr(this.toks.end, 1) === "." && + this.options.ecmaVersion >= 6) { + this.toks.end++ + this.toks.type = tt.ellipsis + } + return new Token(this.toks) + } catch(e) { + if (!(e instanceof SyntaxError)) throw e + + // Try to skip some text, based on the error message, and then continue + let msg = e.message, pos = e.raisedAt, replace = true + if (/unterminated/i.test(msg)) { + pos = this.lineEnd(e.pos + 1) + if (/string/.test(msg)) { + replace = {start: e.pos, end: pos, type: tt.string, value: this.input.slice(e.pos + 1, pos)} + } else if (/regular expr/i.test(msg)) { + let re = this.input.slice(e.pos, pos) + try { re = new RegExp(re) } catch(e) {} + replace = {start: e.pos, end: pos, type: tt.regexp, value: re} + } else if (/template/.test(msg)) { + replace = {start: e.pos, end: pos, + type: tt.template, + value: this.input.slice(e.pos, pos)} + } else { + replace = false + } + } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) { + while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos + } else if (/character escape|expected hexadecimal/i.test(msg)) { + while (pos < this.input.length) { + let ch = this.input.charCodeAt(pos++) + if (ch === 34 || ch === 39 || isNewLine(ch)) break + } + } else if (/unexpected character/i.test(msg)) { + pos++ + replace = false + } else if (/regular expression/i.test(msg)) { + replace = true + } else { + throw e + } + this.resetTo(pos) + if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"} + if (replace) { + if (this.options.locations) + replace.loc = new SourceLocation( + this.toks, + getLineInfo(this.input, replace.start), + getLineInfo(this.input, replace.end)) + return replace + } + } + } +} + +lp.resetTo = function(pos) { + this.toks.pos = pos + let ch = this.input.charAt(pos - 1) + this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || + /[enwfd]/.test(ch) && + /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos)) + + if (this.options.locations) { + this.toks.curLine = 1 + this.toks.lineStart = lineBreakG.lastIndex = 0 + let match + while ((match = lineBreakG.exec(this.input)) && match.index < pos) { + ++this.toks.curLine + this.toks.lineStart = match.index + match[0].length + } + } +} + +lp.lookAhead = function(n) { + while (n > this.ahead.length) + this.ahead.push(this.readToken()) + return this.ahead[n - 1] +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/lval.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/lval.js new file mode 100644 index 000000000..c88d71938 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/lval.js @@ -0,0 +1,219 @@ +import {types as tt} from "./tokentype" +import {Parser} from "./state" +import {has} from "./util" + +const pp = Parser.prototype + +// Convert existing expression atom to assignable pattern +// if possible. + +pp.toAssignable = function(node, isBinding) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + this.raise(node.start, "Can not use 'await' as identifier inside an async function") + break + + case "ObjectPattern": + case "ArrayPattern": + break + + case "ObjectExpression": + node.type = "ObjectPattern" + for (let i = 0; i < node.properties.length; i++) { + let prop = node.properties[i] + if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter") + this.toAssignable(prop.value, isBinding) + } + break + + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + this.toAssignable(node.left, isBinding) + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break + + case "MemberExpression": + if (!isBinding) break + + default: + this.raise(node.start, "Assigning to rvalue") + } + } + return node +} + +// Convert list of expression atoms to binding list. + +pp.toAssignableList = function(exprList, isBinding) { + let end = exprList.length + if (end) { + let last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + let arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (let i = 0; i < end; i++) { + let elt = exprList[i] + if (elt) this.toAssignable(elt, isBinding) + } + return exprList +} + +// Parses spread element. + +pp.parseSpread = function(refDestructuringErrors) { + let node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} + +pp.parseRest = function(allowNonIdent) { + let node = this.startNode() + this.next() + + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() + + return this.finishNode(node, "RestElement") +} + +// Parses lvalue (assignable) atom. + +pp.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() + + case tt.bracketL: + let node = this.startNode() + this.next() + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") + + case tt.braceL: + return this.parseObj(true) + + default: + this.unexpected() + } +} + +pp.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + let elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this.expect(tt.comma) + if (allowEmpty && this.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === tt.ellipsis) { + let rest = this.parseRest(allowNonIdent) + this.parseBindingListItem(rest) + elts.push(rest) + if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element") + this.expect(close) + break + } else { + let elem = this.parseMaybeDefault(this.start, this.startLoc) + this.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + let node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp.checkLVal = function(expr, isBinding, checkClashes) { + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (let i = 0; i < expr.properties.length; i++) + this.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (let i = 0; i < expr.elements.length; i++) { + let elem = expr.elements[i] + if (elem) this.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/node.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/node.js new file mode 100644 index 000000000..76b5b0982 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/node.js @@ -0,0 +1,50 @@ +import {Parser} from "./state" +import {SourceLocation} from "./locutil" + +export class Node { + constructor(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] + } +} + +// Start an AST node, attaching a start offset. + +const pp = Parser.prototype + +pp.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/options.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/options.js new file mode 100644 index 000000000..e7b217e8d --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/options.js @@ -0,0 +1,128 @@ +import {has, isArray} from "./util" +import {SourceLocation} from "./locutil" + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +export const defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. The default is 7. + ecmaVersion: 7, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +export function getOptions(opts) { + let options = {} + + for (let opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + + if (options.ecmaVersion >= 2015) + options.ecmaVersion -= 2009 + + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + let tokens = options.onToken + options.onToken = (token) => tokens.push(token) + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + let comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/parseutil.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/parseutil.js new file mode 100644 index 000000000..46e4521c6 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/parseutil.js @@ -0,0 +1,128 @@ +import {types as tt} from "./tokentype" +import {Parser} from "./state" +import {lineBreak, skipWhiteSpace} from "./whitespace" + +const pp = Parser.prototype + +// ## Parser utilities + +const literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/ +pp.strictDirective = function(start) { + for (;;) { + skipWhiteSpace.lastIndex = start + start += skipWhiteSpace.exec(this.input)[0].length + let match = literal.exec(this.input.slice(start)) + if (!match) return false + if ((match[1] || match[2]) == "use strict") return true + start += match[0].length + } +} + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false + } +} + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true + } +} + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} + +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + if (!notNext) + this.next() + return true + } +} + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} + +export class DestructuringErrors { + constructor() { + this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1 + } +} + +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) return + if (refDestructuringErrors.trailingComma > -1) + this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element") + let parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind + if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern") +} + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + let pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1 + if (!andThrow) return pos >= 0 + if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} + +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + this.raise(this.yieldPos, "Yield expression cannot be a default value") + if (this.awaitPos) + this.raise(this.awaitPos, "Await expression cannot be a default value") +} + +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + return this.isSimpleAssignTarget(expr.expression) + return expr.type === "Identifier" || expr.type === "MemberExpression" +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/state.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/state.js new file mode 100644 index 000000000..4c244e4d6 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/state.js @@ -0,0 +1,111 @@ +import {reservedWords, keywords} from "./identifier" +import {types as tt} from "./tokentype" +import {lineBreak} from "./whitespace" +import {getOptions} from "./options" + +// Registered plugins +export const plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +export class Parser { + constructor(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + let reserved = "" + if (!options.allowReserved) { + for (let v = options.ecmaVersion;; v--) + if (reserved = reservedWords[v]) break + if (options.sourceType == "module") reserved += " await" + } + this.reservedWords = keywordRegexp(reserved) + let reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1 + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module" + this.strict = this.inModule || this.strictDirective(this.pos) + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator, an async function. + this.inFunction = this.inGenerator = this.inAsync = false + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = 0 + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) + } + + // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them + isKeyword(word) { return this.keywords.test(word) } + isReservedWord(word) { return this.reservedWords.test(word) } + + extend(name, f) { + this[name] = f(this[name]) + } + + loadPlugins(pluginConfigs) { + for (let name in pluginConfigs) { + let plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this, pluginConfigs[name]) + } + } + + parse() { + let node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) + } +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/statement.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/statement.js new file mode 100644 index 000000000..ee096132f --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/statement.js @@ -0,0 +1,744 @@ +import {types as tt} from "./tokentype" +import {Parser} from "./state" +import {lineBreak, skipWhiteSpace} from "./whitespace" +import {isIdentifierStart, isIdentifierChar} from "./identifier" +import {DestructuringErrors} from "./parseutil" + +const pp = Parser.prototype + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp.parseTopLevel = function(node) { + let exports = {} + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + let stmt = this.parseStatement(true, true, exports) + node.body.push(stmt) + } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"} + +pp.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + let skip = skipWhiteSpace.exec(this.input) + let next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + let ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp.isAsyncFunction = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 8 || this.value != "async") + return false + + skipWhiteSpace.lastIndex = this.pos + let skip = skipWhiteSpace.exec(this.input) + let next = this.pos + skip[0].length + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 == this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp.parseStatement = function(declaration, topLevel, exports) { + let starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node, false) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction() && declaration) { + this.next() + return this.parseFunctionStatement(node, true) + } + + let maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) + } +} + +pp.parseBreakContinueStatement = function(node, keyword) { + let isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() + } + + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + let lab = this.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + let isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + let init = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init, true, kind) + this.finishNode(init, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1 && + !(kind !== "var" && init.declarations[0].init)) + return this.parseForIn(node, init) + return this.parseFor(node, init) + } + let refDestructuringErrors = new DestructuringErrors + let init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.toAssignable(init) + this.checkLVal(init) + this.checkPatternErrors(refDestructuringErrors, true) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp.parseFunctionStatement = function(node, isAsync) { + this.next() + return this.parseFunction(node, true, false, isAsync) +} + +pp.isFunction = function() { + return this.type === tt._function || this.isAsyncFunction() +} + +pp.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement(!this.strict && this.isFunction()) + node.alternate = this.eat(tt._else) ? this.parseStatement(!this.strict && this.isFunction()) : null + return this.finishNode(node, "IfStatement") +} + +pp.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp.parseSwitchStatement = function(node) { + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this.type === tt._case || this.type === tt._default) { + let isCase = this.type === tt._case + if (cur) this.finishNode(cur, "SwitchCase") + node.cases.push(cur = this.startNode()) + cur.consequent = [] + this.next() + if (isCase) { + cur.test = this.parseExpression() + } else { + if (sawDefault) this.raiseRecoverable(this.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this.expect(tt.colon) + } else { + if (!cur) this.unexpected() + cur.consequent.push(this.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +const empty = [] + +pp.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + let clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp.parseLabeledStatement = function(node, maybeName, expr) { + for (let i = 0; i < this.labels.length; ++i) + if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared") + let kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (let i = this.labels.length - 1; i >= 0; i--) { + let label = this.labels[i] + if (label.statementStart == node.start) { + label.statementStart = this.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + if (node.body.type == "ClassDeclaration" || + node.body.type == "VariableDeclaration" && (this.strict || node.body.kind != "var") || + node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) + this.raiseRecoverable(node.body.start, "Invalid labeled declaration") + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp.parseBlock = function() { + let node = this.startNode() + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + let stmt = this.parseStatement(true) + node.body.push(stmt) + } + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp.parseForIn = function(node, init) { + let type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp.parseVar = function(node, isFor, kind) { + node.declarations = [] + node.kind = kind + for (;;) { + let decl = this.startNode() + this.parseVarId(decl) + if (this.eat(tt.eq)) { + decl.init = this.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")) + if (!this.eat(tt.comma)) break + } + return node +} + +pp.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6 && !isAsync) + node.generator = this.eat(tt.star) + if (this.options.ecmaVersion >= 8) + node.async = !!isAsync + + if (isStatement == null) + isStatement = this.type == tt.name + if (isStatement) + node.id = this.parseIdent() + + let oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction + this.inGenerator = node.generator + this.inAsync = node.async + this.yieldPos = 0 + this.awaitPos = 0 + this.inFunction = true + + if (!isStatement && this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + + this.inGenerator = oldInGen + this.inAsync = oldInAsync + this.yieldPos = oldYieldPos + this.awaitPos = oldAwaitPos + this.inFunction = oldInFunc + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8, true) + this.checkYieldAwaitInDefaultParams() +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp.parseClass = function(node, isStatement) { + this.next() + if (isStatement == null) isStatement = this.type === tt.name + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + let classBody = this.startNode() + let hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this.eat(tt.semi)) continue + let method = this.startNode() + let isGenerator = this.eat(tt.star) + let isAsync = false + let isMaybeStatic = this.type === tt.name && this.value === "static" + this.parsePropertyName(method) + method.static = isMaybeStatic && this.type !== tt.parenL + if (method.static) { + if (isGenerator) this.unexpected() + isGenerator = this.eat(tt.star) + this.parsePropertyName(method) + } + if (this.options.ecmaVersion >= 8 && !isGenerator && !method.computed && + method.key.type === "Identifier" && method.key.name === "async" && this.type !== tt.parenL && + !this.canInsertSemicolon()) { + isAsync = true + this.parsePropertyName(method) + } + method.kind = "method" + let isGetSet = false + if (!method.computed) { + let {key} = method + if (!isGenerator && !isAsync && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this.raise(key.start, "Constructor can't be a generator") + if (isAsync) this.raise(key.start, "Constructor can't be an async method") + method.kind = "constructor" + hadConstructor = true + } + } + this.parseClassMethod(classBody, method, isGenerator, isAsync) + if (isGetSet) { + let paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + let start = method.value.start + if (method.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } else { + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params") + } + } + } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +pp.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} + +pp.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} + +pp.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} + +// Parses module export declaration. + +pp.parseExport = function(node, exports) { + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart) + let isAsync + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + let fNode = this.startNode() + this.next() + if (isAsync) this.next() + node.declaration = this.parseFunction(fNode, null, false, isAsync) + } else if (this.type === tt._class) { + let cNode = this.startNode() + node.declaration = this.parseClass(cNode, null) + } else { + node.declaration = this.parseMaybeAssign() + this.semicolon() + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + if (node.declaration.type === "VariableDeclaration") + this.checkVariableExport(exports, node.declaration.declarations) + else + this.checkExport(exports, node.declaration.id.name, node.declaration.id.start) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers(exports) + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (let i = 0; i < node.specifiers.length; i++) { + if (this.keywords.test(node.specifiers[i].local.name) || this.reservedWords.test(node.specifiers[i].local.name)) { + this.unexpected(node.specifiers[i].local.start) + } + } + + node.source = null + } + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp.checkExport = function(exports, name, pos) { + if (!exports) return + if (Object.prototype.hasOwnProperty.call(exports, name)) + this.raiseRecoverable(pos, "Duplicate export '" + name + "'") + exports[name] = true +} + +pp.checkPatternExport = function(exports, pat) { + let type = pat.type + if (type == "Identifier") + this.checkExport(exports, pat.name, pat.start) + else if (type == "ObjectPattern") + for (let i = 0; i < pat.properties.length; ++i) + this.checkPatternExport(exports, pat.properties[i].value) + else if (type == "ArrayPattern") + for (let i = 0; i < pat.elements.length; ++i) { + let elt = pat.elements[i] + if (elt) this.checkPatternExport(exports, elt) + } + else if (type == "AssignmentPattern") + this.checkPatternExport(exports, pat.left) + else if (type == "ParenthesizedExpression") + this.checkPatternExport(exports, pat.expression) +} + +pp.checkVariableExport = function(exports, decls) { + if (!exports) return + for (let i = 0; i < decls.length; i++) + this.checkPatternExport(exports, decls[i].id) +} + +pp.shouldParseExportStatement = function() { + return this.type.keyword === "var" + || this.type.keyword === "const" + || this.type.keyword === "class" + || this.type.keyword === "function" + || this.isLet() + || this.isAsyncFunction() +} + +// Parses a comma-separated list of module exports. + +pp.parseExportSpecifiers = function(exports) { + let nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this.expect(tt.comma) + if (this.afterTrailingComma(tt.braceR)) break + } else first = false + + let node = this.startNode() + node.local = this.parseIdent(true) + node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local + this.checkExport(exports, node.exported.name, node.exported.start) + nodes.push(this.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp.parseImportSpecifiers = function() { + let nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + let node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + let node = this.startNode() + this.next() + this.expectContextual("as") + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this.expect(tt.comma) + if (this.afterTrailingComma(tt.braceR)) break + } else first = false + + let node = this.startNode() + node.imported = this.parseIdent(true) + if (this.eatContextual("as")) { + node.local = this.parseIdent() + } else { + node.local = node.imported + if (this.isKeyword(node.local.name)) this.unexpected(node.local.start) + if (this.reservedWordsStrict.test(node.local.name)) this.raiseRecoverable(node.local.start, "The keyword '" + node.local.name + "' is reserved") + } + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportSpecifier")) + } + return nodes +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokencontext.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokencontext.js new file mode 100644 index 000000000..911a51563 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokencontext.js @@ -0,0 +1,110 @@ +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +import {Parser} from "./state" +import {types as tt} from "./tokentype" +import {lineBreak} from "./whitespace" + +export class TokContext { + constructor(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override + } +} + +export const types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, p => p.readTmplToken()), + f_expr: new TokContext("function", true) +} + +const pp = Parser.prototype + +pp.initialContext = function() { + return [types.b_stat] +} + +pp.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + let parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp.updateContext = function(prevType) { + let update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} + +// Token-specific context update code + +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return + } + let out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + let statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokenize.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokenize.js new file mode 100644 index 000000000..9a34ba7ab --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokenize.js @@ -0,0 +1,686 @@ +import {isIdentifierStart, isIdentifierChar} from "./identifier" +import {types as tt, keywords as keywordTypes} from "./tokentype" +import {Parser} from "./state" +import {SourceLocation} from "./locutil" +import {lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace} from "./whitespace" + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +export class Token { + constructor(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] + } +} + +// ## Tokenizer + +const pp = Parser.prototype + +// Are we running under Rhino? +const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp[Symbol.iterator] = function () { + let self = this + return {next: function () { + let token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} + } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp.curContext = function() { + return this.context[this.context.length - 1] +} + +// Read a single token, updating the parser object's token-related +// properties. + +pp.nextToken = function() { + let curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() + + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) + + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} + +pp.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() + + return this.getTokenFromCode(code) +} + +pp.fullCharCodeAtPos = function() { + let code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + let next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} + +pp.skipBlockComment = function() { + let startLoc = this.options.onComment && this.curPosition() + let start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + let match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this.curLine + this.lineStart = match.index + match[0].length + } + } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} + +pp.skipLineComment = function(startSkip) { + let start = this.pos + let startLoc = this.options.onComment && this.curPosition() + let ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this.pos + ch = this.input.charCodeAt(this.pos) + } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp.skipSpace = function() { + loop: while (this.pos < this.input.length) { + let ch = this.input.charCodeAt(this.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this.pos + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos + } + case 10: case 8232: case 8233: + ++this.pos + if (this.options.locations) { + ++this.curLine + this.lineStart = this.pos + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment() + break + case 47: + this.skipLineComment(2) + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos + } else { + break loop + } + } + } +} + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp.finishToken = function(type, val) { + this.end = this.pos + if (this.options.locations) this.endLoc = this.curPosition() + let prevType = this.type + this.type = type + this.value = val + + this.updateContext(prevType) +} + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp.readToken_dot = function() { + let next = this.input.charCodeAt(this.pos + 1) + if (next >= 48 && next <= 57) return this.readNumber(true) + let next2 = this.input.charCodeAt(this.pos + 2) + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3 + return this.finishToken(tt.ellipsis) + } else { + ++this.pos + return this.finishToken(tt.dot) + } +} + +pp.readToken_slash = function() { // '/' + let next = this.input.charCodeAt(this.pos + 1) + if (this.exprAllowed) {++this.pos; return this.readRegexp()} + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.slash, 1) +} + +pp.readToken_mult_modulo_exp = function(code) { // '%*' + let next = this.input.charCodeAt(this.pos + 1) + let size = 1 + let tokentype = code === 42 ? tt.star : tt.modulo + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && next === 42) { + ++size + tokentype = tt.starstar + next = this.input.charCodeAt(this.pos + 2) + } + + if (next === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tokentype, size) +} + +pp.readToken_pipe_amp = function(code) { // '|&' + let next = this.input.charCodeAt(this.pos + 1) + if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) +} + +pp.readToken_caret = function() { // '^' + let next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.bitwiseXOR, 1) +} + +pp.readToken_plus_min = function(code) { // '+-' + let next = this.input.charCodeAt(this.pos + 1) + if (next === code) { + if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && + lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { + // A `-->` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp.readToken_lt_gt = function(code) { // '<>' + let next = this.input.charCodeAt(this.pos + 1) + let size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `<!--`, an XML-style comment that should be interpreted as a line comment + this.skipLineComment(4) + this.skipSpace() + return this.nextToken() + } + if (next === 61) size = 2 + return this.finishOp(tt.relational, size) +} + +pp.readToken_eq_excl = function(code) { // '=!' + let next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) + if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>' + this.pos += 2 + return this.finishToken(tt.arrow) + } + return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1) +} + +pp.getTokenFromCode = function(code) { + switch (code) { + // The interpretation of a dot depends on whether it is followed + // by a digit or another two dots. + case 46: // '.' + return this.readToken_dot() + + // Punctuation tokens. + case 40: ++this.pos; return this.finishToken(tt.parenL) + case 41: ++this.pos; return this.finishToken(tt.parenR) + case 59: ++this.pos; return this.finishToken(tt.semi) + case 44: ++this.pos; return this.finishToken(tt.comma) + case 91: ++this.pos; return this.finishToken(tt.bracketL) + case 93: ++this.pos; return this.finishToken(tt.bracketR) + case 123: ++this.pos; return this.finishToken(tt.braceL) + case 125: ++this.pos; return this.finishToken(tt.braceR) + case 58: ++this.pos; return this.finishToken(tt.colon) + case 63: ++this.pos; return this.finishToken(tt.question) + + case 96: // '`' + if (this.options.ecmaVersion < 6) break + ++this.pos + return this.finishToken(tt.backQuote) + + case 48: // '0' + let next = this.input.charCodeAt(this.pos + 1) + if (next === 120 || next === 88) return this.readRadixNumber(16) // '0x', '0X' - hex number + if (this.options.ecmaVersion >= 6) { + if (next === 111 || next === 79) return this.readRadixNumber(8) // '0o', '0O' - octal number + if (next === 98 || next === 66) return this.readRadixNumber(2) // '0b', '0B' - binary number + } + // Anything else beginning with a digit is an integer, octal + // number, or float. + case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 + return this.readNumber(false) + + // Quotes produce strings. + case 34: case 39: // '"', "'" + return this.readString(code) + + // Operators are parsed inline in tiny state machines. '=' (61) is + // often referred to. `finishOp` simply skips the amount of + // characters it is given as second argument, and returns a token + // of the type given by its first argument. + + case 47: // '/' + return this.readToken_slash() + + case 37: case 42: // '%*' + return this.readToken_mult_modulo_exp(code) + + case 124: case 38: // '|&' + return this.readToken_pipe_amp(code) + + case 94: // '^' + return this.readToken_caret() + + case 43: case 45: // '+-' + return this.readToken_plus_min(code) + + case 60: case 62: // '<>' + return this.readToken_lt_gt(code) + + case 61: case 33: // '=!' + return this.readToken_eq_excl(code) + + case 126: // '~' + return this.finishOp(tt.prefix, 1) + } + + this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'") +} + +pp.finishOp = function(type, size) { + let str = this.input.slice(this.pos, this.pos + size) + this.pos += size + return this.finishToken(type, str) +} + +// Parse a regular expression. Some context-awareness is necessary, +// since a '/' inside a '[]' set does not end the expression. + +function tryCreateRegexp(src, flags, throwErrorAt, parser) { + try { + return new RegExp(src, flags) + } catch (e) { + if (throwErrorAt !== undefined) { + if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message) + throw e + } + } +} + +var regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u") + +pp.readRegexp = function() { + let escaped, inClass, start = this.pos + for (;;) { + if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression") + let ch = this.input.charAt(this.pos) + if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression") + if (!escaped) { + if (ch === "[") inClass = true + else if (ch === "]" && inClass) inClass = false + else if (ch === "/" && !inClass) break + escaped = ch === "\\" + } else escaped = false + ++this.pos + } + let content = this.input.slice(start, this.pos) + ++this.pos + // Need to use `readWord1` because '\uXXXX' sequences are allowed + // here (don't ask). + let mods = this.readWord1() + let tmp = content, tmpFlags = "" + if (mods) { + let validFlags = /^[gim]*$/ + if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/ + if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag") + if (mods.indexOf("u") >= 0) { + if (regexpUnicodeSupport) { + tmpFlags = "u" + } else { + // Replace each astral symbol and every Unicode escape sequence that + // possibly represents an astral symbol or a paired surrogate with a + // single ASCII symbol to avoid throwing on regular expressions that + // are only valid in combination with the `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it would + // be replaced by `[x-b]` which throws an error. + tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, (_match, code, offset) => { + code = Number("0x" + code) + if (code > 0x10FFFF) this.raise(start + offset + 3, "Code point out of bounds") + return "x" + }) + tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x") + tmpFlags = tmpFlags.replace("u", "") + } + } + } + // Detect invalid regular expressions. + let value = null + // Rhino's regular expression parser is flaky and throws uncatchable exceptions, + // so don't do detection if we are running under Rhino + if (!isRhino) { + tryCreateRegexp(tmp, tmpFlags, start, this) + // Get a regular expression object for this pattern-flag pair, or `null` in + // case the current environment doesn't support the flags it uses. + value = tryCreateRegexp(content, mods) + } + return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value}) +} + +// Read an integer in the given radix. Return null if zero digits +// were read, the integer value otherwise. When `len` is given, this +// will return `null` unless the integer has exactly `len` digits. + +pp.readInt = function(radix, len) { + let start = this.pos, total = 0 + for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) { + let code = this.input.charCodeAt(this.pos), val + if (code >= 97) val = code - 97 + 10 // a + else if (code >= 65) val = code - 65 + 10 // A + else if (code >= 48 && code <= 57) val = code - 48 // 0-9 + else val = Infinity + if (val >= radix) break + ++this.pos + total = total * radix + val + } + if (this.pos === start || len != null && this.pos - start !== len) return null + + return total +} + +pp.readRadixNumber = function(radix) { + this.pos += 2 // 0x + let val = this.readInt(radix) + if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix) + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + return this.finishToken(tt.num, val) +} + +// Read an integer, octal integer, or floating-point number. + +pp.readNumber = function(startsWithDot) { + let start = this.pos, isFloat = false, octal = this.input.charCodeAt(this.pos) === 48 + if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number") + if (octal && this.pos == start + 1) octal = false + let next = this.input.charCodeAt(this.pos) + if (next === 46 && !octal) { // '.' + ++this.pos + this.readInt(10) + isFloat = true + next = this.input.charCodeAt(this.pos) + } + if ((next === 69 || next === 101) && !octal) { // 'eE' + next = this.input.charCodeAt(++this.pos) + if (next === 43 || next === 45) ++this.pos // '+-' + if (this.readInt(10) === null) this.raise(start, "Invalid number") + isFloat = true + } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number") + + let str = this.input.slice(start, this.pos), val + if (isFloat) val = parseFloat(str) + else if (!octal || str.length === 1) val = parseInt(str, 10) + else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number") + else val = parseInt(str, 8) + return this.finishToken(tt.num, val) +} + +// Read a string value, interpreting backslash-escapes. + +pp.readCodePoint = function() { + let ch = this.input.charCodeAt(this.pos), code + + if (ch === 123) { + if (this.options.ecmaVersion < 6) this.unexpected() + let codePos = ++this.pos + code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos) + ++this.pos + if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds") + } else { + code = this.readHexChar(4) + } + return code +} + +function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) return String.fromCharCode(code) + code -= 0x10000 + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) +} + +pp.readString = function(quote) { + let out = "", chunkStart = ++this.pos + for (;;) { + if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant") + let ch = this.input.charCodeAt(this.pos) + if (ch === quote) break + if (ch === 92) { // '\' + out += this.input.slice(chunkStart, this.pos) + out += this.readEscapedChar(false) + chunkStart = this.pos + } else { + if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant") + ++this.pos + } + } + out += this.input.slice(chunkStart, this.pos++) + return this.finishToken(tt.string, out) +} + +// Reads template string tokens. + +pp.readTmplToken = function() { + let out = "", chunkStart = this.pos + for (;;) { + if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template") + let ch = this.input.charCodeAt(this.pos) + if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${' + if (this.pos === this.start && this.type === tt.template) { + if (ch === 36) { + this.pos += 2 + return this.finishToken(tt.dollarBraceL) + } else { + ++this.pos + return this.finishToken(tt.backQuote) + } + } + out += this.input.slice(chunkStart, this.pos) + return this.finishToken(tt.template, out) + } + if (ch === 92) { // '\' + out += this.input.slice(chunkStart, this.pos) + out += this.readEscapedChar(true) + chunkStart = this.pos + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos) + ++this.pos + switch (ch) { + case 13: + if (this.input.charCodeAt(this.pos) === 10) ++this.pos + case 10: + out += "\n" + break + default: + out += String.fromCharCode(ch) + break + } + if (this.options.locations) { + ++this.curLine + this.lineStart = this.pos + } + chunkStart = this.pos + } else { + ++this.pos + } + } +} + +// Used to read escaped characters + +pp.readEscapedChar = function(inTemplate) { + let ch = this.input.charCodeAt(++this.pos) + ++this.pos + switch (ch) { + case 110: return "\n" // 'n' -> '\n' + case 114: return "\r" // 'r' -> '\r' + case 120: return String.fromCharCode(this.readHexChar(2)) // 'x' + case 117: return codePointToString(this.readCodePoint()) // 'u' + case 116: return "\t" // 't' -> '\t' + case 98: return "\b" // 'b' -> '\b' + case 118: return "\u000b" // 'v' -> '\u000b' + case 102: return "\f" // 'f' -> '\f' + case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos // '\r\n' + case 10: // ' \n' + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine } + return "" + default: + if (ch >= 48 && ch <= 55) { + let octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0] + let octal = parseInt(octalStr, 8) + if (octal > 255) { + octalStr = octalStr.slice(0, -1) + octal = parseInt(octalStr, 8) + } + if (octalStr !== "0" && (this.strict || inTemplate)) { + this.raise(this.pos - 2, "Octal literal in strict mode") + } + this.pos += octalStr.length - 1 + return String.fromCharCode(octal) + } + return String.fromCharCode(ch) + } +} + +// Used to read character escape sequences ('\x', '\u', '\U'). + +pp.readHexChar = function(len) { + let codePos = this.pos + let n = this.readInt(16, len) + if (n === null) this.raise(codePos, "Bad character escape sequence") + return n +} + +// Read an identifier, and return it as a string. Sets `this.containsEsc` +// to whether the word contained a '\u' escape. +// +// Incrementally adds only escaped chars, adding other chunks as-is +// as a micro-optimization. + +pp.readWord1 = function() { + this.containsEsc = false + let word = "", first = true, chunkStart = this.pos + let astral = this.options.ecmaVersion >= 6 + while (this.pos < this.input.length) { + let ch = this.fullCharCodeAtPos() + if (isIdentifierChar(ch, astral)) { + this.pos += ch <= 0xffff ? 1 : 2 + } else if (ch === 92) { // "\" + this.containsEsc = true + word += this.input.slice(chunkStart, this.pos) + let escStart = this.pos + if (this.input.charCodeAt(++this.pos) != 117) // "u" + this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX") + ++this.pos + let esc = this.readCodePoint() + if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) + this.raise(escStart, "Invalid Unicode escape") + word += codePointToString(esc) + chunkStart = this.pos + } else { + break + } + first = false + } + return word + this.input.slice(chunkStart, this.pos) +} + +// Read an identifier or keyword token. Will check for reserved +// words when necessary. + +pp.readWord = function() { + let word = this.readWord1() + let type = tt.name + if (this.keywords.test(word)) { + if (this.containsEsc) this.raiseRecoverable(this.start, "Escape sequence in keyword " + word) + type = keywordTypes[word] + } + return this.finishToken(type, word) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokentype.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokentype.js new file mode 100644 index 000000000..7c36e2d49 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/tokentype.js @@ -0,0 +1,147 @@ +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +export class TokenType { + constructor(label, conf = {}) { + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null + } +} + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +const beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true} + +// Map keyword names to token types. + +export const keywords = {} + +// Succinct definitions of keyword token types +function kw(name, options = {}) { + options.keyword = name + return keywords[name] = new TokenType(name, options) +} + +export const types = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("</>", 7), + bitShift: binop("<</>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/util.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/util.js new file mode 100644 index 000000000..3517f8d21 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/util.js @@ -0,0 +1,9 @@ +export function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +export function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/walk/index.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/walk/index.js new file mode 100644 index 000000000..0da7e0d86 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/walk/index.js @@ -0,0 +1,342 @@ +// AST walker module for Mozilla Parser API compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All Parser API node types +// can be used to identify node types, as well as Expression, +// Statement, and ScopeBody, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +export function simple(node, visitors, base, state, override) { + if (!base) base = exports.base + ;(function c(node, st, override) { + let type = override || node.type, found = visitors[type] + base[type](node, st, c) + if (found) found(node, st) + })(node, state, override) +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +export function ancestor(node, visitors, base, state) { + if (!base) base = exports.base + let ancestors = [] + ;(function c(node, st, override) { + let type = override || node.type, found = visitors[type] + let isNew = node != ancestors[ancestors.length - 1] + if (isNew) ancestors.push(node) + base[type](node, st, c) + if (found) found(node, st || ancestors, ancestors) + if (isNew) ancestors.pop() + })(node, state) +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +export function recursive(node, state, funcs, base, override) { + let visitor = funcs ? exports.make(funcs, base) : base + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c) + })(node, state, override) +} + +function makeTest(test) { + if (typeof test == "string") + return type => type == test + else if (!test) + return () => true + else + return test +} + +class Found { + constructor(node, state) { this.node = node; this.state = state } +} + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +export function findNodeAt(node, start, end, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + let type = override || node.type + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + base[type](node, st, c) + if ((start == null || node.start == start) && + (end == null || node.end == end) && + test(type, node)) + throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +export function findNodeAround(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + let type = override || node.type + if (node.start > pos || node.end < pos) return + base[type](node, st, c) + if (test(type, node)) throw new Found(node, st) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node after a given position. +export function findNodeAfter(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + try { + ;(function c(node, st, override) { + if (node.end < pos) return + let type = override || node.type + if (node.start >= pos && test(type, node)) throw new Found(node, st) + base[type](node, st, c) + })(node, state) + } catch (e) { + if (e instanceof Found) return e + throw e + } +} + +// Find the outermost matching node before a given position. +export function findNodeBefore(node, pos, test, base, state) { + test = makeTest(test) + if (!base) base = exports.base + let max + ;(function c(node, st, override) { + if (node.start > pos) return + let type = override || node.type + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + max = new Found(node, st) + base[type](node, st, c) + })(node, state) + return max +} + +// Fallback to an Object.create polyfill for older environments. +const create = Object.create || function(proto) { + function Ctor() {} + Ctor.prototype = proto + return new Ctor +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +export function make(funcs, base) { + if (!base) base = exports.base + let visitor = create(base) + for (var type in funcs) visitor[type] = funcs[type] + return visitor +} + +function skipThrough(node, st, c) { c(node, st) } +function ignore(_node, _st, _c) {} + +// Node walkers. + +export const base = {} + +base.Program = base.BlockStatement = (node, st, c) => { + for (let i = 0; i < node.body.length; ++i) + c(node.body[i], st, "Statement") +} +base.Statement = skipThrough +base.EmptyStatement = ignore +base.ExpressionStatement = base.ParenthesizedExpression = + (node, st, c) => c(node.expression, st, "Expression") +base.IfStatement = (node, st, c) => { + c(node.test, st, "Expression") + c(node.consequent, st, "Statement") + if (node.alternate) c(node.alternate, st, "Statement") +} +base.LabeledStatement = (node, st, c) => c(node.body, st, "Statement") +base.BreakStatement = base.ContinueStatement = ignore +base.WithStatement = (node, st, c) => { + c(node.object, st, "Expression") + c(node.body, st, "Statement") +} +base.SwitchStatement = (node, st, c) => { + c(node.discriminant, st, "Expression") + for (let i = 0; i < node.cases.length; ++i) { + let cs = node.cases[i] + if (cs.test) c(cs.test, st, "Expression") + for (let j = 0; j < cs.consequent.length; ++j) + c(cs.consequent[j], st, "Statement") + } +} +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = (node, st, c) => { + if (node.argument) c(node.argument, st, "Expression") +} +base.ThrowStatement = base.SpreadElement = + (node, st, c) => c(node.argument, st, "Expression") +base.TryStatement = (node, st, c) => { + c(node.block, st, "Statement") + if (node.handler) c(node.handler, st) + if (node.finalizer) c(node.finalizer, st, "Statement") +} +base.CatchClause = (node, st, c) => { + c(node.param, st, "Pattern") + c(node.body, st, "ScopeBody") +} +base.WhileStatement = base.DoWhileStatement = (node, st, c) => { + c(node.test, st, "Expression") + c(node.body, st, "Statement") +} +base.ForStatement = (node, st, c) => { + if (node.init) c(node.init, st, "ForInit") + if (node.test) c(node.test, st, "Expression") + if (node.update) c(node.update, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInStatement = base.ForOfStatement = (node, st, c) => { + c(node.left, st, "ForInit") + c(node.right, st, "Expression") + c(node.body, st, "Statement") +} +base.ForInit = (node, st, c) => { + if (node.type == "VariableDeclaration") c(node, st) + else c(node, st, "Expression") +} +base.DebuggerStatement = ignore + +base.FunctionDeclaration = (node, st, c) => c(node, st, "Function") +base.VariableDeclaration = (node, st, c) => { + for (let i = 0; i < node.declarations.length; ++i) + c(node.declarations[i], st) +} +base.VariableDeclarator = (node, st, c) => { + c(node.id, st, "Pattern") + if (node.init) c(node.init, st, "Expression") +} + +base.Function = (node, st, c) => { + if (node.id) c(node.id, st, "Pattern") + for (let i = 0; i < node.params.length; i++) + c(node.params[i], st, "Pattern") + c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody") +} +// FIXME drop these node types in next major version +// (They are awkward, and in ES6 every block can be a scope.) +base.ScopeBody = (node, st, c) => c(node, st, "Statement") +base.ScopeExpression = (node, st, c) => c(node, st, "Expression") + +base.Pattern = (node, st, c) => { + if (node.type == "Identifier") + c(node, st, "VariablePattern") + else if (node.type == "MemberExpression") + c(node, st, "MemberPattern") + else + c(node, st) +} +base.VariablePattern = ignore +base.MemberPattern = skipThrough +base.RestElement = (node, st, c) => c(node.argument, st, "Pattern") +base.ArrayPattern = (node, st, c) => { + for (let i = 0; i < node.elements.length; ++i) { + let elt = node.elements[i] + if (elt) c(elt, st, "Pattern") + } +} +base.ObjectPattern = (node, st, c) => { + for (let i = 0; i < node.properties.length; ++i) + c(node.properties[i].value, st, "Pattern") +} + +base.Expression = skipThrough +base.ThisExpression = base.Super = base.MetaProperty = ignore +base.ArrayExpression = (node, st, c) => { + for (let i = 0; i < node.elements.length; ++i) { + let elt = node.elements[i] + if (elt) c(elt, st, "Expression") + } +} +base.ObjectExpression = (node, st, c) => { + for (let i = 0; i < node.properties.length; ++i) + c(node.properties[i], st) +} +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration +base.SequenceExpression = base.TemplateLiteral = (node, st, c) => { + for (let i = 0; i < node.expressions.length; ++i) + c(node.expressions[i], st, "Expression") +} +base.UnaryExpression = base.UpdateExpression = (node, st, c) => { + c(node.argument, st, "Expression") +} +base.BinaryExpression = base.LogicalExpression = (node, st, c) => { + c(node.left, st, "Expression") + c(node.right, st, "Expression") +} +base.AssignmentExpression = base.AssignmentPattern = (node, st, c) => { + c(node.left, st, "Pattern") + c(node.right, st, "Expression") +} +base.ConditionalExpression = (node, st, c) => { + c(node.test, st, "Expression") + c(node.consequent, st, "Expression") + c(node.alternate, st, "Expression") +} +base.NewExpression = base.CallExpression = (node, st, c) => { + c(node.callee, st, "Expression") + if (node.arguments) for (let i = 0; i < node.arguments.length; ++i) + c(node.arguments[i], st, "Expression") +} +base.MemberExpression = (node, st, c) => { + c(node.object, st, "Expression") + if (node.computed) c(node.property, st, "Expression") +} +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = (node, st, c) => { + if (node.declaration) + c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression") + if (node.source) c(node.source, st, "Expression") +} +base.ExportAllDeclaration = (node, st, c) => { + c(node.source, st, "Expression") +} +base.ImportDeclaration = (node, st, c) => { + for (let i = 0; i < node.specifiers.length; i++) + c(node.specifiers[i], st) + c(node.source, st, "Expression") +} +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore + +base.TaggedTemplateExpression = (node, st, c) => { + c(node.tag, st, "Expression") + c(node.quasi, st) +} +base.ClassDeclaration = base.ClassExpression = (node, st, c) => c(node, st, "Class") +base.Class = (node, st, c) => { + if (node.id) c(node.id, st, "Pattern") + if (node.superClass) c(node.superClass, st, "Expression") + for (let i = 0; i < node.body.body.length; i++) + c(node.body.body[i], st) +} +base.MethodDefinition = base.Property = (node, st, c) => { + if (node.computed) c(node.key, st, "Expression") + c(node.value, st, "Expression") +} diff --git a/node_modules/acorn-dynamic-import/node_modules/acorn/src/whitespace.js b/node_modules/acorn-dynamic-import/node_modules/acorn/src/whitespace.js new file mode 100644 index 000000000..094c2e4a4 --- /dev/null +++ b/node_modules/acorn-dynamic-import/node_modules/acorn/src/whitespace.js @@ -0,0 +1,13 @@ +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +export const lineBreak = /\r\n?|\n|\u2028|\u2029/ +export const lineBreakG = new RegExp(lineBreak.source, "g") + +export function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 +} + +export const nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +export const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g diff --git a/node_modules/acorn-dynamic-import/package.json b/node_modules/acorn-dynamic-import/package.json new file mode 100644 index 000000000..0b8e1a37a --- /dev/null +++ b/node_modules/acorn-dynamic-import/package.json @@ -0,0 +1,45 @@ +{ + "name": "acorn-dynamic-import", + "description": "Support dynamic imports in acorn", + "main": "lib/index.js", + "homepage": "https://github.com/kesne/acorn-dynamic-import", + "author": "Jordan Gensler <jordangens@gmail.com>", + "repository": { + "type": "git", + "url": "https://github.com/kesne/acorn-dynamic-import" + }, + "license": "MIT", + "scripts": { + "build": "babel src --out-dir lib", + "test": "npm run lint && npm run tests-only", + "lint": "eslint .", + "tests-only": "mocha", + "prepublish": "in-publish && safe-publish-latest && npm run build || not-in-publish", + "check-changelog": "expr $(git status --porcelain 2>/dev/null| grep \"^\\s*M.*CHANGELOG.md\" | wc -l) >/dev/null || (echo 'Please edit CHANGELOG.md' && exit 1)", + "check-only-changelog-changed": "(expr $(git status --porcelain 2>/dev/null| grep -v \"CHANGELOG.md\" | wc -l) >/dev/null && echo 'Only CHANGELOG.md may have uncommitted changes' && exit 1) || exit 0", + "version:major": "npm --no-git-tag-version version major", + "version:minor": "npm --no-git-tag-version version minor", + "version:patch": "npm --no-git-tag-version version patch", + "postversion": "git commit package.json CHANGELOG.md -m \"v$npm_package_version\" && npm run tag && git push && git push --tags", + "preversion": "npm run test && npm run check-changelog && npm run check-only-changelog-changed", + "tag": "git tag v$npm_package_version" + }, + "dependencies": { + "acorn": "^4.0.3" + }, + "devDependencies": { + "babel-cli": "^6.18.0", + "babel-eslint": "^7.1.1", + "babel-preset-airbnb": "^2.1.1", + "babel-register": "^6.18.0", + "chai": "^3.0.0", + "eslint": "^3.10.2", + "eslint-config-airbnb-base": "^10.0.1", + "eslint-plugin-import": "^2.2.0", + "in-publish": "^2.0.0", + "mocha": "^2.2.5", + "rimraf": "^2.5.4", + "safe-publish-latest": "^1.1.1" + }, + "version": "2.0.2" +} diff --git a/node_modules/acorn-dynamic-import/src/index.js b/node_modules/acorn-dynamic-import/src/index.js new file mode 100644 index 000000000..6eb1d4140 --- /dev/null +++ b/node_modules/acorn-dynamic-import/src/index.js @@ -0,0 +1,4 @@ +import * as acorn from 'acorn'; +import inject from './inject'; + +export default inject(acorn); diff --git a/node_modules/acorn-dynamic-import/src/inject.js b/node_modules/acorn-dynamic-import/src/inject.js new file mode 100644 index 000000000..7a666b278 --- /dev/null +++ b/node_modules/acorn-dynamic-import/src/inject.js @@ -0,0 +1,50 @@ +/* eslint-disable no-underscore-dangle */ + +export default function injectDynamicImport(acorn) { + const tt = acorn.tokTypes; + + // NOTE: This allows `yield import()` to parse correctly. + tt._import.startsExpr = true; + + function parseDynamicImport() { + const node = this.startNode(); + this.next(); + if (this.type !== tt.parenL) { + this.unexpected(); + } + return this.finishNode(node, 'Import'); + } + + function peekNext() { + return this.input[this.pos]; + } + + // eslint-disable-next-line no-param-reassign + acorn.plugins.dynamicImport = function dynamicImportPlugin(instance) { + instance.extend('parseStatement', nextMethod => ( + function parseStatement(...args) { + const node = this.startNode(); + if (this.type === tt._import) { + const nextToken = peekNext.call(this); + if (nextToken === tt.parenL.label) { + const expr = this.parseExpression(); + return this.parseExpressionStatement(node, expr); + } + } + + return nextMethod.apply(this, args); + } + )); + + instance.extend('parseExprAtom', nextMethod => ( + function parseExprAtom(refDestructuringErrors) { + if (this.type === tt._import) { + return parseDynamicImport.call(this); + } + return nextMethod.call(this, refDestructuringErrors); + } + )); + }; + + return acorn; +} |