Commit 13ad2c1f 13ad2c1fed02ea7f36895a143385a13cdde86ff6 by zhanghao

commit

1 parent 272cf8a1
Showing 1000 changed files with 3295 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 ../acorn/bin/acorn
...\ No newline at end of file ...\ No newline at end of file
1 ../ansi-html/bin/ansi-html
...\ No newline at end of file ...\ No newline at end of file
1 ../atob/bin/atob.js
...\ No newline at end of file ...\ No newline at end of file
1 ../autoprefixer/bin/autoprefixer-info
...\ No newline at end of file ...\ No newline at end of file
1 ../babylon/bin/babylon.js
...\ No newline at end of file ...\ No newline at end of file
1 ../browserslist/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../cssesc/bin/cssesc
...\ No newline at end of file ...\ No newline at end of file
1 ../csso/bin/csso
...\ No newline at end of file ...\ No newline at end of file
1 ../errno/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../esprima/bin/esparse.js
...\ No newline at end of file ...\ No newline at end of file
1 ../esprima/bin/esvalidate.js
...\ No newline at end of file ...\ No newline at end of file
1 ../he/bin/he
...\ No newline at end of file ...\ No newline at end of file
1 ../html-minifier/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../import-local/fixtures/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../internal-ip/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../js-yaml/bin/js-yaml.js
...\ No newline at end of file ...\ No newline at end of file
1 ../jsesc/bin/jsesc
...\ No newline at end of file ...\ No newline at end of file
1 ../json5/lib/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../loose-envify/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../miller-rabin/bin/miller-rabin
...\ No newline at end of file ...\ No newline at end of file
1 ../mime/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../mkdirp/bin/cmd.js
...\ No newline at end of file ...\ No newline at end of file
1 ../multicast-dns/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../opener/bin/opener-bin.js
...\ No newline at end of file ...\ No newline at end of file
1 ../prettier/bin-prettier.js
...\ No newline at end of file ...\ No newline at end of file
1 ../regjsparser/bin/parser
...\ No newline at end of file ...\ No newline at end of file
1 ../rimraf/bin.js
...\ No newline at end of file ...\ No newline at end of file
1 ../semver/bin/semver
...\ No newline at end of file ...\ No newline at end of file
1 ../sha.js/bin.js
...\ No newline at end of file ...\ No newline at end of file
1 ../shelljs/bin/shjs
...\ No newline at end of file ...\ No newline at end of file
1 ../strip-indent/cli.js
...\ No newline at end of file ...\ No newline at end of file
1 ../svgo/bin/svgo
...\ No newline at end of file ...\ No newline at end of file
1 ../uglify-js/bin/uglifyjs
...\ No newline at end of file ...\ No newline at end of file
1 ../uuid/bin/uuid
...\ No newline at end of file ...\ No newline at end of file
1 ../webpack/bin/webpack.js
...\ No newline at end of file ...\ No newline at end of file
1 ../webpack-bundle-analyzer/lib/bin/analyzer.js
...\ No newline at end of file ...\ No newline at end of file
1 ../webpack-dev-server/bin/webpack-dev-server.js
...\ No newline at end of file ...\ No newline at end of file
1 ../which/bin/which
...\ No newline at end of file ...\ No newline at end of file
1 1.3.7 / 2019-04-29
2 ==================
3
4 * deps: negotiator@0.6.2
5 - Fix sorting charset, encoding, and language with extra parameters
6
7 1.3.6 / 2019-04-28
8 ==================
9
10 * deps: mime-types@~2.1.24
11 - deps: mime-db@~1.40.0
12
13 1.3.5 / 2018-02-28
14 ==================
15
16 * deps: mime-types@~2.1.18
17 - deps: mime-db@~1.33.0
18
19 1.3.4 / 2017-08-22
20 ==================
21
22 * deps: mime-types@~2.1.16
23 - deps: mime-db@~1.29.0
24
25 1.3.3 / 2016-05-02
26 ==================
27
28 * deps: mime-types@~2.1.11
29 - deps: mime-db@~1.23.0
30 * deps: negotiator@0.6.1
31 - perf: improve `Accept` parsing speed
32 - perf: improve `Accept-Charset` parsing speed
33 - perf: improve `Accept-Encoding` parsing speed
34 - perf: improve `Accept-Language` parsing speed
35
36 1.3.2 / 2016-03-08
37 ==================
38
39 * deps: mime-types@~2.1.10
40 - Fix extension of `application/dash+xml`
41 - Update primary extension for `audio/mp4`
42 - deps: mime-db@~1.22.0
43
44 1.3.1 / 2016-01-19
45 ==================
46
47 * deps: mime-types@~2.1.9
48 - deps: mime-db@~1.21.0
49
50 1.3.0 / 2015-09-29
51 ==================
52
53 * deps: mime-types@~2.1.7
54 - deps: mime-db@~1.19.0
55 * deps: negotiator@0.6.0
56 - Fix including type extensions in parameters in `Accept` parsing
57 - Fix parsing `Accept` parameters with quoted equals
58 - Fix parsing `Accept` parameters with quoted semicolons
59 - Lazy-load modules from main entry point
60 - perf: delay type concatenation until needed
61 - perf: enable strict mode
62 - perf: hoist regular expressions
63 - perf: remove closures getting spec properties
64 - perf: remove a closure from media type parsing
65 - perf: remove property delete from media type parsing
66
67 1.2.13 / 2015-09-06
68 ===================
69
70 * deps: mime-types@~2.1.6
71 - deps: mime-db@~1.18.0
72
73 1.2.12 / 2015-07-30
74 ===================
75
76 * deps: mime-types@~2.1.4
77 - deps: mime-db@~1.16.0
78
79 1.2.11 / 2015-07-16
80 ===================
81
82 * deps: mime-types@~2.1.3
83 - deps: mime-db@~1.15.0
84
85 1.2.10 / 2015-07-01
86 ===================
87
88 * deps: mime-types@~2.1.2
89 - deps: mime-db@~1.14.0
90
91 1.2.9 / 2015-06-08
92 ==================
93
94 * deps: mime-types@~2.1.1
95 - perf: fix deopt during mapping
96
97 1.2.8 / 2015-06-07
98 ==================
99
100 * deps: mime-types@~2.1.0
101 - deps: mime-db@~1.13.0
102 * perf: avoid argument reassignment & argument slice
103 * perf: avoid negotiator recursive construction
104 * perf: enable strict mode
105 * perf: remove unnecessary bitwise operator
106
107 1.2.7 / 2015-05-10
108 ==================
109
110 * deps: negotiator@0.5.3
111 - Fix media type parameter matching to be case-insensitive
112
113 1.2.6 / 2015-05-07
114 ==================
115
116 * deps: mime-types@~2.0.11
117 - deps: mime-db@~1.9.1
118 * deps: negotiator@0.5.2
119 - Fix comparing media types with quoted values
120 - Fix splitting media types with quoted commas
121
122 1.2.5 / 2015-03-13
123 ==================
124
125 * deps: mime-types@~2.0.10
126 - deps: mime-db@~1.8.0
127
128 1.2.4 / 2015-02-14
129 ==================
130
131 * Support Node.js 0.6
132 * deps: mime-types@~2.0.9
133 - deps: mime-db@~1.7.0
134 * deps: negotiator@0.5.1
135 - Fix preference sorting to be stable for long acceptable lists
136
137 1.2.3 / 2015-01-31
138 ==================
139
140 * deps: mime-types@~2.0.8
141 - deps: mime-db@~1.6.0
142
143 1.2.2 / 2014-12-30
144 ==================
145
146 * deps: mime-types@~2.0.7
147 - deps: mime-db@~1.5.0
148
149 1.2.1 / 2014-12-30
150 ==================
151
152 * deps: mime-types@~2.0.5
153 - deps: mime-db@~1.3.1
154
155 1.2.0 / 2014-12-19
156 ==================
157
158 * deps: negotiator@0.5.0
159 - Fix list return order when large accepted list
160 - Fix missing identity encoding when q=0 exists
161 - Remove dynamic building of Negotiator class
162
163 1.1.4 / 2014-12-10
164 ==================
165
166 * deps: mime-types@~2.0.4
167 - deps: mime-db@~1.3.0
168
169 1.1.3 / 2014-11-09
170 ==================
171
172 * deps: mime-types@~2.0.3
173 - deps: mime-db@~1.2.0
174
175 1.1.2 / 2014-10-14
176 ==================
177
178 * deps: negotiator@0.4.9
179 - Fix error when media type has invalid parameter
180
181 1.1.1 / 2014-09-28
182 ==================
183
184 * deps: mime-types@~2.0.2
185 - deps: mime-db@~1.1.0
186 * deps: negotiator@0.4.8
187 - Fix all negotiations to be case-insensitive
188 - Stable sort preferences of same quality according to client order
189
190 1.1.0 / 2014-09-02
191 ==================
192
193 * update `mime-types`
194
195 1.0.7 / 2014-07-04
196 ==================
197
198 * Fix wrong type returned from `type` when match after unknown extension
199
200 1.0.6 / 2014-06-24
201 ==================
202
203 * deps: negotiator@0.4.7
204
205 1.0.5 / 2014-06-20
206 ==================
207
208 * fix crash when unknown extension given
209
210 1.0.4 / 2014-06-19
211 ==================
212
213 * use `mime-types`
214
215 1.0.3 / 2014-06-11
216 ==================
217
218 * deps: negotiator@0.4.6
219 - Order by specificity when quality is the same
220
221 1.0.2 / 2014-05-29
222 ==================
223
224 * Fix interpretation when header not in request
225 * deps: pin negotiator@0.4.5
226
227 1.0.1 / 2014-01-18
228 ==================
229
230 * Identity encoding isn't always acceptable
231 * deps: negotiator@~0.4.0
232
233 1.0.0 / 2013-12-27
234 ==================
235
236 * Genesis
1 (The MIT License)
2
3 Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
4 Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 'Software'), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 # accepts
2
3 [![NPM Version][npm-version-image]][npm-url]
4 [![NPM Downloads][npm-downloads-image]][npm-url]
5 [![Node.js Version][node-version-image]][node-version-url]
6 [![Build Status][travis-image]][travis-url]
7 [![Test Coverage][coveralls-image]][coveralls-url]
8
9 Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
10 Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
11
12 In addition to negotiator, it allows:
13
14 - Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
15 as well as `('text/html', 'application/json')`.
16 - Allows type shorthands such as `json`.
17 - Returns `false` when no types match
18 - Treats non-existent headers as `*`
19
20 ## Installation
21
22 This is a [Node.js](https://nodejs.org/en/) module available through the
23 [npm registry](https://www.npmjs.com/). Installation is done using the
24 [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
25
26 ```sh
27 $ npm install accepts
28 ```
29
30 ## API
31
32 <!-- eslint-disable no-unused-vars -->
33
34 ```js
35 var accepts = require('accepts')
36 ```
37
38 ### accepts(req)
39
40 Create a new `Accepts` object for the given `req`.
41
42 #### .charset(charsets)
43
44 Return the first accepted charset. If nothing in `charsets` is accepted,
45 then `false` is returned.
46
47 #### .charsets()
48
49 Return the charsets that the request accepts, in the order of the client's
50 preference (most preferred first).
51
52 #### .encoding(encodings)
53
54 Return the first accepted encoding. If nothing in `encodings` is accepted,
55 then `false` is returned.
56
57 #### .encodings()
58
59 Return the encodings that the request accepts, in the order of the client's
60 preference (most preferred first).
61
62 #### .language(languages)
63
64 Return the first accepted language. If nothing in `languages` is accepted,
65 then `false` is returned.
66
67 #### .languages()
68
69 Return the languages that the request accepts, in the order of the client's
70 preference (most preferred first).
71
72 #### .type(types)
73
74 Return the first accepted type (and it is returned as the same text as what
75 appears in the `types` array). If nothing in `types` is accepted, then `false`
76 is returned.
77
78 The `types` array can contain full MIME types or file extensions. Any value
79 that is not a full MIME types is passed to `require('mime-types').lookup`.
80
81 #### .types()
82
83 Return the types that the request accepts, in the order of the client's
84 preference (most preferred first).
85
86 ## Examples
87
88 ### Simple type negotiation
89
90 This simple example shows how to use `accepts` to return a different typed
91 respond body based on what the client wants to accept. The server lists it's
92 preferences in order and will get back the best match between the client and
93 server.
94
95 ```js
96 var accepts = require('accepts')
97 var http = require('http')
98
99 function app (req, res) {
100 var accept = accepts(req)
101
102 // the order of this list is significant; should be server preferred order
103 switch (accept.type(['json', 'html'])) {
104 case 'json':
105 res.setHeader('Content-Type', 'application/json')
106 res.write('{"hello":"world!"}')
107 break
108 case 'html':
109 res.setHeader('Content-Type', 'text/html')
110 res.write('<b>hello, world!</b>')
111 break
112 default:
113 // the fallback is text/plain, so no need to specify it above
114 res.setHeader('Content-Type', 'text/plain')
115 res.write('hello, world!')
116 break
117 }
118
119 res.end()
120 }
121
122 http.createServer(app).listen(3000)
123 ```
124
125 You can test this out with the cURL program:
126 ```sh
127 curl -I -H'Accept: text/html' http://localhost:3000/
128 ```
129
130 ## License
131
132 [MIT](LICENSE)
133
134 [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
135 [coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
136 [node-version-image]: https://badgen.net/npm/node/accepts
137 [node-version-url]: https://nodejs.org/en/download
138 [npm-downloads-image]: https://badgen.net/npm/dm/accepts
139 [npm-url]: https://npmjs.org/package/accepts
140 [npm-version-image]: https://badgen.net/npm/v/accepts
141 [travis-image]: https://badgen.net/travis/jshttp/accepts/master
142 [travis-url]: https://travis-ci.org/jshttp/accepts
1 /*!
2 * accepts
3 * Copyright(c) 2014 Jonathan Ong
4 * Copyright(c) 2015 Douglas Christopher Wilson
5 * MIT Licensed
6 */
7
8 'use strict'
9
10 /**
11 * Module dependencies.
12 * @private
13 */
14
15 var Negotiator = require('negotiator')
16 var mime = require('mime-types')
17
18 /**
19 * Module exports.
20 * @public
21 */
22
23 module.exports = Accepts
24
25 /**
26 * Create a new Accepts object for the given req.
27 *
28 * @param {object} req
29 * @public
30 */
31
32 function Accepts (req) {
33 if (!(this instanceof Accepts)) {
34 return new Accepts(req)
35 }
36
37 this.headers = req.headers
38 this.negotiator = new Negotiator(req)
39 }
40
41 /**
42 * Check if the given `type(s)` is acceptable, returning
43 * the best match when true, otherwise `undefined`, in which
44 * case you should respond with 406 "Not Acceptable".
45 *
46 * The `type` value may be a single mime type string
47 * such as "application/json", the extension name
48 * such as "json" or an array `["json", "html", "text/plain"]`. When a list
49 * or array is given the _best_ match, if any is returned.
50 *
51 * Examples:
52 *
53 * // Accept: text/html
54 * this.types('html');
55 * // => "html"
56 *
57 * // Accept: text/*, application/json
58 * this.types('html');
59 * // => "html"
60 * this.types('text/html');
61 * // => "text/html"
62 * this.types('json', 'text');
63 * // => "json"
64 * this.types('application/json');
65 * // => "application/json"
66 *
67 * // Accept: text/*, application/json
68 * this.types('image/png');
69 * this.types('png');
70 * // => undefined
71 *
72 * // Accept: text/*;q=.5, application/json
73 * this.types(['html', 'json']);
74 * this.types('html', 'json');
75 * // => "json"
76 *
77 * @param {String|Array} types...
78 * @return {String|Array|Boolean}
79 * @public
80 */
81
82 Accepts.prototype.type =
83 Accepts.prototype.types = function (types_) {
84 var types = types_
85
86 // support flattened arguments
87 if (types && !Array.isArray(types)) {
88 types = new Array(arguments.length)
89 for (var i = 0; i < types.length; i++) {
90 types[i] = arguments[i]
91 }
92 }
93
94 // no types, return all requested types
95 if (!types || types.length === 0) {
96 return this.negotiator.mediaTypes()
97 }
98
99 // no accept header, return first given type
100 if (!this.headers.accept) {
101 return types[0]
102 }
103
104 var mimes = types.map(extToMime)
105 var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
106 var first = accepts[0]
107
108 return first
109 ? types[mimes.indexOf(first)]
110 : false
111 }
112
113 /**
114 * Return accepted encodings or best fit based on `encodings`.
115 *
116 * Given `Accept-Encoding: gzip, deflate`
117 * an array sorted by quality is returned:
118 *
119 * ['gzip', 'deflate']
120 *
121 * @param {String|Array} encodings...
122 * @return {String|Array}
123 * @public
124 */
125
126 Accepts.prototype.encoding =
127 Accepts.prototype.encodings = function (encodings_) {
128 var encodings = encodings_
129
130 // support flattened arguments
131 if (encodings && !Array.isArray(encodings)) {
132 encodings = new Array(arguments.length)
133 for (var i = 0; i < encodings.length; i++) {
134 encodings[i] = arguments[i]
135 }
136 }
137
138 // no encodings, return all requested encodings
139 if (!encodings || encodings.length === 0) {
140 return this.negotiator.encodings()
141 }
142
143 return this.negotiator.encodings(encodings)[0] || false
144 }
145
146 /**
147 * Return accepted charsets or best fit based on `charsets`.
148 *
149 * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
150 * an array sorted by quality is returned:
151 *
152 * ['utf-8', 'utf-7', 'iso-8859-1']
153 *
154 * @param {String|Array} charsets...
155 * @return {String|Array}
156 * @public
157 */
158
159 Accepts.prototype.charset =
160 Accepts.prototype.charsets = function (charsets_) {
161 var charsets = charsets_
162
163 // support flattened arguments
164 if (charsets && !Array.isArray(charsets)) {
165 charsets = new Array(arguments.length)
166 for (var i = 0; i < charsets.length; i++) {
167 charsets[i] = arguments[i]
168 }
169 }
170
171 // no charsets, return all requested charsets
172 if (!charsets || charsets.length === 0) {
173 return this.negotiator.charsets()
174 }
175
176 return this.negotiator.charsets(charsets)[0] || false
177 }
178
179 /**
180 * Return accepted languages or best fit based on `langs`.
181 *
182 * Given `Accept-Language: en;q=0.8, es, pt`
183 * an array sorted by quality is returned:
184 *
185 * ['es', 'pt', 'en']
186 *
187 * @param {String|Array} langs...
188 * @return {Array|String}
189 * @public
190 */
191
192 Accepts.prototype.lang =
193 Accepts.prototype.langs =
194 Accepts.prototype.language =
195 Accepts.prototype.languages = function (languages_) {
196 var languages = languages_
197
198 // support flattened arguments
199 if (languages && !Array.isArray(languages)) {
200 languages = new Array(arguments.length)
201 for (var i = 0; i < languages.length; i++) {
202 languages[i] = arguments[i]
203 }
204 }
205
206 // no languages, return all requested languages
207 if (!languages || languages.length === 0) {
208 return this.negotiator.languages()
209 }
210
211 return this.negotiator.languages(languages)[0] || false
212 }
213
214 /**
215 * Convert extnames to mime.
216 *
217 * @param {String} type
218 * @return {String}
219 * @private
220 */
221
222 function extToMime (type) {
223 return type.indexOf('/') === -1
224 ? mime.lookup(type)
225 : type
226 }
227
228 /**
229 * Check if mime is valid.
230 *
231 * @param {String} type
232 * @return {String}
233 * @private
234 */
235
236 function validMime (type) {
237 return typeof type === 'string'
238 }
1 {
2 "_from": "accepts@~1.3.7",
3 "_id": "accepts@1.3.7",
4 "_inBundle": false,
5 "_integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
6 "_location": "/accepts",
7 "_phantomChildren": {},
8 "_requested": {
9 "type": "range",
10 "registry": true,
11 "raw": "accepts@~1.3.7",
12 "name": "accepts",
13 "escapedName": "accepts",
14 "rawSpec": "~1.3.7",
15 "saveSpec": null,
16 "fetchSpec": "~1.3.7"
17 },
18 "_requiredBy": [
19 "/compression",
20 "/express",
21 "/serve-index"
22 ],
23 "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
24 "_shasum": "531bc726517a3b2b41f850021c6cc15eaab507cd",
25 "_spec": "accepts@~1.3.7",
26 "_where": "/Users/zhanghao/brcode/br-client/node_modules/express",
27 "bugs": {
28 "url": "https://github.com/jshttp/accepts/issues"
29 },
30 "bundleDependencies": false,
31 "contributors": [
32 {
33 "name": "Douglas Christopher Wilson",
34 "email": "doug@somethingdoug.com"
35 },
36 {
37 "name": "Jonathan Ong",
38 "email": "me@jongleberry.com",
39 "url": "http://jongleberry.com"
40 }
41 ],
42 "dependencies": {
43 "mime-types": "~2.1.24",
44 "negotiator": "0.6.2"
45 },
46 "deprecated": false,
47 "description": "Higher-level content negotiation",
48 "devDependencies": {
49 "deep-equal": "1.0.1",
50 "eslint": "5.16.0",
51 "eslint-config-standard": "12.0.0",
52 "eslint-plugin-import": "2.17.2",
53 "eslint-plugin-markdown": "1.0.0",
54 "eslint-plugin-node": "8.0.1",
55 "eslint-plugin-promise": "4.1.1",
56 "eslint-plugin-standard": "4.0.0",
57 "mocha": "6.1.4",
58 "nyc": "14.0.0"
59 },
60 "engines": {
61 "node": ">= 0.6"
62 },
63 "files": [
64 "LICENSE",
65 "HISTORY.md",
66 "index.js"
67 ],
68 "homepage": "https://github.com/jshttp/accepts#readme",
69 "keywords": [
70 "content",
71 "negotiation",
72 "accept",
73 "accepts"
74 ],
75 "license": "MIT",
76 "name": "accepts",
77 "repository": {
78 "type": "git",
79 "url": "git+https://github.com/jshttp/accepts.git"
80 },
81 "scripts": {
82 "lint": "eslint --plugin markdown --ext js,md .",
83 "test": "mocha --reporter spec --check-leaks --bail test/",
84 "test-cov": "nyc --reporter=html --reporter=text npm test",
85 "test-travis": "nyc --reporter=text npm test"
86 },
87 "version": "1.3.7"
88 }
1 # 2.0.2
2
3 - Fixing parsing of `yield import()`.
4
5 # 2.0.1
6
7 - Removing unnecessary `in-publish` dependency.
8
9 # 2.0.0
10
11 - Updating acorn version to >= 4.
12
13 # 1.0.1
14
15 - Fixes for publishing the module.
16
17 # 1.0.0
18
19 - Initial release of plugin.
1 MIT License
2
3 Copyright (c) 2016 Jordan Gensler
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
1 # Dynamic import support in acorn
2
3 This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
4
5 For more information, check out the [proposal repo](https://github.com/tc39/proposal-dynamic-import).
6
7 ## Usage
8
9 You can use this module directly in order to get Acorn instance with plugin installed:
10
11 ```js
12 import acorn from 'acorn-dynamic-import';
13 // or...
14 const acorn = require('acorn-dynamic-import').default;
15 ```
16
17 Or you can use `inject.js` for injecting plugin into your own version of Acorn like this:
18
19 ```js
20 const acorn = require('acorn-dynamic-import/lib/inject').default(require('./custom-acorn'));
21 ```
22
23 Then, use the `plugins` option whenever you need to support dynamicImport while parsing:
24
25 ```js
26 const ast = acorn.parse(code, {
27 plugins: { dynamicImport: true }
28 });
29 ```
30
31 ## License
32
33 This plugin is issued under the [MIT license](./LICENSE).
1 Object.defineProperty(exports, "__esModule", {
2 value: true
3 });
4
5 var _acorn = require('acorn');
6
7 var acorn = _interopRequireWildcard(_acorn);
8
9 var _inject = require('./inject');
10
11 var _inject2 = _interopRequireDefault(_inject);
12
13 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14
15 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; } }
16
17 exports['default'] = (0, _inject2['default'])(acorn);
...\ No newline at end of file ...\ No newline at end of file
1 Object.defineProperty(exports, "__esModule", {
2 value: true
3 });
4 exports['default'] = injectDynamicImport;
5 /* eslint-disable no-underscore-dangle */
6
7 function injectDynamicImport(acorn) {
8 var tt = acorn.tokTypes;
9
10 // NOTE: This allows `yield import()` to parse correctly.
11 tt._import.startsExpr = true;
12
13 function parseDynamicImport() {
14 var node = this.startNode();
15 this.next();
16 if (this.type !== tt.parenL) {
17 this.unexpected();
18 }
19 return this.finishNode(node, 'Import');
20 }
21
22 function peekNext() {
23 return this.input[this.pos];
24 }
25
26 // eslint-disable-next-line no-param-reassign
27 acorn.plugins.dynamicImport = function () {
28 function dynamicImportPlugin(instance) {
29 instance.extend('parseStatement', function (nextMethod) {
30 return function () {
31 function parseStatement() {
32 var node = this.startNode();
33 if (this.type === tt._import) {
34 var nextToken = peekNext.call(this);
35 if (nextToken === tt.parenL.label) {
36 var expr = this.parseExpression();
37 return this.parseExpressionStatement(node, expr);
38 }
39 }
40
41 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
42 args[_key] = arguments[_key];
43 }
44
45 return nextMethod.apply(this, args);
46 }
47
48 return parseStatement;
49 }();
50 });
51
52 instance.extend('parseExprAtom', function (nextMethod) {
53 return function () {
54 function parseExprAtom(refDestructuringErrors) {
55 if (this.type === tt._import) {
56 return parseDynamicImport.call(this);
57 }
58 return nextMethod.call(this, refDestructuringErrors);
59 }
60
61 return parseExprAtom;
62 }();
63 });
64 }
65
66 return dynamicImportPlugin;
67 }();
68
69 return acorn;
70 }
...\ No newline at end of file ...\ No newline at end of file
1 ../acorn/bin/acorn
...\ No newline at end of file ...\ No newline at end of file
1 /.tern-port
2 /test
3 /local
4 /rollup
5 /bin/generate-identifier-regex.js
6 /bin/update_authors.sh
7 .editorconfig
8 .gitattributes
9 .tern-project
10 .travis.yml
1 List of Acorn contributors. Updated before every release.
2
3 Adrian Rakovsky
4 Alistair Braidwood
5 Amila Welihinda
6 Andres Suarez
7 Angelo
8 Aparajita Fishman
9 Arian Stolwijk
10 Artem Govorov
11 Brandon Mills
12 Charles Hughes
13 Conrad Irwin
14 Daniel Tschinder
15 David Bonnet
16 Domenico Matteo
17 Forbes Lindesay
18 Gilad Peleg
19 impinball
20 Ingvar Stepanyan
21 Jackson Ray Hamilton
22 Jesse McCarthy
23 Jiaxing Wang
24 Joel Kemp
25 Johannes Herr
26 Jordan Klassen
27 Jürg Lehni
28 Kai Cataldo
29 keeyipchan
30 Keheliya Gallaba
31 Kevin Irish
32 Kevin Kwok
33 krator
34 Marijn Haverbeke
35 Martin Carlberg
36 Mat Garcia
37 Mathias Bynens
38 Mathieu 'p01' Henri
39 Matthew Bastien
40 Max Schaefer
41 Max Zerzouri
42 Mihai Bazon
43 Mike Rennie
44 naoh
45 Nicholas C. Zakas
46 Nick Fitzgerald
47 Olivier Thomann
48 Oskar Schöldström
49 Paul Harper
50 Peter Rust
51 PlNG
52 Prayag Verma
53 ReadmeCritic
54 r-e-d
55 Richard Gibson
56 Rich Harris
57 Sebastian McKenzie
58 Simen Bekkhus
59 Timothy Gu
60 Toru Nagashima
61 Wexpo Lyu
62 zsjforcn
1 ## 4.0.11 (2017-02-07)
2
3 ### Bug fixes
4
5 Allow all forms of member expressions to be parenthesized as lvalue.
6
7 ## 4.0.10 (2017-02-07)
8
9 ### Bug fixes
10
11 Don't expect semicolons after default-exported functions or classes,
12 even when they are expressions.
13
14 Check for use of `'use strict'` directives in non-simple parameter
15 functions, even when already in strict mode.
16
17 ## 4.0.9 (2017-02-06)
18
19 ### Bug fixes
20
21 Fix incorrect error raised for parenthesized simple assignment
22 targets, so that `(x) = 1` parses again.
23
24 ## 4.0.8 (2017-02-03)
25
26 ### Bug fixes
27
28 Solve spurious parenthesized pattern errors by temporarily erring on
29 the side of accepting programs that our delayed errors don't handle
30 correctly yet.
31
32 ## 4.0.7 (2017-02-02)
33
34 ### Bug fixes
35
36 Accept invalidly rejected code like `(x).y = 2` again.
37
38 Don't raise an error when a function _inside_ strict code has a
39 non-simple parameter list.
40
41 ## 4.0.6 (2017-02-02)
42
43 ### Bug fixes
44
45 Fix exponential behavior (manifesting itself as a complete hang for
46 even relatively small source files) introduced by the new 'use strict'
47 check.
48
49 ## 4.0.5 (2017-02-02)
50
51 ### Bug fixes
52
53 Disallow parenthesized pattern expressions.
54
55 Allow keywords as export names.
56
57 Don't allow the `async` keyword to be parenthesized.
58
59 Properly raise an error when a keyword contains a character escape.
60
61 Allow `"use strict"` to appear after other string literal expressions.
62
63 Disallow labeled declarations.
64
65 ## 4.0.4 (2016-12-19)
66
67 ### Bug fixes
68
69 Fix issue with loading acorn_loose.js with an AMD loader.
70
71 Fix crash when `export` was followed by a keyword that can't be
72 exported.
73
74 ## 4.0.3 (2016-08-16)
75
76 ### Bug fixes
77
78 Allow regular function declarations inside single-statement `if`
79 branches in loose mode. Forbid them entirely in strict mode.
80
81 Properly parse properties named `async` in ES2017 mode.
82
83 Fix bug where reserved words were broken in ES2017 mode.
84
85 ## 4.0.2 (2016-08-11)
86
87 ### Bug fixes
88
89 Don't ignore period or 'e' characters after octal numbers.
90
91 Fix broken parsing for call expressions in default parameter values
92 of arrow functions.
93
94 ## 4.0.1 (2016-08-08)
95
96 ### Bug fixes
97
98 Fix false positives in duplicated export name errors.
99
100 ## 4.0.0 (2016-08-07)
101
102 ### Breaking changes
103
104 The default `ecmaVersion` option value is now 7.
105
106 A number of internal method signatures changed, so plugins might need
107 to be updated.
108
109 ### Bug fixes
110
111 The parser now raises errors on duplicated export names.
112
113 `arguments` and `eval` can now be used in shorthand properties.
114
115 Duplicate parameter names in non-simple argument lists now always
116 produce an error.
117
118 ### New features
119
120 The `ecmaVersion` option now also accepts year-style version numbers
121 (2015, etc).
122
123 Support for `async`/`await` syntax when `ecmaVersion` is >= 8.
124
125 Support for trailing commas in call expressions when `ecmaVersion`
126 is >= 8.
127
128 ## 3.3.0 (2016-07-25)
129
130 ### Bug fixes
131
132 Fix bug in tokenizing of regexp operator after a function declaration.
133
134 Fix parser crash when parsing an array pattern with a hole.
135
136 ### New features
137
138 Implement check against complex argument lists in functions that
139 enable strict mode in ES7.
140
141 ## 3.2.0 (2016-06-07)
142
143 ### Bug fixes
144
145 Improve handling of lack of unicode regexp support in host
146 environment.
147
148 Properly reject shorthand properties whose name is a keyword.
149
150 Don't crash when the loose parser is called without options object.
151
152 ### New features
153
154 Visitors created with `visit.make` now have their base as _prototype_,
155 rather than copying properties into a fresh object.
156
157 Make it possible to use `visit.ancestor` with a walk state.
158
159 ## 3.1.0 (2016-04-18)
160
161 ### Bug fixes
162
163 Fix issue where the loose parser created invalid TemplateElement nodes
164 for unclosed template literals.
165
166 Properly tokenize the division operator directly after a function
167 expression.
168
169 Allow trailing comma in destructuring arrays.
170
171 ### New features
172
173 The walker now allows defining handlers for `CatchClause` nodes.
174
175 ## 3.0.4 (2016-02-25)
176
177 ### Fixes
178
179 Allow update expressions as left-hand-side of the ES7 exponential
180 operator.
181
182 ## 3.0.2 (2016-02-10)
183
184 ### Fixes
185
186 Fix bug that accidentally made `undefined` a reserved word when
187 parsing ES7.
188
189 ## 3.0.0 (2016-02-10)
190
191 ### Breaking changes
192
193 The default value of the `ecmaVersion` option is now 6 (used to be 5).
194
195 Support for comprehension syntax (which was dropped from the draft
196 spec) has been removed.
197
198 ### Fixes
199
200 `let` and `yield` are now “contextual keywords”, meaning you can
201 mostly use them as identifiers in ES5 non-strict code.
202
203 A parenthesized class or function expression after `export default` is
204 now parsed correctly.
205
206 ### New features
207
208 When `ecmaVersion` is set to 7, Acorn will parse the exponentiation
209 operator (`**`).
210
211 The identifier character ranges are now based on Unicode 8.0.0.
212
213 Plugins can now override the `raiseRecoverable` method to override the
214 way non-critical errors are handled.
215
216 ## 2.7.0 (2016-01-04)
217
218 ### Fixes
219
220 Stop allowing rest parameters in setters.
221
222 Make sure the loose parser always attaches a `local` property to
223 `ImportNamespaceSpecifier` nodes.
224
225 Disallow `y` rexexp flag in ES5.
226
227 Disallow `\00` and `\000` escapes in strict mode.
228
229 Raise an error when an import name is a reserved word.
230
231 ## 2.6.4 (2015-11-12)
232
233 ### Fixes
234
235 Fix crash in loose parser when parsing invalid object pattern.
236
237 ### New features
238
239 Support plugins in the loose parser.
240
241 ## 2.6.2 (2015-11-10)
242
243 ### Fixes
244
245 Don't crash when no options object is passed.
246
247 ## 2.6.0 (2015-11-09)
248
249 ### Fixes
250
251 Add `await` as a reserved word in module sources.
252
253 Disallow `yield` in a parameter default value for a generator.
254
255 Forbid using a comma after a rest pattern in an array destructuring.
256
257 ### New features
258
259 Support parsing stdin in command-line tool.
260
261 ## 2.5.2 (2015-10-27)
262
263 ### Fixes
264
265 Fix bug where the walker walked an exported `let` statement as an
266 expression.
267
268 ## 2.5.0 (2015-10-27)
269
270 ### Fixes
271
272 Fix tokenizer support in the command-line tool.
273
274 In the loose parser, don't allow non-string-literals as import
275 sources.
276
277 Stop allowing `new.target` outside of functions.
278
279 Remove legacy `guard` and `guardedHandler` properties from try nodes.
280
281 Stop allowing multiple `__proto__` properties on an object literal in
282 strict mode.
283
284 Don't allow rest parameters to be non-identifier patterns.
285
286 Check for duplicate paramter names in arrow functions.
1 Copyright (C) 2012-2016 by various contributors (see AUTHORS)
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE.
1 #!/usr/bin/env node
2 'use strict';
3
4 var path = require('path');
5 var fs = require('fs');
6 var acorn = require('../dist/acorn.js');
7
8 var infile;
9 var forceFile;
10 var silent = false;
11 var compact = false;
12 var tokenize = false;
13 var options = {}
14
15 function help(status) {
16 var print = (status == 0) ? console.log : console.error
17 print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]")
18 print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]")
19 process.exit(status)
20 }
21
22 for (var i = 2; i < process.argv.length; ++i) {
23 var arg = process.argv[i]
24 if ((arg == "-" || arg[0] != "-") && !infile) infile = arg
25 else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i]
26 else if (arg == "--locations") options.locations = true
27 else if (arg == "--allow-hash-bang") options.allowHashBang = true
28 else if (arg == "--silent") silent = true
29 else if (arg == "--compact") compact = true
30 else if (arg == "--help") help(0)
31 else if (arg == "--tokenize") tokenize = true
32 else if (arg == "--module") options.sourceType = 'module'
33 else {
34 var match = arg.match(/^--ecma(\d+)$/)
35 if (match)
36 options.ecmaVersion = +match[1]
37 else
38 help(1)
39 }
40 }
41
42 function run(code) {
43 var result
44 if (!tokenize) {
45 try { result = acorn.parse(code, options) }
46 catch(e) { console.error(e.message); process.exit(1) }
47 } else {
48 result = []
49 var tokenizer = acorn.tokenizer(code, options), token
50 while (true) {
51 try { token = tokenizer.getToken() }
52 catch(e) { console.error(e.message); process.exit(1) }
53 result.push(token)
54 if (token.type == acorn.tokTypes.eof) break
55 }
56 }
57 if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2))
58 }
59
60 if (forceFile || infile && infile != "-") {
61 run(fs.readFileSync(infile, "utf8"))
62 } else {
63 var code = ""
64 process.stdin.resume()
65 process.stdin.on("data", function (chunk) { return code += chunk; })
66 process.stdin.on("end", function () { return run(code); })
67 }
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
1 {
2 "_from": "acorn@^4.0.3",
3 "_id": "acorn@4.0.13",
4 "_inBundle": false,
5 "_integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
6 "_location": "/acorn-dynamic-import/acorn",
7 "_phantomChildren": {},
8 "_requested": {
9 "type": "range",
10 "registry": true,
11 "raw": "acorn@^4.0.3",
12 "name": "acorn",
13 "escapedName": "acorn",
14 "rawSpec": "^4.0.3",
15 "saveSpec": null,
16 "fetchSpec": "^4.0.3"
17 },
18 "_requiredBy": [
19 "/acorn-dynamic-import"
20 ],
21 "_resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
22 "_shasum": "105495ae5361d697bd195c825192e1ad7f253787",
23 "_spec": "acorn@^4.0.3",
24 "_where": "/Users/zhanghao/brcode/br-client/node_modules/acorn-dynamic-import",
25 "bin": {
26 "acorn": "bin/acorn"
27 },
28 "bugs": {
29 "url": "https://github.com/ternjs/acorn/issues"
30 },
31 "bundleDependencies": false,
32 "contributors": [
33 {
34 "name": "List of Acorn contributors. Updated before every release."
35 },
36 {
37 "name": "Adrian Rakovsky"
38 },
39 {
40 "name": "Alistair Braidwood"
41 },
42 {
43 "name": "Amila Welihinda"
44 },
45 {
46 "name": "Andres Suarez"
47 },
48 {
49 "name": "Angelo"
50 },
51 {
52 "name": "Aparajita Fishman"
53 },
54 {
55 "name": "Arian Stolwijk"
56 },
57 {
58 "name": "Artem Govorov"
59 },
60 {
61 "name": "Brandon Mills"
62 },
63 {
64 "name": "Charles Hughes"
65 },
66 {
67 "name": "Conrad Irwin"
68 },
69 {
70 "name": "Daniel Tschinder"
71 },
72 {
73 "name": "David Bonnet"
74 },
75 {
76 "name": "Domenico Matteo"
77 },
78 {
79 "name": "Forbes Lindesay"
80 },
81 {
82 "name": "Gilad Peleg"
83 },
84 {
85 "name": "impinball"
86 },
87 {
88 "name": "Ingvar Stepanyan"
89 },
90 {
91 "name": "Jackson Ray Hamilton"
92 },
93 {
94 "name": "Jesse McCarthy"
95 },
96 {
97 "name": "Jiaxing Wang"
98 },
99 {
100 "name": "Joel Kemp"
101 },
102 {
103 "name": "Johannes Herr"
104 },
105 {
106 "name": "Jordan Klassen"
107 },
108 {
109 "name": "Jürg Lehni"
110 },
111 {
112 "name": "Kai Cataldo"
113 },
114 {
115 "name": "keeyipchan"
116 },
117 {
118 "name": "Keheliya Gallaba"
119 },
120 {
121 "name": "Kevin Irish"
122 },
123 {
124 "name": "Kevin Kwok"
125 },
126 {
127 "name": "krator"
128 },
129 {
130 "name": "Marijn Haverbeke"
131 },
132 {
133 "name": "Martin Carlberg"
134 },
135 {
136 "name": "Mat Garcia"
137 },
138 {
139 "name": "Mathias Bynens"
140 },
141 {
142 "name": "Mathieu 'p01' Henri"
143 },
144 {
145 "name": "Matthew Bastien"
146 },
147 {
148 "name": "Max Schaefer"
149 },
150 {
151 "name": "Max Zerzouri"
152 },
153 {
154 "name": "Mihai Bazon"
155 },
156 {
157 "name": "Mike Rennie"
158 },
159 {
160 "name": "naoh"
161 },
162 {
163 "name": "Nicholas C. Zakas"
164 },
165 {
166 "name": "Nick Fitzgerald"
167 },
168 {
169 "name": "Olivier Thomann"
170 },
171 {
172 "name": "Oskar Schöldström"
173 },
174 {
175 "name": "Paul Harper"
176 },
177 {
178 "name": "Peter Rust"
179 },
180 {
181 "name": "PlNG"
182 },
183 {
184 "name": "Prayag Verma"
185 },
186 {
187 "name": "ReadmeCritic"
188 },
189 {
190 "name": "r-e-d"
191 },
192 {
193 "name": "Richard Gibson"
194 },
195 {
196 "name": "Rich Harris"
197 },
198 {
199 "name": "Sebastian McKenzie"
200 },
201 {
202 "name": "Simen Bekkhus"
203 },
204 {
205 "name": "Timothy Gu"
206 },
207 {
208 "name": "Toru Nagashima"
209 },
210 {
211 "name": "Wexpo Lyu"
212 },
213 {
214 "name": "zsjforcn"
215 }
216 ],
217 "deprecated": false,
218 "description": "ECMAScript parser",
219 "devDependencies": {
220 "rollup": "^0.34.1",
221 "rollup-plugin-buble": "^0.11.0",
222 "unicode-9.0.0": "^0.7.0"
223 },
224 "engines": {
225 "node": ">=0.4.0"
226 },
227 "homepage": "https://github.com/ternjs/acorn",
228 "jsnext:main": "dist/acorn.es.js",
229 "license": "MIT",
230 "main": "dist/acorn.js",
231 "maintainers": [
232 {
233 "name": "Marijn Haverbeke",
234 "email": "marijnh@gmail.com",
235 "url": "http://marijnhaverbeke.nl"
236 },
237 {
238 "name": "Ingvar Stepanyan",
239 "email": "me@rreverser.com",
240 "url": "http://rreverser.com/"
241 }
242 ],
243 "name": "acorn",
244 "repository": {
245 "type": "git",
246 "url": "git+https://github.com/ternjs/acorn.git"
247 },
248 "scripts": {
249 "build": "npm run build:main && npm run build:walk && npm run build:loose && npm run build:bin",
250 "build:bin": "rollup -c rollup/config.bin.js",
251 "build:loose": "rollup -c rollup/config.loose.js",
252 "build:main": "rollup -c rollup/config.main.js",
253 "build:walk": "rollup -c rollup/config.walk.js",
254 "prepublish": "npm test",
255 "pretest": "npm run build",
256 "test": "node test/run.js"
257 },
258 "version": "4.0.13"
259 }
1 import {basename} from "path"
2 import {readFileSync as readFile} from "fs"
3 import * as acorn from "acorn"
4
5 let infile, forceFile, silent = false, compact = false, tokenize = false
6 const options = {}
7
8 function help(status) {
9 const print = (status == 0) ? console.log : console.error
10 print("usage: " + basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]")
11 print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]")
12 process.exit(status)
13 }
14
15 for (let i = 2; i < process.argv.length; ++i) {
16 const arg = process.argv[i]
17 if ((arg == "-" || arg[0] != "-") && !infile) infile = arg
18 else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i]
19 else if (arg == "--locations") options.locations = true
20 else if (arg == "--allow-hash-bang") options.allowHashBang = true
21 else if (arg == "--silent") silent = true
22 else if (arg == "--compact") compact = true
23 else if (arg == "--help") help(0)
24 else if (arg == "--tokenize") tokenize = true
25 else if (arg == "--module") options.sourceType = 'module'
26 else {
27 let match = arg.match(/^--ecma(\d+)$/)
28 if (match)
29 options.ecmaVersion = +match[1]
30 else
31 help(1)
32 }
33 }
34
35 function run(code) {
36 let result
37 if (!tokenize) {
38 try { result = acorn.parse(code, options) }
39 catch(e) { console.error(e.message); process.exit(1) }
40 } else {
41 result = []
42 let tokenizer = acorn.tokenizer(code, options), token
43 while (true) {
44 try { token = tokenizer.getToken() }
45 catch(e) { console.error(e.message); process.exit(1) }
46 result.push(token)
47 if (token.type == acorn.tokTypes.eof) break
48 }
49 }
50 if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2))
51 }
52
53 if (forceFile || infile && infile != "-") {
54 run(readFile(infile, "utf8"))
55 } else {
56 let code = ""
57 process.stdin.resume()
58 process.stdin.on("data", chunk => code += chunk)
59 process.stdin.on("end", () => run(code))
60 }
1 // Acorn is a tiny, fast JavaScript parser written in JavaScript.
2 //
3 // Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
4 // various contributors and released under an MIT license.
5 //
6 // Git repositories for Acorn are available at
7 //
8 // http://marijnhaverbeke.nl/git/acorn
9 // https://github.com/ternjs/acorn.git
10 //
11 // Please use the [github bug tracker][ghbt] to report issues.
12 //
13 // [ghbt]: https://github.com/ternjs/acorn/issues
14 //
15 // This file defines the main parser interface. The library also comes
16 // with a [error-tolerant parser][dammit] and an
17 // [abstract syntax tree walker][walk], defined in other files.
18 //
19 // [dammit]: acorn_loose.js
20 // [walk]: util/walk.js
21
22 import {Parser} from "./state"
23 import "./parseutil"
24 import "./statement"
25 import "./lval"
26 import "./expression"
27 import "./location"
28
29 export {Parser, plugins} from "./state"
30 export {defaultOptions} from "./options"
31 export {Position, SourceLocation, getLineInfo} from "./locutil"
32 export {Node} from "./node"
33 export {TokenType, types as tokTypes, keywords as keywordTypes} from "./tokentype"
34 export {TokContext, types as tokContexts} from "./tokencontext"
35 export {isIdentifierChar, isIdentifierStart} from "./identifier"
36 export {Token} from "./tokenize"
37 export {isNewLine, lineBreak, lineBreakG} from "./whitespace"
38
39 export const version = "4.0.11"
40
41 // The main exported interface (under `self.acorn` when in the
42 // browser) is a `parse` function that takes a code string and
43 // returns an abstract syntax tree as specified by [Mozilla parser
44 // API][api].
45 //
46 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
47
48 export function parse(input, options) {
49 return new Parser(options, input).parse()
50 }
51
52 // This function tries to parse a single expression at a given
53 // offset in a string. Useful for parsing mixed-language formats
54 // that embed JavaScript expressions.
55
56 export function parseExpressionAt(input, pos, options) {
57 let p = new Parser(options, input, pos)
58 p.nextToken()
59 return p.parseExpression()
60 }
61
62 // Acorn is organized as a tokenizer and a recursive-descent parser.
63 // The `tokenizer` export provides an interface to the tokenizer.
64
65 export function tokenizer(input, options) {
66 return new Parser(options, input)
67 }
68
69 // This is a terrible kludge to support the existing, pre-ES6
70 // interface where the loose parser module retroactively adds exports
71 // to this module.
72 export let parse_dammit, LooseParser, pluginsLoose
73 export function addLooseExports(parse, Parser, plugins) {
74 parse_dammit = parse
75 LooseParser = Parser
76 pluginsLoose = plugins
77 }
1 import {Parser} from "./state"
2 import {Position, getLineInfo} from "./locutil"
3
4 const pp = Parser.prototype
5
6 // This function is used to raise exceptions on parse errors. It
7 // takes an offset integer (into the current `input`) to indicate
8 // the location of the error, attaches the position to the end
9 // of the error message, and then raises a `SyntaxError` with that
10 // message.
11
12 pp.raise = function(pos, message) {
13 let loc = getLineInfo(this.input, pos)
14 message += " (" + loc.line + ":" + loc.column + ")"
15 let err = new SyntaxError(message)
16 err.pos = pos; err.loc = loc; err.raisedAt = this.pos
17 throw err
18 }
19
20 pp.raiseRecoverable = pp.raise
21
22 pp.curPosition = function() {
23 if (this.options.locations) {
24 return new Position(this.curLine, this.pos - this.lineStart)
25 }
26 }
1 import {lineBreakG} from "./whitespace"
2
3 // These are used when `options.locations` is on, for the
4 // `startLoc` and `endLoc` properties.
5
6 export class Position {
7 constructor(line, col) {
8 this.line = line
9 this.column = col
10 }
11
12 offset(n) {
13 return new Position(this.line, this.column + n)
14 }
15 }
16
17 export class SourceLocation {
18 constructor(p, start, end) {
19 this.start = start
20 this.end = end
21 if (p.sourceFile !== null) this.source = p.sourceFile
22 }
23 }
24
25 // The `getLineInfo` function is mostly useful when the
26 // `locations` option is off (for performance reasons) and you
27 // want to find the line/column position for a given character
28 // offset. `input` should be the code string that the offset refers
29 // into.
30
31 export function getLineInfo(input, offset) {
32 for (let line = 1, cur = 0;;) {
33 lineBreakG.lastIndex = cur
34 let match = lineBreakG.exec(input)
35 if (match && match.index < offset) {
36 ++line
37 cur = match.index + match[0].length
38 } else {
39 return new Position(line, offset - cur)
40 }
41 }
42 }
1 // Acorn: Loose parser
2 //
3 // This module provides an alternative parser (`parse_dammit`) that
4 // exposes that same interface as `parse`, but will try to parse
5 // anything as JavaScript, repairing syntax error the best it can.
6 // There are circumstances in which it will raise an error and give
7 // up, but they are very rare. The resulting AST will be a mostly
8 // valid JavaScript AST (as per the [Mozilla parser API][api], except
9 // that:
10 //
11 // - Return outside functions is allowed
12 //
13 // - Label consistency (no conflicts, break only to existing labels)
14 // is not enforced.
15 //
16 // - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
17 // the parser got too confused to return anything meaningful.
18 //
19 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
20 //
21 // The expected use for this is to *first* try `acorn.parse`, and only
22 // if that fails switch to `parse_dammit`. The loose parser might
23 // parse badly indented code incorrectly, so **don't** use it as
24 // your default parser.
25 //
26 // Quite a lot of acorn.js is duplicated here. The alternative was to
27 // add a *lot* of extra cruft to that file, making it less readable
28 // and slower. Copying and editing the code allowed me to make
29 // invasive changes and simplifications without creating a complicated
30 // tangle.
31
32 import {addLooseExports, defaultOptions} from "../index"
33 import {LooseParser, pluginsLoose} from "./state"
34 import "./tokenize"
35 import "./statement"
36 import "./expression"
37
38 export {LooseParser, pluginsLoose} from "./state"
39
40 defaultOptions.tabSize = 4
41
42 export function parse_dammit(input, options) {
43 let p = new LooseParser(input, options)
44 p.next()
45 return p.parseTopLevel()
46 }
47
48 addLooseExports(parse_dammit, LooseParser, pluginsLoose)
1 export function isDummy(node) { return node.name == "✖" }
...\ No newline at end of file ...\ No newline at end of file
1 import {tokenizer, SourceLocation, tokTypes as tt, Node, lineBreak, isNewLine} from "../index"
2
3 // Registered plugins
4 export const pluginsLoose = {}
5
6 export class LooseParser {
7 constructor(input, options = {}) {
8 this.toks = tokenizer(input, options)
9 this.options = this.toks.options
10 this.input = this.toks.input
11 this.tok = this.last = {type: tt.eof, start: 0, end: 0}
12 if (this.options.locations) {
13 let here = this.toks.curPosition()
14 this.tok.loc = new SourceLocation(this.toks, here, here)
15 }
16 this.ahead = [] // Tokens ahead
17 this.context = [] // Indentation contexted
18 this.curIndent = 0
19 this.curLineStart = 0
20 this.nextLineStart = this.lineEnd(this.curLineStart) + 1
21 this.inAsync = false
22 // Load plugins
23 this.options.pluginsLoose = options.pluginsLoose || {}
24 this.loadPlugins(this.options.pluginsLoose)
25 }
26
27 startNode() {
28 return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null)
29 }
30
31 storeCurrentPos() {
32 return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start
33 }
34
35 startNodeAt(pos) {
36 if (this.options.locations) {
37 return new Node(this.toks, pos[0], pos[1])
38 } else {
39 return new Node(this.toks, pos)
40 }
41 }
42
43 finishNode(node, type) {
44 node.type = type
45 node.end = this.last.end
46 if (this.options.locations)
47 node.loc.end = this.last.loc.end
48 if (this.options.ranges)
49 node.range[1] = this.last.end
50 return node
51 }
52
53 dummyNode(type) {
54 let dummy = this.startNode()
55 dummy.type = type
56 dummy.end = dummy.start
57 if (this.options.locations)
58 dummy.loc.end = dummy.loc.start
59 if (this.options.ranges)
60 dummy.range[1] = dummy.start
61 this.last = {type: tt.name, start: dummy.start, end: dummy.start, loc: dummy.loc}
62 return dummy
63 }
64
65 dummyIdent() {
66 let dummy = this.dummyNode("Identifier")
67 dummy.name = "✖"
68 return dummy
69 }
70
71 dummyString() {
72 let dummy = this.dummyNode("Literal")
73 dummy.value = dummy.raw = "✖"
74 return dummy
75 }
76
77 eat(type) {
78 if (this.tok.type === type) {
79 this.next()
80 return true
81 } else {
82 return false
83 }
84 }
85
86 isContextual(name) {
87 return this.tok.type === tt.name && this.tok.value === name
88 }
89
90 eatContextual(name) {
91 return this.tok.value === name && this.eat(tt.name)
92 }
93
94 canInsertSemicolon() {
95 return this.tok.type === tt.eof || this.tok.type === tt.braceR ||
96 lineBreak.test(this.input.slice(this.last.end, this.tok.start))
97 }
98
99 semicolon() {
100 return this.eat(tt.semi)
101 }
102
103 expect(type) {
104 if (this.eat(type)) return true
105 for (let i = 1; i <= 2; i++) {
106 if (this.lookAhead(i).type == type) {
107 for (let j = 0; j < i; j++) this.next()
108 return true
109 }
110 }
111 }
112
113 pushCx() {
114 this.context.push(this.curIndent)
115 }
116
117 popCx() {
118 this.curIndent = this.context.pop()
119 }
120
121 lineEnd(pos) {
122 while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos
123 return pos
124 }
125
126 indentationAfter(pos) {
127 for (let count = 0;; ++pos) {
128 let ch = this.input.charCodeAt(pos)
129 if (ch === 32) ++count
130 else if (ch === 9) count += this.options.tabSize
131 else return count
132 }
133 }
134
135 closes(closeTok, indent, line, blockHeuristic) {
136 if (this.tok.type === closeTok || this.tok.type === tt.eof) return true
137 return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() &&
138 (!blockHeuristic || this.nextLineStart >= this.input.length ||
139 this.indentationAfter(this.nextLineStart) < indent)
140 }
141
142 tokenStartsLine() {
143 for (let p = this.tok.start - 1; p >= this.curLineStart; --p) {
144 let ch = this.input.charCodeAt(p)
145 if (ch !== 9 && ch !== 32) return false
146 }
147 return true
148 }
149
150 extend(name, f) {
151 this[name] = f(this[name])
152 }
153
154 loadPlugins(pluginConfigs) {
155 for (let name in pluginConfigs) {
156 let plugin = pluginsLoose[name]
157 if (!plugin) throw new Error("Plugin '" + name + "' not found")
158 plugin(this, pluginConfigs[name])
159 }
160 }
161 }
1 import {tokTypes as tt, Token, isNewLine, SourceLocation, getLineInfo, lineBreakG} from "../index"
2 import {LooseParser} from "./state"
3
4 const lp = LooseParser.prototype
5
6 function isSpace(ch) {
7 return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch)
8 }
9
10 lp.next = function() {
11 this.last = this.tok
12 if (this.ahead.length)
13 this.tok = this.ahead.shift()
14 else
15 this.tok = this.readToken()
16
17 if (this.tok.start >= this.nextLineStart) {
18 while (this.tok.start >= this.nextLineStart) {
19 this.curLineStart = this.nextLineStart
20 this.nextLineStart = this.lineEnd(this.curLineStart) + 1
21 }
22 this.curIndent = this.indentationAfter(this.curLineStart)
23 }
24 }
25
26 lp.readToken = function() {
27 for (;;) {
28 try {
29 this.toks.next()
30 if (this.toks.type === tt.dot &&
31 this.input.substr(this.toks.end, 1) === "." &&
32 this.options.ecmaVersion >= 6) {
33 this.toks.end++
34 this.toks.type = tt.ellipsis
35 }
36 return new Token(this.toks)
37 } catch(e) {
38 if (!(e instanceof SyntaxError)) throw e
39
40 // Try to skip some text, based on the error message, and then continue
41 let msg = e.message, pos = e.raisedAt, replace = true
42 if (/unterminated/i.test(msg)) {
43 pos = this.lineEnd(e.pos + 1)
44 if (/string/.test(msg)) {
45 replace = {start: e.pos, end: pos, type: tt.string, value: this.input.slice(e.pos + 1, pos)}
46 } else if (/regular expr/i.test(msg)) {
47 let re = this.input.slice(e.pos, pos)
48 try { re = new RegExp(re) } catch(e) {}
49 replace = {start: e.pos, end: pos, type: tt.regexp, value: re}
50 } else if (/template/.test(msg)) {
51 replace = {start: e.pos, end: pos,
52 type: tt.template,
53 value: this.input.slice(e.pos, pos)}
54 } else {
55 replace = false
56 }
57 } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {
58 while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos
59 } else if (/character escape|expected hexadecimal/i.test(msg)) {
60 while (pos < this.input.length) {
61 let ch = this.input.charCodeAt(pos++)
62 if (ch === 34 || ch === 39 || isNewLine(ch)) break
63 }
64 } else if (/unexpected character/i.test(msg)) {
65 pos++
66 replace = false
67 } else if (/regular expression/i.test(msg)) {
68 replace = true
69 } else {
70 throw e
71 }
72 this.resetTo(pos)
73 if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"}
74 if (replace) {
75 if (this.options.locations)
76 replace.loc = new SourceLocation(
77 this.toks,
78 getLineInfo(this.input, replace.start),
79 getLineInfo(this.input, replace.end))
80 return replace
81 }
82 }
83 }
84 }
85
86 lp.resetTo = function(pos) {
87 this.toks.pos = pos
88 let ch = this.input.charAt(pos - 1)
89 this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) ||
90 /[enwfd]/.test(ch) &&
91 /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos))
92
93 if (this.options.locations) {
94 this.toks.curLine = 1
95 this.toks.lineStart = lineBreakG.lastIndex = 0
96 let match
97 while ((match = lineBreakG.exec(this.input)) && match.index < pos) {
98 ++this.toks.curLine
99 this.toks.lineStart = match.index + match[0].length
100 }
101 }
102 }
103
104 lp.lookAhead = function(n) {
105 while (n > this.ahead.length)
106 this.ahead.push(this.readToken())
107 return this.ahead[n - 1]
108 }
1 import {types as tt} from "./tokentype"
2 import {Parser} from "./state"
3 import {has} from "./util"
4
5 const pp = Parser.prototype
6
7 // Convert existing expression atom to assignable pattern
8 // if possible.
9
10 pp.toAssignable = function(node, isBinding) {
11 if (this.options.ecmaVersion >= 6 && node) {
12 switch (node.type) {
13 case "Identifier":
14 if (this.inAsync && node.name === "await")
15 this.raise(node.start, "Can not use 'await' as identifier inside an async function")
16 break
17
18 case "ObjectPattern":
19 case "ArrayPattern":
20 break
21
22 case "ObjectExpression":
23 node.type = "ObjectPattern"
24 for (let i = 0; i < node.properties.length; i++) {
25 let prop = node.properties[i]
26 if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter")
27 this.toAssignable(prop.value, isBinding)
28 }
29 break
30
31 case "ArrayExpression":
32 node.type = "ArrayPattern"
33 this.toAssignableList(node.elements, isBinding)
34 break
35
36 case "AssignmentExpression":
37 if (node.operator === "=") {
38 node.type = "AssignmentPattern"
39 delete node.operator
40 this.toAssignable(node.left, isBinding)
41 // falls through to AssignmentPattern
42 } else {
43 this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
44 break
45 }
46
47 case "AssignmentPattern":
48 break
49
50 case "ParenthesizedExpression":
51 node.expression = this.toAssignable(node.expression, isBinding)
52 break
53
54 case "MemberExpression":
55 if (!isBinding) break
56
57 default:
58 this.raise(node.start, "Assigning to rvalue")
59 }
60 }
61 return node
62 }
63
64 // Convert list of expression atoms to binding list.
65
66 pp.toAssignableList = function(exprList, isBinding) {
67 let end = exprList.length
68 if (end) {
69 let last = exprList[end - 1]
70 if (last && last.type == "RestElement") {
71 --end
72 } else if (last && last.type == "SpreadElement") {
73 last.type = "RestElement"
74 let arg = last.argument
75 this.toAssignable(arg, isBinding)
76 if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
77 this.unexpected(arg.start)
78 --end
79 }
80
81 if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
82 this.unexpected(last.argument.start)
83 }
84 for (let i = 0; i < end; i++) {
85 let elt = exprList[i]
86 if (elt) this.toAssignable(elt, isBinding)
87 }
88 return exprList
89 }
90
91 // Parses spread element.
92
93 pp.parseSpread = function(refDestructuringErrors) {
94 let node = this.startNode()
95 this.next()
96 node.argument = this.parseMaybeAssign(false, refDestructuringErrors)
97 return this.finishNode(node, "SpreadElement")
98 }
99
100 pp.parseRest = function(allowNonIdent) {
101 let node = this.startNode()
102 this.next()
103
104 // RestElement inside of a function parameter must be an identifier
105 if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected()
106 else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected()
107
108 return this.finishNode(node, "RestElement")
109 }
110
111 // Parses lvalue (assignable) atom.
112
113 pp.parseBindingAtom = function() {
114 if (this.options.ecmaVersion < 6) return this.parseIdent()
115 switch (this.type) {
116 case tt.name:
117 return this.parseIdent()
118
119 case tt.bracketL:
120 let node = this.startNode()
121 this.next()
122 node.elements = this.parseBindingList(tt.bracketR, true, true)
123 return this.finishNode(node, "ArrayPattern")
124
125 case tt.braceL:
126 return this.parseObj(true)
127
128 default:
129 this.unexpected()
130 }
131 }
132
133 pp.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) {
134 let elts = [], first = true
135 while (!this.eat(close)) {
136 if (first) first = false
137 else this.expect(tt.comma)
138 if (allowEmpty && this.type === tt.comma) {
139 elts.push(null)
140 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
141 break
142 } else if (this.type === tt.ellipsis) {
143 let rest = this.parseRest(allowNonIdent)
144 this.parseBindingListItem(rest)
145 elts.push(rest)
146 if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element")
147 this.expect(close)
148 break
149 } else {
150 let elem = this.parseMaybeDefault(this.start, this.startLoc)
151 this.parseBindingListItem(elem)
152 elts.push(elem)
153 }
154 }
155 return elts
156 }
157
158 pp.parseBindingListItem = function(param) {
159 return param
160 }
161
162 // Parses assignment pattern around given atom if possible.
163
164 pp.parseMaybeDefault = function(startPos, startLoc, left) {
165 left = left || this.parseBindingAtom()
166 if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left
167 let node = this.startNodeAt(startPos, startLoc)
168 node.left = left
169 node.right = this.parseMaybeAssign()
170 return this.finishNode(node, "AssignmentPattern")
171 }
172
173 // Verify that a node is an lval — something that can be assigned
174 // to.
175
176 pp.checkLVal = function(expr, isBinding, checkClashes) {
177 switch (expr.type) {
178 case "Identifier":
179 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
180 this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode")
181 if (checkClashes) {
182 if (has(checkClashes, expr.name))
183 this.raiseRecoverable(expr.start, "Argument name clash")
184 checkClashes[expr.name] = true
185 }
186 break
187
188 case "MemberExpression":
189 if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression")
190 break
191
192 case "ObjectPattern":
193 for (let i = 0; i < expr.properties.length; i++)
194 this.checkLVal(expr.properties[i].value, isBinding, checkClashes)
195 break
196
197 case "ArrayPattern":
198 for (let i = 0; i < expr.elements.length; i++) {
199 let elem = expr.elements[i]
200 if (elem) this.checkLVal(elem, isBinding, checkClashes)
201 }
202 break
203
204 case "AssignmentPattern":
205 this.checkLVal(expr.left, isBinding, checkClashes)
206 break
207
208 case "RestElement":
209 this.checkLVal(expr.argument, isBinding, checkClashes)
210 break
211
212 case "ParenthesizedExpression":
213 this.checkLVal(expr.expression, isBinding, checkClashes)
214 break
215
216 default:
217 this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
218 }
219 }
1 import {Parser} from "./state"
2 import {SourceLocation} from "./locutil"
3
4 export class Node {
5 constructor(parser, pos, loc) {
6 this.type = ""
7 this.start = pos
8 this.end = 0
9 if (parser.options.locations)
10 this.loc = new SourceLocation(parser, loc)
11 if (parser.options.directSourceFile)
12 this.sourceFile = parser.options.directSourceFile
13 if (parser.options.ranges)
14 this.range = [pos, 0]
15 }
16 }
17
18 // Start an AST node, attaching a start offset.
19
20 const pp = Parser.prototype
21
22 pp.startNode = function() {
23 return new Node(this, this.start, this.startLoc)
24 }
25
26 pp.startNodeAt = function(pos, loc) {
27 return new Node(this, pos, loc)
28 }
29
30 // Finish an AST node, adding `type` and `end` properties.
31
32 function finishNodeAt(node, type, pos, loc) {
33 node.type = type
34 node.end = pos
35 if (this.options.locations)
36 node.loc.end = loc
37 if (this.options.ranges)
38 node.range[1] = pos
39 return node
40 }
41
42 pp.finishNode = function(node, type) {
43 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
44 }
45
46 // Finish node at given position
47
48 pp.finishNodeAt = function(node, type, pos, loc) {
49 return finishNodeAt.call(this, node, type, pos, loc)
50 }
1 import {has, isArray} from "./util"
2 import {SourceLocation} from "./locutil"
3
4 // A second optional argument can be given to further configure
5 // the parser process. These options are recognized:
6
7 export const defaultOptions = {
8 // `ecmaVersion` indicates the ECMAScript version to parse. Must
9 // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support
10 // for strict mode, the set of reserved words, and support for
11 // new syntax features. The default is 7.
12 ecmaVersion: 7,
13 // `sourceType` indicates the mode the code should be parsed in.
14 // Can be either `"script"` or `"module"`. This influences global
15 // strict mode and parsing of `import` and `export` declarations.
16 sourceType: "script",
17 // `onInsertedSemicolon` can be a callback that will be called
18 // when a semicolon is automatically inserted. It will be passed
19 // th position of the comma as an offset, and if `locations` is
20 // enabled, it is given the location as a `{line, column}` object
21 // as second argument.
22 onInsertedSemicolon: null,
23 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
24 // trailing commas.
25 onTrailingComma: null,
26 // By default, reserved words are only enforced if ecmaVersion >= 5.
27 // Set `allowReserved` to a boolean value to explicitly turn this on
28 // an off. When this option has the value "never", reserved words
29 // and keywords can also not be used as property names.
30 allowReserved: null,
31 // When enabled, a return at the top level is not considered an
32 // error.
33 allowReturnOutsideFunction: false,
34 // When enabled, import/export statements are not constrained to
35 // appearing at the top of the program.
36 allowImportExportEverywhere: false,
37 // When enabled, hashbang directive in the beginning of file
38 // is allowed and treated as a line comment.
39 allowHashBang: false,
40 // When `locations` is on, `loc` properties holding objects with
41 // `start` and `end` properties in `{line, column}` form (with
42 // line being 1-based and column 0-based) will be attached to the
43 // nodes.
44 locations: false,
45 // A function can be passed as `onToken` option, which will
46 // cause Acorn to call that function with object in the same
47 // format as tokens returned from `tokenizer().getToken()`. Note
48 // that you are not allowed to call the parser from the
49 // callback—that will corrupt its internal state.
50 onToken: null,
51 // A function can be passed as `onComment` option, which will
52 // cause Acorn to call that function with `(block, text, start,
53 // end)` parameters whenever a comment is skipped. `block` is a
54 // boolean indicating whether this is a block (`/* */`) comment,
55 // `text` is the content of the comment, and `start` and `end` are
56 // character offsets that denote the start and end of the comment.
57 // When the `locations` option is on, two more parameters are
58 // passed, the full `{line, column}` locations of the start and
59 // end of the comments. Note that you are not allowed to call the
60 // parser from the callback—that will corrupt its internal state.
61 onComment: null,
62 // Nodes have their start and end characters offsets recorded in
63 // `start` and `end` properties (directly on the node, rather than
64 // the `loc` object, which holds line/column data. To also add a
65 // [semi-standardized][range] `range` property holding a `[start,
66 // end]` array with the same numbers, set the `ranges` option to
67 // `true`.
68 //
69 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
70 ranges: false,
71 // It is possible to parse multiple files into a single AST by
72 // passing the tree produced by parsing the first file as
73 // `program` option in subsequent parses. This will add the
74 // toplevel forms of the parsed file to the `Program` (top) node
75 // of an existing parse tree.
76 program: null,
77 // When `locations` is on, you can pass this to record the source
78 // file in every node's `loc` object.
79 sourceFile: null,
80 // This value, if given, is stored in every node, whether
81 // `locations` is on or off.
82 directSourceFile: null,
83 // When enabled, parenthesized expressions are represented by
84 // (non-standard) ParenthesizedExpression nodes
85 preserveParens: false,
86 plugins: {}
87 }
88
89 // Interpret and default an options object
90
91 export function getOptions(opts) {
92 let options = {}
93
94 for (let opt in defaultOptions)
95 options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]
96
97 if (options.ecmaVersion >= 2015)
98 options.ecmaVersion -= 2009
99
100 if (options.allowReserved == null)
101 options.allowReserved = options.ecmaVersion < 5
102
103 if (isArray(options.onToken)) {
104 let tokens = options.onToken
105 options.onToken = (token) => tokens.push(token)
106 }
107 if (isArray(options.onComment))
108 options.onComment = pushComment(options, options.onComment)
109
110 return options
111 }
112
113 function pushComment(options, array) {
114 return function (block, text, start, end, startLoc, endLoc) {
115 let comment = {
116 type: block ? 'Block' : 'Line',
117 value: text,
118 start: start,
119 end: end
120 }
121 if (options.locations)
122 comment.loc = new SourceLocation(this, startLoc, endLoc)
123 if (options.ranges)
124 comment.range = [start, end]
125 array.push(comment)
126 }
127 }
128
1 import {types as tt} from "./tokentype"
2 import {Parser} from "./state"
3 import {lineBreak, skipWhiteSpace} from "./whitespace"
4
5 const pp = Parser.prototype
6
7 // ## Parser utilities
8
9 const literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/
10 pp.strictDirective = function(start) {
11 for (;;) {
12 skipWhiteSpace.lastIndex = start
13 start += skipWhiteSpace.exec(this.input)[0].length
14 let match = literal.exec(this.input.slice(start))
15 if (!match) return false
16 if ((match[1] || match[2]) == "use strict") return true
17 start += match[0].length
18 }
19 }
20
21 // Predicate that tests whether the next token is of the given
22 // type, and if yes, consumes it as a side effect.
23
24 pp.eat = function(type) {
25 if (this.type === type) {
26 this.next()
27 return true
28 } else {
29 return false
30 }
31 }
32
33 // Tests whether parsed token is a contextual keyword.
34
35 pp.isContextual = function(name) {
36 return this.type === tt.name && this.value === name
37 }
38
39 // Consumes contextual keyword if possible.
40
41 pp.eatContextual = function(name) {
42 return this.value === name && this.eat(tt.name)
43 }
44
45 // Asserts that following token is given contextual keyword.
46
47 pp.expectContextual = function(name) {
48 if (!this.eatContextual(name)) this.unexpected()
49 }
50
51 // Test whether a semicolon can be inserted at the current position.
52
53 pp.canInsertSemicolon = function() {
54 return this.type === tt.eof ||
55 this.type === tt.braceR ||
56 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
57 }
58
59 pp.insertSemicolon = function() {
60 if (this.canInsertSemicolon()) {
61 if (this.options.onInsertedSemicolon)
62 this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc)
63 return true
64 }
65 }
66
67 // Consume a semicolon, or, failing that, see if we are allowed to
68 // pretend that there is a semicolon at this position.
69
70 pp.semicolon = function() {
71 if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected()
72 }
73
74 pp.afterTrailingComma = function(tokType, notNext) {
75 if (this.type == tokType) {
76 if (this.options.onTrailingComma)
77 this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc)
78 if (!notNext)
79 this.next()
80 return true
81 }
82 }
83
84 // Expect a token of a given type. If found, consume it, otherwise,
85 // raise an unexpected token error.
86
87 pp.expect = function(type) {
88 this.eat(type) || this.unexpected()
89 }
90
91 // Raise an unexpected token error.
92
93 pp.unexpected = function(pos) {
94 this.raise(pos != null ? pos : this.start, "Unexpected token")
95 }
96
97 export class DestructuringErrors {
98 constructor() {
99 this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1
100 }
101 }
102
103 pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
104 if (!refDestructuringErrors) return
105 if (refDestructuringErrors.trailingComma > -1)
106 this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element")
107 let parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind
108 if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern")
109 }
110
111 pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
112 let pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1
113 if (!andThrow) return pos >= 0
114 if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns")
115 }
116
117 pp.checkYieldAwaitInDefaultParams = function() {
118 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
119 this.raise(this.yieldPos, "Yield expression cannot be a default value")
120 if (this.awaitPos)
121 this.raise(this.awaitPos, "Await expression cannot be a default value")
122 }
123
124 pp.isSimpleAssignTarget = function(expr) {
125 if (expr.type === "ParenthesizedExpression")
126 return this.isSimpleAssignTarget(expr.expression)
127 return expr.type === "Identifier" || expr.type === "MemberExpression"
128 }
1 import {reservedWords, keywords} from "./identifier"
2 import {types as tt} from "./tokentype"
3 import {lineBreak} from "./whitespace"
4 import {getOptions} from "./options"
5
6 // Registered plugins
7 export const plugins = {}
8
9 function keywordRegexp(words) {
10 return new RegExp("^(" + words.replace(/ /g, "|") + ")$")
11 }
12
13 export class Parser {
14 constructor(options, input, startPos) {
15 this.options = options = getOptions(options)
16 this.sourceFile = options.sourceFile
17 this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5])
18 let reserved = ""
19 if (!options.allowReserved) {
20 for (let v = options.ecmaVersion;; v--)
21 if (reserved = reservedWords[v]) break
22 if (options.sourceType == "module") reserved += " await"
23 }
24 this.reservedWords = keywordRegexp(reserved)
25 let reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict
26 this.reservedWordsStrict = keywordRegexp(reservedStrict)
27 this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind)
28 this.input = String(input)
29
30 // Used to signal to callers of `readWord1` whether the word
31 // contained any escape sequences. This is needed because words with
32 // escape sequences must not be interpreted as keywords.
33 this.containsEsc = false
34
35 // Load plugins
36 this.loadPlugins(options.plugins)
37
38 // Set up token state
39
40 // The current position of the tokenizer in the input.
41 if (startPos) {
42 this.pos = startPos
43 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1
44 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length
45 } else {
46 this.pos = this.lineStart = 0
47 this.curLine = 1
48 }
49
50 // Properties of the current token:
51 // Its type
52 this.type = tt.eof
53 // For tokens that include more information than their type, the value
54 this.value = null
55 // Its start and end offset
56 this.start = this.end = this.pos
57 // And, if locations are used, the {line, column} object
58 // corresponding to those offsets
59 this.startLoc = this.endLoc = this.curPosition()
60
61 // Position information for the previous token
62 this.lastTokEndLoc = this.lastTokStartLoc = null
63 this.lastTokStart = this.lastTokEnd = this.pos
64
65 // The context stack is used to superficially track syntactic
66 // context to predict whether a regular expression is allowed in a
67 // given position.
68 this.context = this.initialContext()
69 this.exprAllowed = true
70
71 // Figure out if it's a module code.
72 this.inModule = options.sourceType === "module"
73 this.strict = this.inModule || this.strictDirective(this.pos)
74
75 // Used to signify the start of a potential arrow function
76 this.potentialArrowAt = -1
77
78 // Flags to track whether we are in a function, a generator, an async function.
79 this.inFunction = this.inGenerator = this.inAsync = false
80 // Positions to delayed-check that yield/await does not exist in default parameters.
81 this.yieldPos = this.awaitPos = 0
82 // Labels in scope.
83 this.labels = []
84
85 // If enabled, skip leading hashbang line.
86 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!')
87 this.skipLineComment(2)
88 }
89
90 // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
91 isKeyword(word) { return this.keywords.test(word) }
92 isReservedWord(word) { return this.reservedWords.test(word) }
93
94 extend(name, f) {
95 this[name] = f(this[name])
96 }
97
98 loadPlugins(pluginConfigs) {
99 for (let name in pluginConfigs) {
100 let plugin = plugins[name]
101 if (!plugin) throw new Error("Plugin '" + name + "' not found")
102 plugin(this, pluginConfigs[name])
103 }
104 }
105
106 parse() {
107 let node = this.options.program || this.startNode()
108 this.nextToken()
109 return this.parseTopLevel(node)
110 }
111 }
1 // The algorithm used to determine whether a regexp can appear at a
2 // given point in the program is loosely based on sweet.js' approach.
3 // See https://github.com/mozilla/sweet.js/wiki/design
4
5 import {Parser} from "./state"
6 import {types as tt} from "./tokentype"
7 import {lineBreak} from "./whitespace"
8
9 export class TokContext {
10 constructor(token, isExpr, preserveSpace, override) {
11 this.token = token
12 this.isExpr = !!isExpr
13 this.preserveSpace = !!preserveSpace
14 this.override = override
15 }
16 }
17
18 export const types = {
19 b_stat: new TokContext("{", false),
20 b_expr: new TokContext("{", true),
21 b_tmpl: new TokContext("${", true),
22 p_stat: new TokContext("(", false),
23 p_expr: new TokContext("(", true),
24 q_tmpl: new TokContext("`", true, true, p => p.readTmplToken()),
25 f_expr: new TokContext("function", true)
26 }
27
28 const pp = Parser.prototype
29
30 pp.initialContext = function() {
31 return [types.b_stat]
32 }
33
34 pp.braceIsBlock = function(prevType) {
35 if (prevType === tt.colon) {
36 let parent = this.curContext()
37 if (parent === types.b_stat || parent === types.b_expr)
38 return !parent.isExpr
39 }
40 if (prevType === tt._return)
41 return lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
42 if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR)
43 return true
44 if (prevType == tt.braceL)
45 return this.curContext() === types.b_stat
46 return !this.exprAllowed
47 }
48
49 pp.updateContext = function(prevType) {
50 let update, type = this.type
51 if (type.keyword && prevType == tt.dot)
52 this.exprAllowed = false
53 else if (update = type.updateContext)
54 update.call(this, prevType)
55 else
56 this.exprAllowed = type.beforeExpr
57 }
58
59 // Token-specific context update code
60
61 tt.parenR.updateContext = tt.braceR.updateContext = function() {
62 if (this.context.length == 1) {
63 this.exprAllowed = true
64 return
65 }
66 let out = this.context.pop()
67 if (out === types.b_stat && this.curContext() === types.f_expr) {
68 this.context.pop()
69 this.exprAllowed = false
70 } else if (out === types.b_tmpl) {
71 this.exprAllowed = true
72 } else {
73 this.exprAllowed = !out.isExpr
74 }
75 }
76
77 tt.braceL.updateContext = function(prevType) {
78 this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr)
79 this.exprAllowed = true
80 }
81
82 tt.dollarBraceL.updateContext = function() {
83 this.context.push(types.b_tmpl)
84 this.exprAllowed = true
85 }
86
87 tt.parenL.updateContext = function(prevType) {
88 let statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while
89 this.context.push(statementParens ? types.p_stat : types.p_expr)
90 this.exprAllowed = true
91 }
92
93 tt.incDec.updateContext = function() {
94 // tokExprAllowed stays unchanged
95 }
96
97 tt._function.updateContext = function(prevType) {
98 if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else &&
99 !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat))
100 this.context.push(types.f_expr)
101 this.exprAllowed = false
102 }
103
104 tt.backQuote.updateContext = function() {
105 if (this.curContext() === types.q_tmpl)
106 this.context.pop()
107 else
108 this.context.push(types.q_tmpl)
109 this.exprAllowed = false
110 }
1 // ## Token types
2
3 // The assignment of fine-grained, information-carrying type objects
4 // allows the tokenizer to store the information it has about a
5 // token in a way that is very cheap for the parser to look up.
6
7 // All token type variables start with an underscore, to make them
8 // easy to recognize.
9
10 // The `beforeExpr` property is used to disambiguate between regular
11 // expressions and divisions. It is set on all token types that can
12 // be followed by an expression (thus, a slash after them would be a
13 // regular expression).
14 //
15 // The `startsExpr` property is used to check if the token ends a
16 // `yield` expression. It is set on all token types that either can
17 // directly start an expression (like a quotation mark) or can
18 // continue an expression (like the body of a string).
19 //
20 // `isLoop` marks a keyword as starting a loop, which is important
21 // to know when parsing a label, in order to allow or disallow
22 // continue jumps to that label.
23
24 export class TokenType {
25 constructor(label, conf = {}) {
26 this.label = label
27 this.keyword = conf.keyword
28 this.beforeExpr = !!conf.beforeExpr
29 this.startsExpr = !!conf.startsExpr
30 this.isLoop = !!conf.isLoop
31 this.isAssign = !!conf.isAssign
32 this.prefix = !!conf.prefix
33 this.postfix = !!conf.postfix
34 this.binop = conf.binop || null
35 this.updateContext = null
36 }
37 }
38
39 function binop(name, prec) {
40 return new TokenType(name, {beforeExpr: true, binop: prec})
41 }
42 const beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}
43
44 // Map keyword names to token types.
45
46 export const keywords = {}
47
48 // Succinct definitions of keyword token types
49 function kw(name, options = {}) {
50 options.keyword = name
51 return keywords[name] = new TokenType(name, options)
52 }
53
54 export const types = {
55 num: new TokenType("num", startsExpr),
56 regexp: new TokenType("regexp", startsExpr),
57 string: new TokenType("string", startsExpr),
58 name: new TokenType("name", startsExpr),
59 eof: new TokenType("eof"),
60
61 // Punctuation token types.
62 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
63 bracketR: new TokenType("]"),
64 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
65 braceR: new TokenType("}"),
66 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
67 parenR: new TokenType(")"),
68 comma: new TokenType(",", beforeExpr),
69 semi: new TokenType(";", beforeExpr),
70 colon: new TokenType(":", beforeExpr),
71 dot: new TokenType("."),
72 question: new TokenType("?", beforeExpr),
73 arrow: new TokenType("=>", beforeExpr),
74 template: new TokenType("template"),
75 ellipsis: new TokenType("...", beforeExpr),
76 backQuote: new TokenType("`", startsExpr),
77 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
78
79 // Operators. These carry several kinds of properties to help the
80 // parser use them properly (the presence of these properties is
81 // what categorizes them as operators).
82 //
83 // `binop`, when present, specifies that this operator is a binary
84 // operator, and will refer to its precedence.
85 //
86 // `prefix` and `postfix` mark the operator as a prefix or postfix
87 // unary operator.
88 //
89 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
90 // binary operators with a very low precedence, that should result
91 // in AssignmentExpression nodes.
92
93 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
94 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
95 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
96 prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
97 logicalOR: binop("||", 1),
98 logicalAND: binop("&&", 2),
99 bitwiseOR: binop("|", 3),
100 bitwiseXOR: binop("^", 4),
101 bitwiseAND: binop("&", 5),
102 equality: binop("==/!=", 6),
103 relational: binop("</>", 7),
104 bitShift: binop("<</>>", 8),
105 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
106 modulo: binop("%", 10),
107 star: binop("*", 10),
108 slash: binop("/", 10),
109 starstar: new TokenType("**", {beforeExpr: true}),
110
111 // Keyword token types.
112 _break: kw("break"),
113 _case: kw("case", beforeExpr),
114 _catch: kw("catch"),
115 _continue: kw("continue"),
116 _debugger: kw("debugger"),
117 _default: kw("default", beforeExpr),
118 _do: kw("do", {isLoop: true, beforeExpr: true}),
119 _else: kw("else", beforeExpr),
120 _finally: kw("finally"),
121 _for: kw("for", {isLoop: true}),
122 _function: kw("function", startsExpr),
123 _if: kw("if"),
124 _return: kw("return", beforeExpr),
125 _switch: kw("switch"),
126 _throw: kw("throw", beforeExpr),
127 _try: kw("try"),
128 _var: kw("var"),
129 _const: kw("const"),
130 _while: kw("while", {isLoop: true}),
131 _with: kw("with"),
132 _new: kw("new", {beforeExpr: true, startsExpr: true}),
133 _this: kw("this", startsExpr),
134 _super: kw("super", startsExpr),
135 _class: kw("class"),
136 _extends: kw("extends", beforeExpr),
137 _export: kw("export"),
138 _import: kw("import"),
139 _null: kw("null", startsExpr),
140 _true: kw("true", startsExpr),
141 _false: kw("false", startsExpr),
142 _in: kw("in", {beforeExpr: true, binop: 7}),
143 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
144 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
145 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
146 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
147 }
1 export function isArray(obj) {
2 return Object.prototype.toString.call(obj) === "[object Array]"
3 }
4
5 // Checks if an object has a property.
6
7 export function has(obj, propName) {
8 return Object.prototype.hasOwnProperty.call(obj, propName)
9 }
1 // Matches a whole line break (where CRLF is considered a single
2 // line break). Used to count lines.
3
4 export const lineBreak = /\r\n?|\n|\u2028|\u2029/
5 export const lineBreakG = new RegExp(lineBreak.source, "g")
6
7 export function isNewLine(code) {
8 return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
9 }
10
11 export const nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/
12
13 export const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g
1 {
2 "_from": "acorn-dynamic-import@^2.0.0",
3 "_id": "acorn-dynamic-import@2.0.2",
4 "_inBundle": false,
5 "_integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
6 "_location": "/acorn-dynamic-import",
7 "_phantomChildren": {},
8 "_requested": {
9 "type": "range",
10 "registry": true,
11 "raw": "acorn-dynamic-import@^2.0.0",
12 "name": "acorn-dynamic-import",
13 "escapedName": "acorn-dynamic-import",
14 "rawSpec": "^2.0.0",
15 "saveSpec": null,
16 "fetchSpec": "^2.0.0"
17 },
18 "_requiredBy": [
19 "/webpack"
20 ],
21 "_resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
22 "_shasum": "c752bd210bef679501b6c6cb7fc84f8f47158cc4",
23 "_spec": "acorn-dynamic-import@^2.0.0",
24 "_where": "/Users/zhanghao/brcode/br-client/node_modules/webpack",
25 "author": {
26 "name": "Jordan Gensler",
27 "email": "jordangens@gmail.com"
28 },
29 "bugs": {
30 "url": "https://github.com/kesne/acorn-dynamic-import/issues"
31 },
32 "bundleDependencies": false,
33 "dependencies": {
34 "acorn": "^4.0.3"
35 },
36 "deprecated": false,
37 "description": "Support dynamic imports in acorn",
38 "devDependencies": {
39 "babel-cli": "^6.18.0",
40 "babel-eslint": "^7.1.1",
41 "babel-preset-airbnb": "^2.1.1",
42 "babel-register": "^6.18.0",
43 "chai": "^3.0.0",
44 "eslint": "^3.10.2",
45 "eslint-config-airbnb-base": "^10.0.1",
46 "eslint-plugin-import": "^2.2.0",
47 "in-publish": "^2.0.0",
48 "mocha": "^2.2.5",
49 "rimraf": "^2.5.4",
50 "safe-publish-latest": "^1.1.1"
51 },
52 "homepage": "https://github.com/kesne/acorn-dynamic-import",
53 "license": "MIT",
54 "main": "lib/index.js",
55 "name": "acorn-dynamic-import",
56 "repository": {
57 "type": "git",
58 "url": "git+https://github.com/kesne/acorn-dynamic-import.git"
59 },
60 "scripts": {
61 "build": "babel src --out-dir lib",
62 "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)",
63 "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",
64 "lint": "eslint .",
65 "postversion": "git commit package.json CHANGELOG.md -m \"v$npm_package_version\" && npm run tag && git push && git push --tags",
66 "prepublish": "in-publish && safe-publish-latest && npm run build || not-in-publish",
67 "preversion": "npm run test && npm run check-changelog && npm run check-only-changelog-changed",
68 "tag": "git tag v$npm_package_version",
69 "test": "npm run lint && npm run tests-only",
70 "tests-only": "mocha",
71 "version:major": "npm --no-git-tag-version version major",
72 "version:minor": "npm --no-git-tag-version version minor",
73 "version:patch": "npm --no-git-tag-version version patch"
74 },
75 "version": "2.0.2"
76 }
1 import * as acorn from 'acorn';
2 import inject from './inject';
3
4 export default inject(acorn);
1 /* eslint-disable no-underscore-dangle */
2
3 export default function injectDynamicImport(acorn) {
4 const tt = acorn.tokTypes;
5
6 // NOTE: This allows `yield import()` to parse correctly.
7 tt._import.startsExpr = true;
8
9 function parseDynamicImport() {
10 const node = this.startNode();
11 this.next();
12 if (this.type !== tt.parenL) {
13 this.unexpected();
14 }
15 return this.finishNode(node, 'Import');
16 }
17
18 function peekNext() {
19 return this.input[this.pos];
20 }
21
22 // eslint-disable-next-line no-param-reassign
23 acorn.plugins.dynamicImport = function dynamicImportPlugin(instance) {
24 instance.extend('parseStatement', nextMethod => (
25 function parseStatement(...args) {
26 const node = this.startNode();
27 if (this.type === tt._import) {
28 const nextToken = peekNext.call(this);
29 if (nextToken === tt.parenL.label) {
30 const expr = this.parseExpression();
31 return this.parseExpressionStatement(node, expr);
32 }
33 }
34
35 return nextMethod.apply(this, args);
36 }
37 ));
38
39 instance.extend('parseExprAtom', nextMethod => (
40 function parseExprAtom(refDestructuringErrors) {
41 if (this.type === tt._import) {
42 return parseDynamicImport.call(this);
43 }
44 return nextMethod.call(this, refDestructuringErrors);
45 }
46 ));
47 };
48
49 return acorn;
50 }
1 List of Acorn contributors. Updated before every release.
2
3 Adrian Heine
4 Adrian Rakovsky
5 Alistair Braidwood
6 Amila Welihinda
7 Andres Suarez
8 Angelo
9 Aparajita Fishman
10 Arian Stolwijk
11 Artem Govorov
12 Boopesh Mahendran
13 Bradley Heinz
14 Brandon Mills
15 Charles Hughes
16 Charmander
17 Chris McKnight
18 Conrad Irwin
19 Daniel Tschinder
20 David Bonnet
21 Domenico Matteo
22 ehmicky
23 Eugene Obrezkov
24 Felix Maier
25 Forbes Lindesay
26 Gilad Peleg
27 impinball
28 Ingvar Stepanyan
29 Jackson Ray Hamilton
30 Jesse McCarthy
31 Jiaxing Wang
32 Joel Kemp
33 Johannes Herr
34 John-David Dalton
35 Jordan Klassen
36 Jürg Lehni
37 Kai Cataldo
38 keeyipchan
39 Keheliya Gallaba
40 Kevin Irish
41 Kevin Kwok
42 krator
43 laosb
44 luckyzeng
45 Marek
46 Marijn Haverbeke
47 Martin Carlberg
48 Mat Garcia
49 Mathias Bynens
50 Mathieu 'p01' Henri
51 Matthew Bastien
52 Max Schaefer
53 Max Zerzouri
54 Mihai Bazon
55 Mike Rennie
56 naoh
57 Nicholas C. Zakas
58 Nick Fitzgerald
59 Olivier Thomann
60 Oskar Schöldström
61 Paul Harper
62 Peter Rust
63 PlNG
64 Prayag Verma
65 ReadmeCritic
66 r-e-d
67 Renée Kooi
68 Richard Gibson
69 Rich Harris
70 Sebastian McKenzie
71 Shahar Soel
72 Sheel Bedi
73 Simen Bekkhus
74 Teddy Katz
75 Timothy Gu
76 Toru Nagashima
77 Victor Homyakov
78 Wexpo Lyu
79 zsjforcn
1 Copyright (C) 2012-2018 by various contributors (see AUTHORS)
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is
8 furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.