Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80559 views
1
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
2
3
4
// The main exported interface (under `self.acorn` when in the
5
// browser) is a `parse` function that takes a code string and
6
// returns an abstract syntax tree as specified by [Mozilla parser
7
// API][api].
8
//
9
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
10
11
"use strict";
12
13
exports.parse = parse;
14
15
// This function tries to parse a single expression at a given
16
// offset in a string. Useful for parsing mixed-language formats
17
// that embed JavaScript expressions.
18
19
exports.parseExpressionAt = parseExpressionAt;
20
21
// Acorn is organized as a tokenizer and a recursive-descent parser.
22
// The `tokenize` export provides an interface to the tokenizer.
23
24
exports.tokenizer = tokenizer;
25
exports.__esModule = true;
26
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
27
//
28
// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
29
// various contributors and released under an MIT license.
30
//
31
// Git repositories for Acorn are available at
32
//
33
// http://marijnhaverbeke.nl/git/acorn
34
// https://github.com/marijnh/acorn.git
35
//
36
// Please use the [github bug tracker][ghbt] to report issues.
37
//
38
// [ghbt]: https://github.com/marijnh/acorn/issues
39
//
40
// This file defines the main parser interface. The library also comes
41
// with a [error-tolerant parser][dammit] and an
42
// [abstract syntax tree walker][walk], defined in other files.
43
//
44
// [dammit]: acorn_loose.js
45
// [walk]: util/walk.js
46
47
var _state = _dereq_("./state");
48
49
var Parser = _state.Parser;
50
51
var _options = _dereq_("./options");
52
53
var getOptions = _options.getOptions;
54
55
_dereq_("./parseutil");
56
57
_dereq_("./statement");
58
59
_dereq_("./lval");
60
61
_dereq_("./expression");
62
63
exports.Parser = _state.Parser;
64
exports.plugins = _state.plugins;
65
exports.defaultOptions = _options.defaultOptions;
66
67
var _location = _dereq_("./location");
68
69
exports.SourceLocation = _location.SourceLocation;
70
exports.getLineInfo = _location.getLineInfo;
71
exports.Node = _dereq_("./node").Node;
72
73
var _tokentype = _dereq_("./tokentype");
74
75
exports.TokenType = _tokentype.TokenType;
76
exports.tokTypes = _tokentype.types;
77
78
var _tokencontext = _dereq_("./tokencontext");
79
80
exports.TokContext = _tokencontext.TokContext;
81
exports.tokContexts = _tokencontext.types;
82
83
var _identifier = _dereq_("./identifier");
84
85
exports.isIdentifierChar = _identifier.isIdentifierChar;
86
exports.isIdentifierStart = _identifier.isIdentifierStart;
87
exports.Token = _dereq_("./tokenize").Token;
88
89
var _whitespace = _dereq_("./whitespace");
90
91
exports.isNewLine = _whitespace.isNewLine;
92
exports.lineBreak = _whitespace.lineBreak;
93
exports.lineBreakG = _whitespace.lineBreakG;
94
var version = "1.2.2";exports.version = version;
95
96
function parse(input, options) {
97
var p = parser(options, input);
98
var startPos = p.pos,
99
startLoc = p.options.locations && p.curPosition();
100
p.nextToken();
101
return p.parseTopLevel(p.options.program || p.startNodeAt(startPos, startLoc));
102
}
103
104
function parseExpressionAt(input, pos, options) {
105
var p = parser(options, input, pos);
106
p.nextToken();
107
return p.parseExpression();
108
}
109
110
function tokenizer(input, options) {
111
return parser(options, input);
112
}
113
114
function parser(options, input) {
115
return new Parser(getOptions(options), String(input));
116
}
117
118
},{"./expression":6,"./identifier":7,"./location":8,"./lval":9,"./node":10,"./options":11,"./parseutil":12,"./state":13,"./statement":14,"./tokencontext":15,"./tokenize":16,"./tokentype":17,"./whitespace":19}],2:[function(_dereq_,module,exports){
119
if (typeof Object.create === 'function') {
120
// implementation from standard node.js 'util' module
121
module.exports = function inherits(ctor, superCtor) {
122
ctor.super_ = superCtor
123
ctor.prototype = Object.create(superCtor.prototype, {
124
constructor: {
125
value: ctor,
126
enumerable: false,
127
writable: true,
128
configurable: true
129
}
130
});
131
};
132
} else {
133
// old school shim for old browsers
134
module.exports = function inherits(ctor, superCtor) {
135
ctor.super_ = superCtor
136
var TempCtor = function () {}
137
TempCtor.prototype = superCtor.prototype
138
ctor.prototype = new TempCtor()
139
ctor.prototype.constructor = ctor
140
}
141
}
142
143
},{}],3:[function(_dereq_,module,exports){
144
// shim for using process in browser
145
146
var process = module.exports = {};
147
var queue = [];
148
var draining = false;
149
150
function drainQueue() {
151
if (draining) {
152
return;
153
}
154
draining = true;
155
var currentQueue;
156
var len = queue.length;
157
while(len) {
158
currentQueue = queue;
159
queue = [];
160
var i = -1;
161
while (++i < len) {
162
currentQueue[i]();
163
}
164
len = queue.length;
165
}
166
draining = false;
167
}
168
process.nextTick = function (fun) {
169
queue.push(fun);
170
if (!draining) {
171
setTimeout(drainQueue, 0);
172
}
173
};
174
175
process.title = 'browser';
176
process.browser = true;
177
process.env = {};
178
process.argv = [];
179
process.version = ''; // empty string to avoid regexp issues
180
process.versions = {};
181
182
function noop() {}
183
184
process.on = noop;
185
process.addListener = noop;
186
process.once = noop;
187
process.off = noop;
188
process.removeListener = noop;
189
process.removeAllListeners = noop;
190
process.emit = noop;
191
192
process.binding = function (name) {
193
throw new Error('process.binding is not supported');
194
};
195
196
// TODO(shtylman)
197
process.cwd = function () { return '/' };
198
process.chdir = function (dir) {
199
throw new Error('process.chdir is not supported');
200
};
201
process.umask = function() { return 0; };
202
203
},{}],4:[function(_dereq_,module,exports){
204
module.exports = function isBuffer(arg) {
205
return arg && typeof arg === 'object'
206
&& typeof arg.copy === 'function'
207
&& typeof arg.fill === 'function'
208
&& typeof arg.readUInt8 === 'function';
209
}
210
},{}],5:[function(_dereq_,module,exports){
211
(function (process,global){
212
// Copyright Joyent, Inc. and other Node contributors.
213
//
214
// Permission is hereby granted, free of charge, to any person obtaining a
215
// copy of this software and associated documentation files (the
216
// "Software"), to deal in the Software without restriction, including
217
// without limitation the rights to use, copy, modify, merge, publish,
218
// distribute, sublicense, and/or sell copies of the Software, and to permit
219
// persons to whom the Software is furnished to do so, subject to the
220
// following conditions:
221
//
222
// The above copyright notice and this permission notice shall be included
223
// in all copies or substantial portions of the Software.
224
//
225
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
226
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
227
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
228
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
229
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
230
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
231
// USE OR OTHER DEALINGS IN THE SOFTWARE.
232
233
var formatRegExp = /%[sdj%]/g;
234
exports.format = function(f) {
235
if (!isString(f)) {
236
var objects = [];
237
for (var i = 0; i < arguments.length; i++) {
238
objects.push(inspect(arguments[i]));
239
}
240
return objects.join(' ');
241
}
242
243
var i = 1;
244
var args = arguments;
245
var len = args.length;
246
var str = String(f).replace(formatRegExp, function(x) {
247
if (x === '%%') return '%';
248
if (i >= len) return x;
249
switch (x) {
250
case '%s': return String(args[i++]);
251
case '%d': return Number(args[i++]);
252
case '%j':
253
try {
254
return JSON.stringify(args[i++]);
255
} catch (_) {
256
return '[Circular]';
257
}
258
default:
259
return x;
260
}
261
});
262
for (var x = args[i]; i < len; x = args[++i]) {
263
if (isNull(x) || !isObject(x)) {
264
str += ' ' + x;
265
} else {
266
str += ' ' + inspect(x);
267
}
268
}
269
return str;
270
};
271
272
273
// Mark that a method should not be used.
274
// Returns a modified function which warns once by default.
275
// If --no-deprecation is set, then it is a no-op.
276
exports.deprecate = function(fn, msg) {
277
// Allow for deprecating things in the process of starting up.
278
if (isUndefined(global.process)) {
279
return function() {
280
return exports.deprecate(fn, msg).apply(this, arguments);
281
};
282
}
283
284
if (process.noDeprecation === true) {
285
return fn;
286
}
287
288
var warned = false;
289
function deprecated() {
290
if (!warned) {
291
if (process.throwDeprecation) {
292
throw new Error(msg);
293
} else if (process.traceDeprecation) {
294
console.trace(msg);
295
} else {
296
console.error(msg);
297
}
298
warned = true;
299
}
300
return fn.apply(this, arguments);
301
}
302
303
return deprecated;
304
};
305
306
307
var debugs = {};
308
var debugEnviron;
309
exports.debuglog = function(set) {
310
if (isUndefined(debugEnviron))
311
debugEnviron = process.env.NODE_DEBUG || '';
312
set = set.toUpperCase();
313
if (!debugs[set]) {
314
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
315
var pid = process.pid;
316
debugs[set] = function() {
317
var msg = exports.format.apply(exports, arguments);
318
console.error('%s %d: %s', set, pid, msg);
319
};
320
} else {
321
debugs[set] = function() {};
322
}
323
}
324
return debugs[set];
325
};
326
327
328
/**
329
* Echos the value of a value. Trys to print the value out
330
* in the best way possible given the different types.
331
*
332
* @param {Object} obj The object to print out.
333
* @param {Object} opts Optional options object that alters the output.
334
*/
335
/* legacy: obj, showHidden, depth, colors*/
336
function inspect(obj, opts) {
337
// default options
338
var ctx = {
339
seen: [],
340
stylize: stylizeNoColor
341
};
342
// legacy...
343
if (arguments.length >= 3) ctx.depth = arguments[2];
344
if (arguments.length >= 4) ctx.colors = arguments[3];
345
if (isBoolean(opts)) {
346
// legacy...
347
ctx.showHidden = opts;
348
} else if (opts) {
349
// got an "options" object
350
exports._extend(ctx, opts);
351
}
352
// set default options
353
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
354
if (isUndefined(ctx.depth)) ctx.depth = 2;
355
if (isUndefined(ctx.colors)) ctx.colors = false;
356
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
357
if (ctx.colors) ctx.stylize = stylizeWithColor;
358
return formatValue(ctx, obj, ctx.depth);
359
}
360
exports.inspect = inspect;
361
362
363
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
364
inspect.colors = {
365
'bold' : [1, 22],
366
'italic' : [3, 23],
367
'underline' : [4, 24],
368
'inverse' : [7, 27],
369
'white' : [37, 39],
370
'grey' : [90, 39],
371
'black' : [30, 39],
372
'blue' : [34, 39],
373
'cyan' : [36, 39],
374
'green' : [32, 39],
375
'magenta' : [35, 39],
376
'red' : [31, 39],
377
'yellow' : [33, 39]
378
};
379
380
// Don't use 'blue' not visible on cmd.exe
381
inspect.styles = {
382
'special': 'cyan',
383
'number': 'yellow',
384
'boolean': 'yellow',
385
'undefined': 'grey',
386
'null': 'bold',
387
'string': 'green',
388
'date': 'magenta',
389
// "name": intentionally not styling
390
'regexp': 'red'
391
};
392
393
394
function stylizeWithColor(str, styleType) {
395
var style = inspect.styles[styleType];
396
397
if (style) {
398
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
399
'\u001b[' + inspect.colors[style][1] + 'm';
400
} else {
401
return str;
402
}
403
}
404
405
406
function stylizeNoColor(str, styleType) {
407
return str;
408
}
409
410
411
function arrayToHash(array) {
412
var hash = {};
413
414
array.forEach(function(val, idx) {
415
hash[val] = true;
416
});
417
418
return hash;
419
}
420
421
422
function formatValue(ctx, value, recurseTimes) {
423
// Provide a hook for user-specified inspect functions.
424
// Check that value is an object with an inspect function on it
425
if (ctx.customInspect &&
426
value &&
427
isFunction(value.inspect) &&
428
// Filter out the util module, it's inspect function is special
429
value.inspect !== exports.inspect &&
430
// Also filter out any prototype objects using the circular check.
431
!(value.constructor && value.constructor.prototype === value)) {
432
var ret = value.inspect(recurseTimes, ctx);
433
if (!isString(ret)) {
434
ret = formatValue(ctx, ret, recurseTimes);
435
}
436
return ret;
437
}
438
439
// Primitive types cannot have properties
440
var primitive = formatPrimitive(ctx, value);
441
if (primitive) {
442
return primitive;
443
}
444
445
// Look up the keys of the object.
446
var keys = Object.keys(value);
447
var visibleKeys = arrayToHash(keys);
448
449
if (ctx.showHidden) {
450
keys = Object.getOwnPropertyNames(value);
451
}
452
453
// IE doesn't make error fields non-enumerable
454
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
455
if (isError(value)
456
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
457
return formatError(value);
458
}
459
460
// Some type of object without properties can be shortcutted.
461
if (keys.length === 0) {
462
if (isFunction(value)) {
463
var name = value.name ? ': ' + value.name : '';
464
return ctx.stylize('[Function' + name + ']', 'special');
465
}
466
if (isRegExp(value)) {
467
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
468
}
469
if (isDate(value)) {
470
return ctx.stylize(Date.prototype.toString.call(value), 'date');
471
}
472
if (isError(value)) {
473
return formatError(value);
474
}
475
}
476
477
var base = '', array = false, braces = ['{', '}'];
478
479
// Make Array say that they are Array
480
if (isArray(value)) {
481
array = true;
482
braces = ['[', ']'];
483
}
484
485
// Make functions say that they are functions
486
if (isFunction(value)) {
487
var n = value.name ? ': ' + value.name : '';
488
base = ' [Function' + n + ']';
489
}
490
491
// Make RegExps say that they are RegExps
492
if (isRegExp(value)) {
493
base = ' ' + RegExp.prototype.toString.call(value);
494
}
495
496
// Make dates with properties first say the date
497
if (isDate(value)) {
498
base = ' ' + Date.prototype.toUTCString.call(value);
499
}
500
501
// Make error with message first say the error
502
if (isError(value)) {
503
base = ' ' + formatError(value);
504
}
505
506
if (keys.length === 0 && (!array || value.length == 0)) {
507
return braces[0] + base + braces[1];
508
}
509
510
if (recurseTimes < 0) {
511
if (isRegExp(value)) {
512
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
513
} else {
514
return ctx.stylize('[Object]', 'special');
515
}
516
}
517
518
ctx.seen.push(value);
519
520
var output;
521
if (array) {
522
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
523
} else {
524
output = keys.map(function(key) {
525
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
526
});
527
}
528
529
ctx.seen.pop();
530
531
return reduceToSingleString(output, base, braces);
532
}
533
534
535
function formatPrimitive(ctx, value) {
536
if (isUndefined(value))
537
return ctx.stylize('undefined', 'undefined');
538
if (isString(value)) {
539
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
540
.replace(/'/g, "\\'")
541
.replace(/\\"/g, '"') + '\'';
542
return ctx.stylize(simple, 'string');
543
}
544
if (isNumber(value))
545
return ctx.stylize('' + value, 'number');
546
if (isBoolean(value))
547
return ctx.stylize('' + value, 'boolean');
548
// For some reason typeof null is "object", so special case here.
549
if (isNull(value))
550
return ctx.stylize('null', 'null');
551
}
552
553
554
function formatError(value) {
555
return '[' + Error.prototype.toString.call(value) + ']';
556
}
557
558
559
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
560
var output = [];
561
for (var i = 0, l = value.length; i < l; ++i) {
562
if (hasOwnProperty(value, String(i))) {
563
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
564
String(i), true));
565
} else {
566
output.push('');
567
}
568
}
569
keys.forEach(function(key) {
570
if (!key.match(/^\d+$/)) {
571
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
572
key, true));
573
}
574
});
575
return output;
576
}
577
578
579
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
580
var name, str, desc;
581
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
582
if (desc.get) {
583
if (desc.set) {
584
str = ctx.stylize('[Getter/Setter]', 'special');
585
} else {
586
str = ctx.stylize('[Getter]', 'special');
587
}
588
} else {
589
if (desc.set) {
590
str = ctx.stylize('[Setter]', 'special');
591
}
592
}
593
if (!hasOwnProperty(visibleKeys, key)) {
594
name = '[' + key + ']';
595
}
596
if (!str) {
597
if (ctx.seen.indexOf(desc.value) < 0) {
598
if (isNull(recurseTimes)) {
599
str = formatValue(ctx, desc.value, null);
600
} else {
601
str = formatValue(ctx, desc.value, recurseTimes - 1);
602
}
603
if (str.indexOf('\n') > -1) {
604
if (array) {
605
str = str.split('\n').map(function(line) {
606
return ' ' + line;
607
}).join('\n').substr(2);
608
} else {
609
str = '\n' + str.split('\n').map(function(line) {
610
return ' ' + line;
611
}).join('\n');
612
}
613
}
614
} else {
615
str = ctx.stylize('[Circular]', 'special');
616
}
617
}
618
if (isUndefined(name)) {
619
if (array && key.match(/^\d+$/)) {
620
return str;
621
}
622
name = JSON.stringify('' + key);
623
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
624
name = name.substr(1, name.length - 2);
625
name = ctx.stylize(name, 'name');
626
} else {
627
name = name.replace(/'/g, "\\'")
628
.replace(/\\"/g, '"')
629
.replace(/(^"|"$)/g, "'");
630
name = ctx.stylize(name, 'string');
631
}
632
}
633
634
return name + ': ' + str;
635
}
636
637
638
function reduceToSingleString(output, base, braces) {
639
var numLinesEst = 0;
640
var length = output.reduce(function(prev, cur) {
641
numLinesEst++;
642
if (cur.indexOf('\n') >= 0) numLinesEst++;
643
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
644
}, 0);
645
646
if (length > 60) {
647
return braces[0] +
648
(base === '' ? '' : base + '\n ') +
649
' ' +
650
output.join(',\n ') +
651
' ' +
652
braces[1];
653
}
654
655
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
656
}
657
658
659
// NOTE: These type checking functions intentionally don't use `instanceof`
660
// because it is fragile and can be easily faked with `Object.create()`.
661
function isArray(ar) {
662
return Array.isArray(ar);
663
}
664
exports.isArray = isArray;
665
666
function isBoolean(arg) {
667
return typeof arg === 'boolean';
668
}
669
exports.isBoolean = isBoolean;
670
671
function isNull(arg) {
672
return arg === null;
673
}
674
exports.isNull = isNull;
675
676
function isNullOrUndefined(arg) {
677
return arg == null;
678
}
679
exports.isNullOrUndefined = isNullOrUndefined;
680
681
function isNumber(arg) {
682
return typeof arg === 'number';
683
}
684
exports.isNumber = isNumber;
685
686
function isString(arg) {
687
return typeof arg === 'string';
688
}
689
exports.isString = isString;
690
691
function isSymbol(arg) {
692
return typeof arg === 'symbol';
693
}
694
exports.isSymbol = isSymbol;
695
696
function isUndefined(arg) {
697
return arg === void 0;
698
}
699
exports.isUndefined = isUndefined;
700
701
function isRegExp(re) {
702
return isObject(re) && objectToString(re) === '[object RegExp]';
703
}
704
exports.isRegExp = isRegExp;
705
706
function isObject(arg) {
707
return typeof arg === 'object' && arg !== null;
708
}
709
exports.isObject = isObject;
710
711
function isDate(d) {
712
return isObject(d) && objectToString(d) === '[object Date]';
713
}
714
exports.isDate = isDate;
715
716
function isError(e) {
717
return isObject(e) &&
718
(objectToString(e) === '[object Error]' || e instanceof Error);
719
}
720
exports.isError = isError;
721
722
function isFunction(arg) {
723
return typeof arg === 'function';
724
}
725
exports.isFunction = isFunction;
726
727
function isPrimitive(arg) {
728
return arg === null ||
729
typeof arg === 'boolean' ||
730
typeof arg === 'number' ||
731
typeof arg === 'string' ||
732
typeof arg === 'symbol' || // ES6 symbol
733
typeof arg === 'undefined';
734
}
735
exports.isPrimitive = isPrimitive;
736
737
exports.isBuffer = _dereq_('./support/isBuffer');
738
739
function objectToString(o) {
740
return Object.prototype.toString.call(o);
741
}
742
743
744
function pad(n) {
745
return n < 10 ? '0' + n.toString(10) : n.toString(10);
746
}
747
748
749
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
750
'Oct', 'Nov', 'Dec'];
751
752
// 26 Feb 16:19:34
753
function timestamp() {
754
var d = new Date();
755
var time = [pad(d.getHours()),
756
pad(d.getMinutes()),
757
pad(d.getSeconds())].join(':');
758
return [d.getDate(), months[d.getMonth()], time].join(' ');
759
}
760
761
762
// log is just a thin wrapper to console.log that prepends a timestamp
763
exports.log = function() {
764
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
765
};
766
767
768
/**
769
* Inherit the prototype methods from one constructor into another.
770
*
771
* The Function.prototype.inherits from lang.js rewritten as a standalone
772
* function (not on Function.prototype). NOTE: If this file is to be loaded
773
* during bootstrapping this function needs to be rewritten using some native
774
* functions as prototype setup using normal JavaScript does not work as
775
* expected during bootstrapping (see mirror.js in r114903).
776
*
777
* @param {function} ctor Constructor function which needs to inherit the
778
* prototype.
779
* @param {function} superCtor Constructor function to inherit prototype from.
780
*/
781
exports.inherits = _dereq_('inherits');
782
783
exports._extend = function(origin, add) {
784
// Don't do anything if add isn't an object
785
if (!add || !isObject(add)) return origin;
786
787
var keys = Object.keys(add);
788
var i = keys.length;
789
while (i--) {
790
origin[keys[i]] = add[keys[i]];
791
}
792
return origin;
793
};
794
795
function hasOwnProperty(obj, prop) {
796
return Object.prototype.hasOwnProperty.call(obj, prop);
797
}
798
799
}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
800
},{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(_dereq_,module,exports){
801
// A recursive descent parser operates by defining functions for all
802
// syntactic elements, and recursively calling those, each function
803
// advancing the input stream and returning an AST node. Precedence
804
// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
805
// instead of `(!x)[1]` is handled by the fact that the parser
806
// function that parses unary prefix operators is called first, and
807
// in turn calls the function that parses `[]` subscripts — that
808
// way, it'll receive the node for `x[1]` already parsed, and wraps
809
// *that* in the unary operator node.
810
//
811
// Acorn uses an [operator precedence parser][opp] to handle binary
812
// operator precedence, because it is much more compact than using
813
// the technique outlined above, which uses different, nesting
814
// functions to specify precedence, for all of the ten binary
815
// precedence levels that JavaScript defines.
816
//
817
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
818
819
"use strict";
820
821
var tt = _dereq_("./tokentype").types;
822
823
var Parser = _dereq_("./state").Parser;
824
825
var reservedWords = _dereq_("./identifier").reservedWords;
826
827
var has = _dereq_("./util").has;
828
829
var pp = Parser.prototype;
830
831
// Check if property name clashes with already added.
832
// Object/class getters and setters are not allowed to clash —
833
// either with each other or with an init property — and in
834
// strict mode, init properties are also not allowed to be repeated.
835
836
pp.checkPropClash = function (prop, propHash) {
837
if (this.options.ecmaVersion >= 6) return;
838
var key = prop.key,
839
name = undefined;
840
switch (key.type) {
841
case "Identifier":
842
name = key.name;break;
843
case "Literal":
844
name = String(key.value);break;
845
default:
846
return;
847
}
848
var kind = prop.kind || "init",
849
other = undefined;
850
if (has(propHash, name)) {
851
other = propHash[name];
852
var isGetSet = kind !== "init";
853
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
854
} else {
855
other = propHash[name] = {
856
init: false,
857
get: false,
858
set: false
859
};
860
}
861
other[kind] = true;
862
};
863
864
// ### Expression parsing
865
866
// These nest, from the most general expression type at the top to
867
// 'atomic', nondivisible expression types at the bottom. Most of
868
// the functions will simply let the function(s) below them parse,
869
// and, *if* the syntactic construct they handle is present, wrap
870
// the AST node that the inner parser gave them in another node.
871
872
// Parse a full expression. The optional arguments are used to
873
// forbid the `in` operator (in for loops initalization expressions)
874
// and provide reference for storing '=' operator inside shorthand
875
// property assignment in contexts where both object expression
876
// and object pattern might appear (so it's possible to raise
877
// delayed syntax error at correct position).
878
879
pp.parseExpression = function (noIn, refShorthandDefaultPos) {
880
var startPos = this.start,
881
startLoc = this.startLoc;
882
var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
883
if (this.type === tt.comma) {
884
var node = this.startNodeAt(startPos, startLoc);
885
node.expressions = [expr];
886
while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
887
return this.finishNode(node, "SequenceExpression");
888
}
889
return expr;
890
};
891
892
// Parse an assignment expression. This includes applications of
893
// operators like `+=`.
894
895
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
896
if (this.type == tt._yield && this.inGenerator) return this.parseYield();
897
898
var failOnShorthandAssign = undefined;
899
if (!refShorthandDefaultPos) {
900
refShorthandDefaultPos = { start: 0 };
901
failOnShorthandAssign = true;
902
} else {
903
failOnShorthandAssign = false;
904
}
905
var startPos = this.start,
906
startLoc = this.startLoc;
907
if (this.type == tt.parenL || this.type == tt.name) this.potentialArrowAt = this.start;
908
var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
909
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
910
if (this.type.isAssign) {
911
var node = this.startNodeAt(startPos, startLoc);
912
node.operator = this.value;
913
node.left = this.type === tt.eq ? this.toAssignable(left) : left;
914
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
915
this.checkLVal(left);
916
this.next();
917
node.right = this.parseMaybeAssign(noIn);
918
return this.finishNode(node, "AssignmentExpression");
919
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
920
this.unexpected(refShorthandDefaultPos.start);
921
}
922
return left;
923
};
924
925
// Parse a ternary conditional (`?:`) operator.
926
927
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
928
var startPos = this.start,
929
startLoc = this.startLoc;
930
var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
931
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
932
if (this.eat(tt.question)) {
933
var node = this.startNodeAt(startPos, startLoc);
934
node.test = expr;
935
node.consequent = this.parseMaybeAssign();
936
this.expect(tt.colon);
937
node.alternate = this.parseMaybeAssign(noIn);
938
return this.finishNode(node, "ConditionalExpression");
939
}
940
return expr;
941
};
942
943
// Start the precedence parser.
944
945
pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
946
var startPos = this.start,
947
startLoc = this.startLoc;
948
var expr = this.parseMaybeUnary(refShorthandDefaultPos);
949
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
950
return this.parseExprOp(expr, startPos, startLoc, -1, noIn);
951
};
952
953
// Parse binary operators with the operator precedence parsing
954
// algorithm. `left` is the left-hand side of the operator.
955
// `minPrec` provides context that allows the function to stop and
956
// defer further parser to one of its callers when it encounters an
957
// operator that has a lower precedence than the set it is parsing.
958
959
pp.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
960
var prec = this.type.binop;
961
if (Array.isArray(leftStartPos)) {
962
if (this.options.locations && noIn === undefined) {
963
// shift arguments to left by one
964
noIn = minPrec;
965
minPrec = leftStartLoc;
966
// flatten leftStartPos
967
leftStartLoc = leftStartPos[1];
968
leftStartPos = leftStartPos[0];
969
}
970
}
971
if (prec != null && (!noIn || this.type !== tt._in)) {
972
if (prec > minPrec) {
973
var node = this.startNodeAt(leftStartPos, leftStartLoc);
974
node.left = left;
975
node.operator = this.value;
976
var op = this.type;
977
this.next();
978
var startPos = this.start,
979
startLoc = this.startLoc;
980
node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn);
981
this.finishNode(node, op === tt.logicalOR || op === tt.logicalAND ? "LogicalExpression" : "BinaryExpression");
982
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
983
}
984
}
985
return left;
986
};
987
988
// Parse unary operators, both prefix and postfix.
989
990
pp.parseMaybeUnary = function (refShorthandDefaultPos) {
991
if (this.type.prefix) {
992
var node = this.startNode(),
993
update = this.type === tt.incDec;
994
node.operator = this.value;
995
node.prefix = true;
996
this.next();
997
node.argument = this.parseMaybeUnary();
998
if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
999
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
1000
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
1001
}
1002
var startPos = this.start,
1003
startLoc = this.startLoc;
1004
var expr = this.parseExprSubscripts(refShorthandDefaultPos);
1005
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
1006
while (this.type.postfix && !this.canInsertSemicolon()) {
1007
var node = this.startNodeAt(startPos, startLoc);
1008
node.operator = this.value;
1009
node.prefix = false;
1010
node.argument = expr;
1011
this.checkLVal(expr);
1012
this.next();
1013
expr = this.finishNode(node, "UpdateExpression");
1014
}
1015
return expr;
1016
};
1017
1018
// Parse call, dot, and `[]`-subscript expressions.
1019
1020
pp.parseExprSubscripts = function (refShorthandDefaultPos) {
1021
var startPos = this.start,
1022
startLoc = this.startLoc;
1023
var expr = this.parseExprAtom(refShorthandDefaultPos);
1024
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
1025
return this.parseSubscripts(expr, startPos, startLoc);
1026
};
1027
1028
pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
1029
if (Array.isArray(startPos)) {
1030
if (this.options.locations && noCalls === undefined) {
1031
// shift arguments to left by one
1032
noCalls = startLoc;
1033
// flatten startPos
1034
startLoc = startPos[1];
1035
startPos = startPos[0];
1036
}
1037
}
1038
for (;;) {
1039
if (this.eat(tt.dot)) {
1040
var node = this.startNodeAt(startPos, startLoc);
1041
node.object = base;
1042
node.property = this.parseIdent(true);
1043
node.computed = false;
1044
base = this.finishNode(node, "MemberExpression");
1045
} else if (this.eat(tt.bracketL)) {
1046
var node = this.startNodeAt(startPos, startLoc);
1047
node.object = base;
1048
node.property = this.parseExpression();
1049
node.computed = true;
1050
this.expect(tt.bracketR);
1051
base = this.finishNode(node, "MemberExpression");
1052
} else if (!noCalls && this.eat(tt.parenL)) {
1053
var node = this.startNodeAt(startPos, startLoc);
1054
node.callee = base;
1055
node.arguments = this.parseExprList(tt.parenR, false);
1056
base = this.finishNode(node, "CallExpression");
1057
} else if (this.type === tt.backQuote) {
1058
var node = this.startNodeAt(startPos, startLoc);
1059
node.tag = base;
1060
node.quasi = this.parseTemplate();
1061
base = this.finishNode(node, "TaggedTemplateExpression");
1062
} else {
1063
return base;
1064
}
1065
}
1066
};
1067
1068
// Parse an atomic expression — either a single token that is an
1069
// expression, an expression started by a keyword like `function` or
1070
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
1071
// or `{}`.
1072
1073
pp.parseExprAtom = function (refShorthandDefaultPos) {
1074
var node = undefined,
1075
canBeArrow = this.potentialArrowAt == this.start;
1076
switch (this.type) {
1077
case tt._this:
1078
case tt._super:
1079
var type = this.type === tt._this ? "ThisExpression" : "Super";
1080
node = this.startNode();
1081
this.next();
1082
return this.finishNode(node, type);
1083
1084
case tt._yield:
1085
if (this.inGenerator) this.unexpected();
1086
1087
case tt.name:
1088
var startPos = this.start,
1089
startLoc = this.startLoc;
1090
var id = this.parseIdent(this.type !== tt.name);
1091
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]);
1092
return id;
1093
1094
case tt.regexp:
1095
var value = this.value;
1096
node = this.parseLiteral(value.value);
1097
node.regex = { pattern: value.pattern, flags: value.flags };
1098
return node;
1099
1100
case tt.num:case tt.string:
1101
return this.parseLiteral(this.value);
1102
1103
case tt._null:case tt._true:case tt._false:
1104
node = this.startNode();
1105
node.value = this.type === tt._null ? null : this.type === tt._true;
1106
node.raw = this.type.keyword;
1107
this.next();
1108
return this.finishNode(node, "Literal");
1109
1110
case tt.parenL:
1111
return this.parseParenAndDistinguishExpression(canBeArrow);
1112
1113
case tt.bracketL:
1114
node = this.startNode();
1115
this.next();
1116
// check whether this is array comprehension or regular array
1117
if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
1118
return this.parseComprehension(node, false);
1119
}
1120
node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos);
1121
return this.finishNode(node, "ArrayExpression");
1122
1123
case tt.braceL:
1124
return this.parseObj(false, refShorthandDefaultPos);
1125
1126
case tt._function:
1127
node = this.startNode();
1128
this.next();
1129
return this.parseFunction(node, false);
1130
1131
case tt._class:
1132
return this.parseClass(this.startNode(), false);
1133
1134
case tt._new:
1135
return this.parseNew();
1136
1137
case tt.backQuote:
1138
return this.parseTemplate();
1139
1140
default:
1141
this.unexpected();
1142
}
1143
};
1144
1145
pp.parseLiteral = function (value) {
1146
var node = this.startNode();
1147
node.value = value;
1148
node.raw = this.input.slice(this.start, this.end);
1149
this.next();
1150
return this.finishNode(node, "Literal");
1151
};
1152
1153
pp.parseParenExpression = function () {
1154
this.expect(tt.parenL);
1155
var val = this.parseExpression();
1156
this.expect(tt.parenR);
1157
return val;
1158
};
1159
1160
pp.parseParenAndDistinguishExpression = function (canBeArrow) {
1161
var startPos = this.start,
1162
startLoc = this.startLoc,
1163
val = undefined;
1164
if (this.options.ecmaVersion >= 6) {
1165
this.next();
1166
1167
if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
1168
return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
1169
}
1170
1171
var innerStartPos = this.start,
1172
innerStartLoc = this.startLoc;
1173
var exprList = [],
1174
first = true;
1175
var refShorthandDefaultPos = { start: 0 },
1176
spreadStart = undefined,
1177
innerParenStart = undefined;
1178
while (this.type !== tt.parenR) {
1179
first ? first = false : this.expect(tt.comma);
1180
if (this.type === tt.ellipsis) {
1181
spreadStart = this.start;
1182
exprList.push(this.parseParenItem(this.parseRest()));
1183
break;
1184
} else {
1185
if (this.type === tt.parenL && !innerParenStart) {
1186
innerParenStart = this.start;
1187
}
1188
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
1189
}
1190
}
1191
var innerEndPos = this.start,
1192
innerEndLoc = this.startLoc;
1193
this.expect(tt.parenR);
1194
1195
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
1196
if (innerParenStart) this.unexpected(innerParenStart);
1197
return this.parseParenArrowList(startPos, startLoc, exprList);
1198
}
1199
1200
if (!exprList.length) this.unexpected(this.lastTokStart);
1201
if (spreadStart) this.unexpected(spreadStart);
1202
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
1203
1204
if (exprList.length > 1) {
1205
val = this.startNodeAt(innerStartPos, innerStartLoc);
1206
val.expressions = exprList;
1207
this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
1208
} else {
1209
val = exprList[0];
1210
}
1211
} else {
1212
val = this.parseParenExpression();
1213
}
1214
1215
if (this.options.preserveParens) {
1216
var par = this.startNodeAt(startPos, startLoc);
1217
par.expression = val;
1218
return this.finishNode(par, "ParenthesizedExpression");
1219
} else {
1220
return val;
1221
}
1222
};
1223
1224
pp.parseParenItem = function (item) {
1225
return item;
1226
};
1227
1228
pp.parseParenArrowList = function (startPos, startLoc, exprList) {
1229
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList);
1230
};
1231
1232
// New's precedence is slightly tricky. It must allow its argument
1233
// to be a `[]` or dot subscript expression, but not a call — at
1234
// least, not without wrapping it in parentheses. Thus, it uses the
1235
1236
var empty = [];
1237
1238
pp.parseNew = function () {
1239
var node = this.startNode();
1240
var meta = this.parseIdent(true);
1241
if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
1242
node.meta = meta;
1243
node.property = this.parseIdent(true);
1244
if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
1245
return this.finishNode(node, "MetaProperty");
1246
}
1247
var startPos = this.start,
1248
startLoc = this.startLoc;
1249
node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
1250
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false);else node.arguments = empty;
1251
return this.finishNode(node, "NewExpression");
1252
};
1253
1254
// Parse template expression.
1255
1256
pp.parseTemplateElement = function () {
1257
var elem = this.startNode();
1258
elem.value = {
1259
raw: this.input.slice(this.start, this.end),
1260
cooked: this.value
1261
};
1262
this.next();
1263
elem.tail = this.type === tt.backQuote;
1264
return this.finishNode(elem, "TemplateElement");
1265
};
1266
1267
pp.parseTemplate = function () {
1268
var node = this.startNode();
1269
this.next();
1270
node.expressions = [];
1271
var curElt = this.parseTemplateElement();
1272
node.quasis = [curElt];
1273
while (!curElt.tail) {
1274
this.expect(tt.dollarBraceL);
1275
node.expressions.push(this.parseExpression());
1276
this.expect(tt.braceR);
1277
node.quasis.push(curElt = this.parseTemplateElement());
1278
}
1279
this.next();
1280
return this.finishNode(node, "TemplateLiteral");
1281
};
1282
1283
// Parse an object literal or binding pattern.
1284
1285
pp.parseObj = function (isPattern, refShorthandDefaultPos) {
1286
var node = this.startNode(),
1287
first = true,
1288
propHash = {};
1289
node.properties = [];
1290
this.next();
1291
while (!this.eat(tt.braceR)) {
1292
if (!first) {
1293
this.expect(tt.comma);
1294
if (this.afterTrailingComma(tt.braceR)) break;
1295
} else first = false;
1296
1297
var prop = this.startNode(),
1298
isGenerator = undefined,
1299
startPos = undefined,
1300
startLoc = undefined;
1301
if (this.options.ecmaVersion >= 6) {
1302
prop.method = false;
1303
prop.shorthand = false;
1304
if (isPattern || refShorthandDefaultPos) {
1305
startPos = this.start;
1306
startLoc = this.startLoc;
1307
}
1308
if (!isPattern) isGenerator = this.eat(tt.star);
1309
}
1310
this.parsePropertyName(prop);
1311
this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos);
1312
this.checkPropClash(prop, propHash);
1313
node.properties.push(this.finishNode(prop, "Property"));
1314
}
1315
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
1316
};
1317
1318
pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) {
1319
if (this.eat(tt.colon)) {
1320
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
1321
prop.kind = "init";
1322
} else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
1323
if (isPattern) this.unexpected();
1324
prop.kind = "init";
1325
prop.method = true;
1326
prop.value = this.parseMethod(isGenerator);
1327
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != tt.comma && this.type != tt.braceR)) {
1328
if (isGenerator || isPattern) this.unexpected();
1329
prop.kind = prop.key.name;
1330
this.parsePropertyName(prop);
1331
prop.value = this.parseMethod(false);
1332
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
1333
prop.kind = "init";
1334
if (isPattern) {
1335
if (this.isKeyword(prop.key.name) || this.strict && (reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
1336
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
1337
} else if (this.type === tt.eq && refShorthandDefaultPos) {
1338
if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
1339
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
1340
} else {
1341
prop.value = prop.key;
1342
}
1343
prop.shorthand = true;
1344
} else this.unexpected();
1345
};
1346
1347
pp.parsePropertyName = function (prop) {
1348
if (this.options.ecmaVersion >= 6) {
1349
if (this.eat(tt.bracketL)) {
1350
prop.computed = true;
1351
prop.key = this.parseMaybeAssign();
1352
this.expect(tt.bracketR);
1353
return prop.key;
1354
} else {
1355
prop.computed = false;
1356
}
1357
}
1358
return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true);
1359
};
1360
1361
// Initialize empty function node.
1362
1363
pp.initFunction = function (node) {
1364
node.id = null;
1365
if (this.options.ecmaVersion >= 6) {
1366
node.generator = false;
1367
node.expression = false;
1368
}
1369
};
1370
1371
// Parse object or class method.
1372
1373
pp.parseMethod = function (isGenerator) {
1374
var node = this.startNode();
1375
this.initFunction(node);
1376
this.expect(tt.parenL);
1377
node.params = this.parseBindingList(tt.parenR, false, false);
1378
var allowExpressionBody = undefined;
1379
if (this.options.ecmaVersion >= 6) {
1380
node.generator = isGenerator;
1381
allowExpressionBody = true;
1382
} else {
1383
allowExpressionBody = false;
1384
}
1385
this.parseFunctionBody(node, allowExpressionBody);
1386
return this.finishNode(node, "FunctionExpression");
1387
};
1388
1389
// Parse arrow function expression with given parameters.
1390
1391
pp.parseArrowExpression = function (node, params) {
1392
this.initFunction(node);
1393
node.params = this.toAssignableList(params, true);
1394
this.parseFunctionBody(node, true);
1395
return this.finishNode(node, "ArrowFunctionExpression");
1396
};
1397
1398
// Parse function body and check parameters.
1399
1400
pp.parseFunctionBody = function (node, allowExpression) {
1401
var isExpression = allowExpression && this.type !== tt.braceL;
1402
1403
if (isExpression) {
1404
node.body = this.parseMaybeAssign();
1405
node.expression = true;
1406
} else {
1407
// Start a new scope with regard to labels and the `inFunction`
1408
// flag (restore them to their old value afterwards).
1409
var oldInFunc = this.inFunction,
1410
oldInGen = this.inGenerator,
1411
oldLabels = this.labels;
1412
this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
1413
node.body = this.parseBlock(true);
1414
node.expression = false;
1415
this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
1416
}
1417
1418
// If this is a strict mode function, verify that argument names
1419
// are not repeated, and it does not try to bind the words `eval`
1420
// or `arguments`.
1421
if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
1422
var nameHash = {},
1423
oldStrict = this.strict;
1424
this.strict = true;
1425
if (node.id) this.checkLVal(node.id, true);
1426
for (var i = 0; i < node.params.length; i++) {
1427
this.checkLVal(node.params[i], true, nameHash);
1428
}this.strict = oldStrict;
1429
}
1430
};
1431
1432
// Parses a comma-separated list of expressions, and returns them as
1433
// an array. `close` is the token type that ends the list, and
1434
// `allowEmpty` can be turned on to allow subsequent commas with
1435
// nothing in between them to be parsed as `null` (which is needed
1436
// for array literals).
1437
1438
pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
1439
var elts = [],
1440
first = true;
1441
while (!this.eat(close)) {
1442
if (!first) {
1443
this.expect(tt.comma);
1444
if (allowTrailingComma && this.afterTrailingComma(close)) break;
1445
} else first = false;
1446
1447
if (allowEmpty && this.type === tt.comma) {
1448
elts.push(null);
1449
} else {
1450
if (this.type === tt.ellipsis) elts.push(this.parseSpread(refShorthandDefaultPos));else elts.push(this.parseMaybeAssign(false, refShorthandDefaultPos));
1451
}
1452
}
1453
return elts;
1454
};
1455
1456
// Parse the next token as an identifier. If `liberal` is true (used
1457
// when parsing properties), it will also convert keywords into
1458
// identifiers.
1459
1460
pp.parseIdent = function (liberal) {
1461
var node = this.startNode();
1462
if (liberal && this.options.allowReserved == "never") liberal = false;
1463
if (this.type === tt.name) {
1464
if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
1465
node.name = this.value;
1466
} else if (liberal && this.type.keyword) {
1467
node.name = this.type.keyword;
1468
} else {
1469
this.unexpected();
1470
}
1471
this.next();
1472
return this.finishNode(node, "Identifier");
1473
};
1474
1475
// Parses yield expression inside generator.
1476
1477
pp.parseYield = function () {
1478
var node = this.startNode();
1479
this.next();
1480
if (this.type == tt.semi || this.canInsertSemicolon() || this.type != tt.star && !this.type.startsExpr) {
1481
node.delegate = false;
1482
node.argument = null;
1483
} else {
1484
node.delegate = this.eat(tt.star);
1485
node.argument = this.parseMaybeAssign();
1486
}
1487
return this.finishNode(node, "YieldExpression");
1488
};
1489
1490
// Parses array and generator comprehensions.
1491
1492
pp.parseComprehension = function (node, isGenerator) {
1493
node.blocks = [];
1494
while (this.type === tt._for) {
1495
var block = this.startNode();
1496
this.next();
1497
this.expect(tt.parenL);
1498
block.left = this.parseBindingAtom();
1499
this.checkLVal(block.left, true);
1500
this.expectContextual("of");
1501
block.right = this.parseExpression();
1502
this.expect(tt.parenR);
1503
node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
1504
}
1505
node.filter = this.eat(tt._if) ? this.parseParenExpression() : null;
1506
node.body = this.parseExpression();
1507
this.expect(isGenerator ? tt.parenR : tt.bracketR);
1508
node.generator = isGenerator;
1509
return this.finishNode(node, "ComprehensionExpression");
1510
};
1511
1512
},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){
1513
1514
1515
// Test whether a given character code starts an identifier.
1516
1517
"use strict";
1518
1519
exports.isIdentifierStart = isIdentifierStart;
1520
1521
// Test whether a given character is part of an identifier.
1522
1523
exports.isIdentifierChar = isIdentifierChar;
1524
exports.__esModule = true;
1525
// This is a trick taken from Esprima. It turns out that, on
1526
// non-Chrome browsers, to check whether a string is in a set, a
1527
// predicate containing a big ugly `switch` statement is faster than
1528
// a regular expression, and on Chrome the two are about on par.
1529
// This function uses `eval` (non-lexical) to produce such a
1530
// predicate from a space-separated string of words.
1531
//
1532
// It starts by sorting the words by length.
1533
1534
function makePredicate(words) {
1535
words = words.split(" ");
1536
var f = "",
1537
cats = [];
1538
out: for (var i = 0; i < words.length; ++i) {
1539
for (var j = 0; j < cats.length; ++j) {
1540
if (cats[j][0].length == words[i].length) {
1541
cats[j].push(words[i]);
1542
continue out;
1543
}
1544
}cats.push([words[i]]);
1545
}
1546
function compareTo(arr) {
1547
if (arr.length == 1) {
1548
return f += "return str === " + JSON.stringify(arr[0]) + ";";
1549
}f += "switch(str){";
1550
for (var i = 0; i < arr.length; ++i) {
1551
f += "case " + JSON.stringify(arr[i]) + ":";
1552
}f += "return true}return false;";
1553
}
1554
1555
// When there are more than three length categories, an outer
1556
// switch first dispatches on the lengths, to save on comparisons.
1557
1558
if (cats.length > 3) {
1559
cats.sort(function (a, b) {
1560
return b.length - a.length;
1561
});
1562
f += "switch(str.length){";
1563
for (var i = 0; i < cats.length; ++i) {
1564
var cat = cats[i];
1565
f += "case " + cat[0].length + ":";
1566
compareTo(cat);
1567
}
1568
f += "}"
1569
1570
// Otherwise, simply generate a flat `switch` statement.
1571
1572
;
1573
} else {
1574
compareTo(words);
1575
}
1576
return new Function("str", f);
1577
}
1578
1579
// Reserved word lists for various dialects of the language
1580
1581
var reservedWords = {
1582
3: makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"),
1583
5: makePredicate("class enum extends super const export import"),
1584
6: makePredicate("enum await"),
1585
strict: makePredicate("implements interface let package private protected public static yield"),
1586
strictBind: makePredicate("eval arguments")
1587
};
1588
1589
exports.reservedWords = reservedWords;
1590
// And the keywords
1591
1592
var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
1593
1594
var keywords = {
1595
5: makePredicate(ecma5AndLessKeywords),
1596
6: makePredicate(ecma5AndLessKeywords + " let const class extends export import yield super")
1597
};
1598
1599
exports.keywords = keywords;
1600
// ## Character categories
1601
1602
// Big ugly regular expressions that match characters in the
1603
// whitespace, identifier, and identifier-start categories. These
1604
// are only applied when a character is found to actually have a
1605
// code point above 128.
1606
// Generated by `tools/generate-identifier-regex.js`.
1607
1608
var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
1609
var nonASCIIidentifierChars = "‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
1610
1611
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
1612
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
1613
1614
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
1615
1616
// These are a run-length and offset encoded representation of the
1617
// >0xffff code points that are a valid part of identifiers. The
1618
// offset starts at 0x10000, and each pair of numbers represents an
1619
// offset to the next range, and then a size of the range. They were
1620
// generated by tools/generate-identifier-regex.js
1621
var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 1340, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 16355, 541];
1622
var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 4305, 6, 792618, 239];
1623
1624
// This has a complexity linear to the value of the code. The
1625
// assumption is that looking up astral identifier characters is
1626
// rare.
1627
function isInAstralSet(code, set) {
1628
var pos = 65536;
1629
for (var i = 0; i < set.length; i += 2) {
1630
pos += set[i];
1631
if (pos > code) {
1632
return false;
1633
}pos += set[i + 1];
1634
if (pos >= code) {
1635
return true;
1636
}
1637
}
1638
}
1639
function isIdentifierStart(code, astral) {
1640
if (code < 65) {
1641
return code === 36;
1642
}if (code < 91) {
1643
return true;
1644
}if (code < 97) {
1645
return code === 95;
1646
}if (code < 123) {
1647
return true;
1648
}if (code <= 65535) {
1649
return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
1650
}if (astral === false) {
1651
return false;
1652
}return isInAstralSet(code, astralIdentifierStartCodes);
1653
}
1654
1655
function isIdentifierChar(code, astral) {
1656
if (code < 48) {
1657
return code === 36;
1658
}if (code < 58) {
1659
return true;
1660
}if (code < 65) {
1661
return false;
1662
}if (code < 91) {
1663
return true;
1664
}if (code < 97) {
1665
return code === 95;
1666
}if (code < 123) {
1667
return true;
1668
}if (code <= 65535) {
1669
return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
1670
}if (astral === false) {
1671
return false;
1672
}return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
1673
}
1674
1675
},{}],8:[function(_dereq_,module,exports){
1676
"use strict";
1677
1678
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
1679
1680
// The `getLineInfo` function is mostly useful when the
1681
// `locations` option is off (for performance reasons) and you
1682
// want to find the line/column position for a given character
1683
// offset. `input` should be the code string that the offset refers
1684
// into.
1685
1686
exports.getLineInfo = getLineInfo;
1687
exports.__esModule = true;
1688
1689
var Parser = _dereq_("./state").Parser;
1690
1691
var lineBreakG = _dereq_("./whitespace").lineBreakG;
1692
1693
var deprecate = _dereq_("util").deprecate;
1694
1695
// These are used when `options.locations` is on, for the
1696
// `startLoc` and `endLoc` properties.
1697
1698
var Position = exports.Position = (function () {
1699
function Position(line, col) {
1700
_classCallCheck(this, Position);
1701
1702
this.line = line;
1703
this.column = col;
1704
}
1705
1706
Position.prototype.offset = function offset(n) {
1707
return new Position(this.line, this.column + n);
1708
};
1709
1710
return Position;
1711
})();
1712
1713
var SourceLocation = exports.SourceLocation = function SourceLocation(p, start, end) {
1714
_classCallCheck(this, SourceLocation);
1715
1716
this.start = start;
1717
this.end = end;
1718
if (p.sourceFile !== null) this.source = p.sourceFile;
1719
};
1720
1721
function getLineInfo(input, offset) {
1722
for (var line = 1, cur = 0;;) {
1723
lineBreakG.lastIndex = cur;
1724
var match = lineBreakG.exec(input);
1725
if (match && match.index < offset) {
1726
++line;
1727
cur = match.index + match[0].length;
1728
} else {
1729
return new Position(line, offset - cur);
1730
}
1731
}
1732
}
1733
1734
var pp = Parser.prototype;
1735
1736
// This function is used to raise exceptions on parse errors. It
1737
// takes an offset integer (into the current `input`) to indicate
1738
// the location of the error, attaches the position to the end
1739
// of the error message, and then raises a `SyntaxError` with that
1740
// message.
1741
1742
pp.raise = function (pos, message) {
1743
var loc = getLineInfo(this.input, pos);
1744
message += " (" + loc.line + ":" + loc.column + ")";
1745
var err = new SyntaxError(message);
1746
err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
1747
throw err;
1748
};
1749
1750
pp.curPosition = function () {
1751
return new Position(this.curLine, this.pos - this.lineStart);
1752
};
1753
1754
pp.markPosition = function () {
1755
return this.options.locations ? [this.start, this.startLoc] : this.start;
1756
};
1757
1758
},{"./state":13,"./whitespace":19,"util":5}],9:[function(_dereq_,module,exports){
1759
"use strict";
1760
1761
var tt = _dereq_("./tokentype").types;
1762
1763
var Parser = _dereq_("./state").Parser;
1764
1765
var reservedWords = _dereq_("./identifier").reservedWords;
1766
1767
var has = _dereq_("./util").has;
1768
1769
var pp = Parser.prototype;
1770
1771
// Convert existing expression atom to assignable pattern
1772
// if possible.
1773
1774
pp.toAssignable = function (node, isBinding) {
1775
if (this.options.ecmaVersion >= 6 && node) {
1776
switch (node.type) {
1777
case "Identifier":
1778
case "ObjectPattern":
1779
case "ArrayPattern":
1780
case "AssignmentPattern":
1781
break;
1782
1783
case "ObjectExpression":
1784
node.type = "ObjectPattern";
1785
for (var i = 0; i < node.properties.length; i++) {
1786
var prop = node.properties[i];
1787
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
1788
this.toAssignable(prop.value, isBinding);
1789
}
1790
break;
1791
1792
case "ArrayExpression":
1793
node.type = "ArrayPattern";
1794
this.toAssignableList(node.elements, isBinding);
1795
break;
1796
1797
case "AssignmentExpression":
1798
if (node.operator === "=") {
1799
node.type = "AssignmentPattern";
1800
} else {
1801
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
1802
}
1803
break;
1804
1805
case "ParenthesizedExpression":
1806
node.expression = this.toAssignable(node.expression, isBinding);
1807
break;
1808
1809
case "MemberExpression":
1810
if (!isBinding) break;
1811
1812
default:
1813
this.raise(node.start, "Assigning to rvalue");
1814
}
1815
}
1816
return node;
1817
};
1818
1819
// Convert list of expression atoms to binding list.
1820
1821
pp.toAssignableList = function (exprList, isBinding) {
1822
var end = exprList.length;
1823
if (end) {
1824
var last = exprList[end - 1];
1825
if (last && last.type == "RestElement") {
1826
--end;
1827
} else if (last && last.type == "SpreadElement") {
1828
last.type = "RestElement";
1829
var arg = last.argument;
1830
this.toAssignable(arg, isBinding);
1831
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
1832
--end;
1833
}
1834
}
1835
for (var i = 0; i < end; i++) {
1836
var elt = exprList[i];
1837
if (elt) this.toAssignable(elt, isBinding);
1838
}
1839
return exprList;
1840
};
1841
1842
// Parses spread element.
1843
1844
pp.parseSpread = function (refShorthandDefaultPos) {
1845
var node = this.startNode();
1846
this.next();
1847
node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
1848
return this.finishNode(node, "SpreadElement");
1849
};
1850
1851
pp.parseRest = function () {
1852
var node = this.startNode();
1853
this.next();
1854
node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected();
1855
return this.finishNode(node, "RestElement");
1856
};
1857
1858
// Parses lvalue (assignable) atom.
1859
1860
pp.parseBindingAtom = function () {
1861
if (this.options.ecmaVersion < 6) return this.parseIdent();
1862
switch (this.type) {
1863
case tt.name:
1864
return this.parseIdent();
1865
1866
case tt.bracketL:
1867
var node = this.startNode();
1868
this.next();
1869
node.elements = this.parseBindingList(tt.bracketR, true, true);
1870
return this.finishNode(node, "ArrayPattern");
1871
1872
case tt.braceL:
1873
return this.parseObj(true);
1874
1875
default:
1876
this.unexpected();
1877
}
1878
};
1879
1880
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
1881
var elts = [],
1882
first = true;
1883
while (!this.eat(close)) {
1884
if (first) first = false;else this.expect(tt.comma);
1885
if (allowEmpty && this.type === tt.comma) {
1886
elts.push(null);
1887
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
1888
break;
1889
} else if (this.type === tt.ellipsis) {
1890
var rest = this.parseRest();
1891
this.parseBindingListItem(rest);
1892
elts.push(rest);
1893
this.expect(close);
1894
break;
1895
} else {
1896
var elem = this.parseMaybeDefault(this.start, this.startLoc);
1897
this.parseBindingListItem(elem);
1898
elts.push(elem);
1899
}
1900
}
1901
return elts;
1902
};
1903
1904
pp.parseBindingListItem = function (param) {
1905
return param;
1906
};
1907
1908
// Parses assignment pattern around given atom if possible.
1909
1910
pp.parseMaybeDefault = function (startPos, startLoc, left) {
1911
if (Array.isArray(startPos)) {
1912
if (this.options.locations && noCalls === undefined) {
1913
// shift arguments to left by one
1914
left = startLoc;
1915
// flatten startPos
1916
startLoc = startPos[1];
1917
startPos = startPos[0];
1918
}
1919
}
1920
left = left || this.parseBindingAtom();
1921
if (!this.eat(tt.eq)) return left;
1922
var node = this.startNodeAt(startPos, startLoc);
1923
node.operator = "=";
1924
node.left = left;
1925
node.right = this.parseMaybeAssign();
1926
return this.finishNode(node, "AssignmentPattern");
1927
};
1928
1929
// Verify that a node is an lval — something that can be assigned
1930
// to.
1931
1932
pp.checkLVal = function (expr, isBinding, checkClashes) {
1933
switch (expr.type) {
1934
case "Identifier":
1935
if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
1936
if (checkClashes) {
1937
if (has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
1938
checkClashes[expr.name] = true;
1939
}
1940
break;
1941
1942
case "MemberExpression":
1943
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
1944
break;
1945
1946
case "ObjectPattern":
1947
for (var i = 0; i < expr.properties.length; i++) {
1948
this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
1949
}break;
1950
1951
case "ArrayPattern":
1952
for (var i = 0; i < expr.elements.length; i++) {
1953
var elem = expr.elements[i];
1954
if (elem) this.checkLVal(elem, isBinding, checkClashes);
1955
}
1956
break;
1957
1958
case "AssignmentPattern":
1959
this.checkLVal(expr.left, isBinding, checkClashes);
1960
break;
1961
1962
case "RestElement":
1963
this.checkLVal(expr.argument, isBinding, checkClashes);
1964
break;
1965
1966
case "ParenthesizedExpression":
1967
this.checkLVal(expr.expression, isBinding, checkClashes);
1968
break;
1969
1970
default:
1971
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
1972
}
1973
};
1974
1975
},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],10:[function(_dereq_,module,exports){
1976
"use strict";
1977
1978
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
1979
1980
exports.__esModule = true;
1981
1982
var Parser = _dereq_("./state").Parser;
1983
1984
var SourceLocation = _dereq_("./location").SourceLocation;
1985
1986
// Start an AST node, attaching a start offset.
1987
1988
var pp = Parser.prototype;
1989
1990
var Node = exports.Node = function Node() {
1991
_classCallCheck(this, Node);
1992
};
1993
1994
pp.startNode = function () {
1995
var node = new Node();
1996
node.start = this.start;
1997
if (this.options.locations) node.loc = new SourceLocation(this, this.startLoc);
1998
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
1999
if (this.options.ranges) node.range = [this.start, 0];
2000
return node;
2001
};
2002
2003
pp.startNodeAt = function (pos, loc) {
2004
var node = new Node();
2005
if (Array.isArray(pos)) {
2006
if (this.options.locations && loc === undefined) {
2007
// flatten pos
2008
loc = pos[1];
2009
pos = pos[0];
2010
}
2011
}
2012
node.start = pos;
2013
if (this.options.locations) node.loc = new SourceLocation(this, loc);
2014
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
2015
if (this.options.ranges) node.range = [pos, 0];
2016
return node;
2017
};
2018
2019
// Finish an AST node, adding `type` and `end` properties.
2020
2021
pp.finishNode = function (node, type) {
2022
node.type = type;
2023
node.end = this.lastTokEnd;
2024
if (this.options.locations) node.loc.end = this.lastTokEndLoc;
2025
if (this.options.ranges) node.range[1] = this.lastTokEnd;
2026
return node;
2027
};
2028
2029
// Finish node at given position
2030
2031
pp.finishNodeAt = function (node, type, pos, loc) {
2032
node.type = type;
2033
if (Array.isArray(pos)) {
2034
if (this.options.locations && loc === undefined) {
2035
// flatten pos
2036
loc = pos[1];
2037
pos = pos[0];
2038
}
2039
}
2040
node.end = pos;
2041
if (this.options.locations) node.loc.end = loc;
2042
if (this.options.ranges) node.range[1] = pos;
2043
return node;
2044
};
2045
2046
},{"./location":8,"./state":13}],11:[function(_dereq_,module,exports){
2047
2048
2049
// Interpret and default an options object
2050
2051
"use strict";
2052
2053
exports.getOptions = getOptions;
2054
exports.__esModule = true;
2055
2056
var _util = _dereq_("./util");
2057
2058
var has = _util.has;
2059
var isArray = _util.isArray;
2060
2061
var SourceLocation = _dereq_("./location").SourceLocation;
2062
2063
// A second optional argument can be given to further configure
2064
// the parser process. These options are recognized:
2065
2066
var defaultOptions = {
2067
// `ecmaVersion` indicates the ECMAScript version to parse. Must
2068
// be either 3, or 5, or 6. This influences support for strict
2069
// mode, the set of reserved words, support for getters and
2070
// setters and other features.
2071
ecmaVersion: 5,
2072
// Source type ("script" or "module") for different semantics
2073
sourceType: "script",
2074
// `onInsertedSemicolon` can be a callback that will be called
2075
// when a semicolon is automatically inserted. It will be passed
2076
// th position of the comma as an offset, and if `locations` is
2077
// enabled, it is given the location as a `{line, column}` object
2078
// as second argument.
2079
onInsertedSemicolon: null,
2080
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
2081
// trailing commas.
2082
onTrailingComma: null,
2083
// By default, reserved words are not enforced. Disable
2084
// `allowReserved` to enforce them. When this option has the
2085
// value "never", reserved words and keywords can also not be
2086
// used as property names.
2087
allowReserved: true,
2088
// When enabled, a return at the top level is not considered an
2089
// error.
2090
allowReturnOutsideFunction: false,
2091
// When enabled, import/export statements are not constrained to
2092
// appearing at the top of the program.
2093
allowImportExportEverywhere: false,
2094
// When enabled, hashbang directive in the beginning of file
2095
// is allowed and treated as a line comment.
2096
allowHashBang: false,
2097
// When `locations` is on, `loc` properties holding objects with
2098
// `start` and `end` properties in `{line, column}` form (with
2099
// line being 1-based and column 0-based) will be attached to the
2100
// nodes.
2101
locations: false,
2102
// A function can be passed as `onToken` option, which will
2103
// cause Acorn to call that function with object in the same
2104
// format as tokenize() returns. Note that you are not
2105
// allowed to call the parser from the callback—that will
2106
// corrupt its internal state.
2107
onToken: null,
2108
// A function can be passed as `onComment` option, which will
2109
// cause Acorn to call that function with `(block, text, start,
2110
// end)` parameters whenever a comment is skipped. `block` is a
2111
// boolean indicating whether this is a block (`/* */`) comment,
2112
// `text` is the content of the comment, and `start` and `end` are
2113
// character offsets that denote the start and end of the comment.
2114
// When the `locations` option is on, two more parameters are
2115
// passed, the full `{line, column}` locations of the start and
2116
// end of the comments. Note that you are not allowed to call the
2117
// parser from the callback—that will corrupt its internal state.
2118
onComment: null,
2119
// Nodes have their start and end characters offsets recorded in
2120
// `start` and `end` properties (directly on the node, rather than
2121
// the `loc` object, which holds line/column data. To also add a
2122
// [semi-standardized][range] `range` property holding a `[start,
2123
// end]` array with the same numbers, set the `ranges` option to
2124
// `true`.
2125
//
2126
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
2127
ranges: false,
2128
// It is possible to parse multiple files into a single AST by
2129
// passing the tree produced by parsing the first file as
2130
// `program` option in subsequent parses. This will add the
2131
// toplevel forms of the parsed file to the `Program` (top) node
2132
// of an existing parse tree.
2133
program: null,
2134
// When `locations` is on, you can pass this to record the source
2135
// file in every node's `loc` object.
2136
sourceFile: null,
2137
// This value, if given, is stored in every node, whether
2138
// `locations` is on or off.
2139
directSourceFile: null,
2140
// When enabled, parenthesized expressions are represented by
2141
// (non-standard) ParenthesizedExpression nodes
2142
preserveParens: false,
2143
plugins: {}
2144
};exports.defaultOptions = defaultOptions;
2145
2146
function getOptions(opts) {
2147
var options = {};
2148
for (var opt in defaultOptions) {
2149
options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt];
2150
}if (isArray(options.onToken)) {
2151
(function () {
2152
var tokens = options.onToken;
2153
options.onToken = function (token) {
2154
return tokens.push(token);
2155
};
2156
})();
2157
}
2158
if (isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
2159
2160
return options;
2161
}
2162
2163
function pushComment(options, array) {
2164
return function (block, text, start, end, startLoc, endLoc) {
2165
var comment = {
2166
type: block ? "Block" : "Line",
2167
value: text,
2168
start: start,
2169
end: end
2170
};
2171
if (options.locations) comment.loc = new SourceLocation(this, startLoc, endLoc);
2172
if (options.ranges) comment.range = [start, end];
2173
array.push(comment);
2174
};
2175
}
2176
2177
},{"./location":8,"./util":18}],12:[function(_dereq_,module,exports){
2178
"use strict";
2179
2180
var tt = _dereq_("./tokentype").types;
2181
2182
var Parser = _dereq_("./state").Parser;
2183
2184
var lineBreak = _dereq_("./whitespace").lineBreak;
2185
2186
var pp = Parser.prototype;
2187
2188
// ## Parser utilities
2189
2190
// Test whether a statement node is the string literal `"use strict"`.
2191
2192
pp.isUseStrict = function (stmt) {
2193
return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
2194
};
2195
2196
// Predicate that tests whether the next token is of the given
2197
// type, and if yes, consumes it as a side effect.
2198
2199
pp.eat = function (type) {
2200
if (this.type === type) {
2201
this.next();
2202
return true;
2203
} else {
2204
return false;
2205
}
2206
};
2207
2208
// Tests whether parsed token is a contextual keyword.
2209
2210
pp.isContextual = function (name) {
2211
return this.type === tt.name && this.value === name;
2212
};
2213
2214
// Consumes contextual keyword if possible.
2215
2216
pp.eatContextual = function (name) {
2217
return this.value === name && this.eat(tt.name);
2218
};
2219
2220
// Asserts that following token is given contextual keyword.
2221
2222
pp.expectContextual = function (name) {
2223
if (!this.eatContextual(name)) this.unexpected();
2224
};
2225
2226
// Test whether a semicolon can be inserted at the current position.
2227
2228
pp.canInsertSemicolon = function () {
2229
return this.type === tt.eof || this.type === tt.braceR || lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
2230
};
2231
2232
pp.insertSemicolon = function () {
2233
if (this.canInsertSemicolon()) {
2234
if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
2235
return true;
2236
}
2237
};
2238
2239
// Consume a semicolon, or, failing that, see if we are allowed to
2240
// pretend that there is a semicolon at this position.
2241
2242
pp.semicolon = function () {
2243
if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected();
2244
};
2245
2246
pp.afterTrailingComma = function (tokType) {
2247
if (this.type == tokType) {
2248
if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
2249
this.next();
2250
return true;
2251
}
2252
};
2253
2254
// Expect a token of a given type. If found, consume it, otherwise,
2255
// raise an unexpected token error.
2256
2257
pp.expect = function (type) {
2258
this.eat(type) || this.unexpected();
2259
};
2260
2261
// Raise an unexpected token error.
2262
2263
pp.unexpected = function (pos) {
2264
this.raise(pos != null ? pos : this.start, "Unexpected token");
2265
};
2266
2267
},{"./state":13,"./tokentype":17,"./whitespace":19}],13:[function(_dereq_,module,exports){
2268
"use strict";
2269
2270
exports.Parser = Parser;
2271
exports.__esModule = true;
2272
2273
var _identifier = _dereq_("./identifier");
2274
2275
var reservedWords = _identifier.reservedWords;
2276
var keywords = _identifier.keywords;
2277
2278
var tt = _dereq_("./tokentype").types;
2279
2280
var lineBreak = _dereq_("./whitespace").lineBreak;
2281
2282
function Parser(options, input, startPos) {
2283
this.options = options;
2284
this.sourceFile = this.options.sourceFile || null;
2285
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
2286
this.isReservedWord = reservedWords[this.options.ecmaVersion];
2287
this.input = input;
2288
2289
// Load plugins
2290
this.loadPlugins(this.options.plugins);
2291
2292
// Set up token state
2293
2294
// The current position of the tokenizer in the input.
2295
if (startPos) {
2296
this.pos = startPos;
2297
this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
2298
this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
2299
} else {
2300
this.pos = this.lineStart = 0;
2301
this.curLine = 1;
2302
}
2303
2304
// Properties of the current token:
2305
// Its type
2306
this.type = tt.eof;
2307
// For tokens that include more information than their type, the value
2308
this.value = null;
2309
// Its start and end offset
2310
this.start = this.end = this.pos;
2311
// And, if locations are used, the {line, column} object
2312
// corresponding to those offsets
2313
this.startLoc = this.endLoc = null;
2314
2315
// Position information for the previous token
2316
this.lastTokEndLoc = this.lastTokStartLoc = null;
2317
this.lastTokStart = this.lastTokEnd = this.pos;
2318
2319
// The context stack is used to superficially track syntactic
2320
// context to predict whether a regular expression is allowed in a
2321
// given position.
2322
this.context = this.initialContext();
2323
this.exprAllowed = true;
2324
2325
// Figure out if it's a module code.
2326
this.strict = this.inModule = this.options.sourceType === "module";
2327
2328
// Used to signify the start of a potential arrow function
2329
this.potentialArrowAt = -1;
2330
2331
// Flags to track whether we are in a function, a generator.
2332
this.inFunction = this.inGenerator = false;
2333
// Labels in scope.
2334
this.labels = [];
2335
2336
// If enabled, skip leading hashbang line.
2337
if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
2338
}
2339
2340
Parser.prototype.extend = function (name, f) {
2341
this[name] = f(this[name]);
2342
};
2343
2344
// Registered plugins
2345
2346
var plugins = {};
2347
2348
exports.plugins = plugins;
2349
Parser.prototype.loadPlugins = function (plugins) {
2350
for (var _name in plugins) {
2351
var plugin = exports.plugins[_name];
2352
if (!plugin) throw new Error("Plugin '" + _name + "' not found");
2353
plugin(this, plugins[_name]);
2354
}
2355
};
2356
2357
},{"./identifier":7,"./tokentype":17,"./whitespace":19}],14:[function(_dereq_,module,exports){
2358
"use strict";
2359
2360
var tt = _dereq_("./tokentype").types;
2361
2362
var Parser = _dereq_("./state").Parser;
2363
2364
var lineBreak = _dereq_("./whitespace").lineBreak;
2365
2366
var pp = Parser.prototype;
2367
2368
// ### Statement parsing
2369
2370
// Parse a program. Initializes the parser, reads any number of
2371
// statements, and wraps them in a Program node. Optionally takes a
2372
// `program` argument. If present, the statements will be appended
2373
// to its body instead of creating a new node.
2374
2375
pp.parseTopLevel = function (node) {
2376
var first = true;
2377
if (!node.body) node.body = [];
2378
while (this.type !== tt.eof) {
2379
var stmt = this.parseStatement(true, true);
2380
node.body.push(stmt);
2381
if (first && this.isUseStrict(stmt)) this.setStrict(true);
2382
first = false;
2383
}
2384
this.next();
2385
if (this.options.ecmaVersion >= 6) {
2386
node.sourceType = this.options.sourceType;
2387
}
2388
return this.finishNode(node, "Program");
2389
};
2390
2391
var loopLabel = { kind: "loop" },
2392
switchLabel = { kind: "switch" };
2393
2394
// Parse a single statement.
2395
//
2396
// If expecting a statement and finding a slash operator, parse a
2397
// regular expression literal. This is to handle cases like
2398
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
2399
// does not help.
2400
2401
pp.parseStatement = function (declaration, topLevel) {
2402
var starttype = this.type,
2403
node = this.startNode();
2404
2405
// Most types of statements are recognized by the keyword they
2406
// start with. Many are trivial to parse, some require a bit of
2407
// complexity.
2408
2409
switch (starttype) {
2410
case tt._break:case tt._continue:
2411
return this.parseBreakContinueStatement(node, starttype.keyword);
2412
case tt._debugger:
2413
return this.parseDebuggerStatement(node);
2414
case tt._do:
2415
return this.parseDoStatement(node);
2416
case tt._for:
2417
return this.parseForStatement(node);
2418
case tt._function:
2419
if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
2420
return this.parseFunctionStatement(node);
2421
case tt._class:
2422
if (!declaration) this.unexpected();
2423
return this.parseClass(node, true);
2424
case tt._if:
2425
return this.parseIfStatement(node);
2426
case tt._return:
2427
return this.parseReturnStatement(node);
2428
case tt._switch:
2429
return this.parseSwitchStatement(node);
2430
case tt._throw:
2431
return this.parseThrowStatement(node);
2432
case tt._try:
2433
return this.parseTryStatement(node);
2434
case tt._let:case tt._const:
2435
if (!declaration) this.unexpected(); // NOTE: falls through to _var
2436
case tt._var:
2437
return this.parseVarStatement(node, starttype);
2438
case tt._while:
2439
return this.parseWhileStatement(node);
2440
case tt._with:
2441
return this.parseWithStatement(node);
2442
case tt.braceL:
2443
return this.parseBlock();
2444
case tt.semi:
2445
return this.parseEmptyStatement(node);
2446
case tt._export:
2447
case tt._import:
2448
if (!this.options.allowImportExportEverywhere) {
2449
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
2450
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
2451
}
2452
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
2453
2454
// If the statement does not start with a statement keyword or a
2455
// brace, it's an ExpressionStatement or LabeledStatement. We
2456
// simply start parsing an expression, and afterwards, if the
2457
// next token is a colon and the expression was a simple
2458
// Identifier node, we switch to interpreting it as a label.
2459
default:
2460
var maybeName = this.value,
2461
expr = this.parseExpression();
2462
if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
2463
}
2464
};
2465
2466
pp.parseBreakContinueStatement = function (node, keyword) {
2467
var isBreak = keyword == "break";
2468
this.next();
2469
if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== tt.name) this.unexpected();else {
2470
node.label = this.parseIdent();
2471
this.semicolon();
2472
}
2473
2474
// Verify that there is an actual destination to break or
2475
// continue to.
2476
for (var i = 0; i < this.labels.length; ++i) {
2477
var lab = this.labels[i];
2478
if (node.label == null || lab.name === node.label.name) {
2479
if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
2480
if (node.label && isBreak) break;
2481
}
2482
}
2483
if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
2484
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
2485
};
2486
2487
pp.parseDebuggerStatement = function (node) {
2488
this.next();
2489
this.semicolon();
2490
return this.finishNode(node, "DebuggerStatement");
2491
};
2492
2493
pp.parseDoStatement = function (node) {
2494
this.next();
2495
this.labels.push(loopLabel);
2496
node.body = this.parseStatement(false);
2497
this.labels.pop();
2498
this.expect(tt._while);
2499
node.test = this.parseParenExpression();
2500
if (this.options.ecmaVersion >= 6) this.eat(tt.semi);else this.semicolon();
2501
return this.finishNode(node, "DoWhileStatement");
2502
};
2503
2504
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
2505
// loop is non-trivial. Basically, we have to parse the init `var`
2506
// statement or expression, disallowing the `in` operator (see
2507
// the second parameter to `parseExpression`), and then check
2508
// whether the next token is `in` or `of`. When there is no init
2509
// part (semicolon immediately after the opening parenthesis), it
2510
// is a regular `for` loop.
2511
2512
pp.parseForStatement = function (node) {
2513
this.next();
2514
this.labels.push(loopLabel);
2515
this.expect(tt.parenL);
2516
if (this.type === tt.semi) return this.parseFor(node, null);
2517
if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
2518
var _init = this.startNode(),
2519
varKind = this.type;
2520
this.next();
2521
this.parseVar(_init, true, varKind);
2522
this.finishNode(_init, "VariableDeclaration");
2523
if ((this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== tt._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
2524
return this.parseFor(node, _init);
2525
}
2526
var refShorthandDefaultPos = { start: 0 };
2527
var init = this.parseExpression(true, refShorthandDefaultPos);
2528
if (this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
2529
this.toAssignable(init);
2530
this.checkLVal(init);
2531
return this.parseForIn(node, init);
2532
} else if (refShorthandDefaultPos.start) {
2533
this.unexpected(refShorthandDefaultPos.start);
2534
}
2535
return this.parseFor(node, init);
2536
};
2537
2538
pp.parseFunctionStatement = function (node) {
2539
this.next();
2540
return this.parseFunction(node, true);
2541
};
2542
2543
pp.parseIfStatement = function (node) {
2544
this.next();
2545
node.test = this.parseParenExpression();
2546
node.consequent = this.parseStatement(false);
2547
node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
2548
return this.finishNode(node, "IfStatement");
2549
};
2550
2551
pp.parseReturnStatement = function (node) {
2552
if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
2553
this.next();
2554
2555
// In `return` (and `break`/`continue`), the keywords with
2556
// optional arguments, we eagerly look for a semicolon or the
2557
// possibility to insert one.
2558
2559
if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null;else {
2560
node.argument = this.parseExpression();this.semicolon();
2561
}
2562
return this.finishNode(node, "ReturnStatement");
2563
};
2564
2565
pp.parseSwitchStatement = function (node) {
2566
this.next();
2567
node.discriminant = this.parseParenExpression();
2568
node.cases = [];
2569
this.expect(tt.braceL);
2570
this.labels.push(switchLabel);
2571
2572
// Statements under must be grouped (by label) in SwitchCase
2573
// nodes. `cur` is used to keep the node that we are currently
2574
// adding statements to.
2575
2576
for (var cur, sawDefault; this.type != tt.braceR;) {
2577
if (this.type === tt._case || this.type === tt._default) {
2578
var isCase = this.type === tt._case;
2579
if (cur) this.finishNode(cur, "SwitchCase");
2580
node.cases.push(cur = this.startNode());
2581
cur.consequent = [];
2582
this.next();
2583
if (isCase) {
2584
cur.test = this.parseExpression();
2585
} else {
2586
if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
2587
sawDefault = true;
2588
cur.test = null;
2589
}
2590
this.expect(tt.colon);
2591
} else {
2592
if (!cur) this.unexpected();
2593
cur.consequent.push(this.parseStatement(true));
2594
}
2595
}
2596
if (cur) this.finishNode(cur, "SwitchCase");
2597
this.next(); // Closing brace
2598
this.labels.pop();
2599
return this.finishNode(node, "SwitchStatement");
2600
};
2601
2602
pp.parseThrowStatement = function (node) {
2603
this.next();
2604
if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
2605
node.argument = this.parseExpression();
2606
this.semicolon();
2607
return this.finishNode(node, "ThrowStatement");
2608
};
2609
2610
// Reused empty array added for node fields that are always empty.
2611
2612
var empty = [];
2613
2614
pp.parseTryStatement = function (node) {
2615
this.next();
2616
node.block = this.parseBlock();
2617
node.handler = null;
2618
if (this.type === tt._catch) {
2619
var clause = this.startNode();
2620
this.next();
2621
this.expect(tt.parenL);
2622
clause.param = this.parseBindingAtom();
2623
this.checkLVal(clause.param, true);
2624
this.expect(tt.parenR);
2625
clause.guard = null;
2626
clause.body = this.parseBlock();
2627
node.handler = this.finishNode(clause, "CatchClause");
2628
}
2629
node.guardedHandlers = empty;
2630
node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
2631
if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
2632
return this.finishNode(node, "TryStatement");
2633
};
2634
2635
pp.parseVarStatement = function (node, kind) {
2636
this.next();
2637
this.parseVar(node, false, kind);
2638
this.semicolon();
2639
return this.finishNode(node, "VariableDeclaration");
2640
};
2641
2642
pp.parseWhileStatement = function (node) {
2643
this.next();
2644
node.test = this.parseParenExpression();
2645
this.labels.push(loopLabel);
2646
node.body = this.parseStatement(false);
2647
this.labels.pop();
2648
return this.finishNode(node, "WhileStatement");
2649
};
2650
2651
pp.parseWithStatement = function (node) {
2652
if (this.strict) this.raise(this.start, "'with' in strict mode");
2653
this.next();
2654
node.object = this.parseParenExpression();
2655
node.body = this.parseStatement(false);
2656
return this.finishNode(node, "WithStatement");
2657
};
2658
2659
pp.parseEmptyStatement = function (node) {
2660
this.next();
2661
return this.finishNode(node, "EmptyStatement");
2662
};
2663
2664
pp.parseLabeledStatement = function (node, maybeName, expr) {
2665
for (var i = 0; i < this.labels.length; ++i) {
2666
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
2667
}var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null;
2668
this.labels.push({ name: maybeName, kind: kind });
2669
node.body = this.parseStatement(true);
2670
this.labels.pop();
2671
node.label = expr;
2672
return this.finishNode(node, "LabeledStatement");
2673
};
2674
2675
pp.parseExpressionStatement = function (node, expr) {
2676
node.expression = expr;
2677
this.semicolon();
2678
return this.finishNode(node, "ExpressionStatement");
2679
};
2680
2681
// Parse a semicolon-enclosed block of statements, handling `"use
2682
// strict"` declarations when `allowStrict` is true (used for
2683
// function bodies).
2684
2685
pp.parseBlock = function (allowStrict) {
2686
var node = this.startNode(),
2687
first = true,
2688
oldStrict = undefined;
2689
node.body = [];
2690
this.expect(tt.braceL);
2691
while (!this.eat(tt.braceR)) {
2692
var stmt = this.parseStatement(true);
2693
node.body.push(stmt);
2694
if (first && allowStrict && this.isUseStrict(stmt)) {
2695
oldStrict = this.strict;
2696
this.setStrict(this.strict = true);
2697
}
2698
first = false;
2699
}
2700
if (oldStrict === false) this.setStrict(false);
2701
return this.finishNode(node, "BlockStatement");
2702
};
2703
2704
// Parse a regular `for` loop. The disambiguation code in
2705
// `parseStatement` will already have parsed the init statement or
2706
// expression.
2707
2708
pp.parseFor = function (node, init) {
2709
node.init = init;
2710
this.expect(tt.semi);
2711
node.test = this.type === tt.semi ? null : this.parseExpression();
2712
this.expect(tt.semi);
2713
node.update = this.type === tt.parenR ? null : this.parseExpression();
2714
this.expect(tt.parenR);
2715
node.body = this.parseStatement(false);
2716
this.labels.pop();
2717
return this.finishNode(node, "ForStatement");
2718
};
2719
2720
// Parse a `for`/`in` and `for`/`of` loop, which are almost
2721
// same from parser's perspective.
2722
2723
pp.parseForIn = function (node, init) {
2724
var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement";
2725
this.next();
2726
node.left = init;
2727
node.right = this.parseExpression();
2728
this.expect(tt.parenR);
2729
node.body = this.parseStatement(false);
2730
this.labels.pop();
2731
return this.finishNode(node, type);
2732
};
2733
2734
// Parse a list of variable declarations.
2735
2736
pp.parseVar = function (node, isFor, kind) {
2737
node.declarations = [];
2738
node.kind = kind.keyword;
2739
for (;;) {
2740
var decl = this.startNode();
2741
this.parseVarId(decl);
2742
if (this.eat(tt.eq)) {
2743
decl.init = this.parseMaybeAssign(isFor);
2744
} else if (kind === tt._const && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
2745
this.unexpected();
2746
} else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
2747
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
2748
} else {
2749
decl.init = null;
2750
}
2751
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
2752
if (!this.eat(tt.comma)) break;
2753
}
2754
return node;
2755
};
2756
2757
pp.parseVarId = function (decl) {
2758
decl.id = this.parseBindingAtom();
2759
this.checkLVal(decl.id, true);
2760
};
2761
2762
// Parse a function declaration or literal (depending on the
2763
// `isStatement` parameter).
2764
2765
pp.parseFunction = function (node, isStatement, allowExpressionBody) {
2766
this.initFunction(node);
2767
if (this.options.ecmaVersion >= 6) node.generator = this.eat(tt.star);
2768
if (isStatement || this.type === tt.name) node.id = this.parseIdent();
2769
this.parseFunctionParams(node);
2770
this.parseFunctionBody(node, allowExpressionBody);
2771
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
2772
};
2773
2774
pp.parseFunctionParams = function (node) {
2775
this.expect(tt.parenL);
2776
node.params = this.parseBindingList(tt.parenR, false, false);
2777
};
2778
2779
// Parse a class declaration or literal (depending on the
2780
// `isStatement` parameter).
2781
2782
pp.parseClass = function (node, isStatement) {
2783
this.next();
2784
this.parseClassId(node, isStatement);
2785
this.parseClassSuper(node);
2786
var classBody = this.startNode();
2787
var hadConstructor = false;
2788
classBody.body = [];
2789
this.expect(tt.braceL);
2790
while (!this.eat(tt.braceR)) {
2791
if (this.eat(tt.semi)) continue;
2792
var method = this.startNode();
2793
var isGenerator = this.eat(tt.star);
2794
var isMaybeStatic = this.type === tt.name && this.value === "static";
2795
this.parsePropertyName(method);
2796
method["static"] = isMaybeStatic && this.type !== tt.parenL;
2797
if (method["static"]) {
2798
if (isGenerator) this.unexpected();
2799
isGenerator = this.eat(tt.star);
2800
this.parsePropertyName(method);
2801
}
2802
method.kind = "method";
2803
if (!method.computed) {
2804
var key = method.key;
2805
2806
var isGetSet = false;
2807
if (!isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
2808
isGetSet = true;
2809
method.kind = key.name;
2810
key = this.parsePropertyName(method);
2811
}
2812
if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
2813
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
2814
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
2815
if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
2816
method.kind = "constructor";
2817
hadConstructor = true;
2818
}
2819
}
2820
this.parseClassMethod(classBody, method, isGenerator);
2821
}
2822
node.body = this.finishNode(classBody, "ClassBody");
2823
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
2824
};
2825
2826
pp.parseClassMethod = function (classBody, method, isGenerator) {
2827
method.value = this.parseMethod(isGenerator);
2828
classBody.body.push(this.finishNode(method, "MethodDefinition"));
2829
};
2830
2831
pp.parseClassId = function (node, isStatement) {
2832
node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
2833
};
2834
2835
pp.parseClassSuper = function (node) {
2836
node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
2837
};
2838
2839
// Parses module export declaration.
2840
2841
pp.parseExport = function (node) {
2842
this.next();
2843
// export * from '...'
2844
if (this.eat(tt.star)) {
2845
this.expectContextual("from");
2846
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2847
this.semicolon();
2848
return this.finishNode(node, "ExportAllDeclaration");
2849
}
2850
if (this.eat(tt._default)) {
2851
// export default ...
2852
var expr = this.parseMaybeAssign();
2853
var needsSemi = true;
2854
if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
2855
needsSemi = false;
2856
if (expr.id) {
2857
expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
2858
}
2859
}
2860
node.declaration = expr;
2861
if (needsSemi) this.semicolon();
2862
return this.finishNode(node, "ExportDefaultDeclaration");
2863
}
2864
// export var|const|let|function|class ...
2865
if (this.shouldParseExportStatement()) {
2866
node.declaration = this.parseStatement(true);
2867
node.specifiers = [];
2868
node.source = null;
2869
} else {
2870
// export { x, y as z } [from '...']
2871
node.declaration = null;
2872
node.specifiers = this.parseExportSpecifiers();
2873
if (this.eatContextual("from")) {
2874
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2875
} else {
2876
node.source = null;
2877
}
2878
this.semicolon();
2879
}
2880
return this.finishNode(node, "ExportNamedDeclaration");
2881
};
2882
2883
pp.shouldParseExportStatement = function () {
2884
return this.type.keyword;
2885
};
2886
2887
// Parses a comma-separated list of module exports.
2888
2889
pp.parseExportSpecifiers = function () {
2890
var nodes = [],
2891
first = true;
2892
// export { x, y as z } [from '...']
2893
this.expect(tt.braceL);
2894
while (!this.eat(tt.braceR)) {
2895
if (!first) {
2896
this.expect(tt.comma);
2897
if (this.afterTrailingComma(tt.braceR)) break;
2898
} else first = false;
2899
2900
var node = this.startNode();
2901
node.local = this.parseIdent(this.type === tt._default);
2902
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
2903
nodes.push(this.finishNode(node, "ExportSpecifier"));
2904
}
2905
return nodes;
2906
};
2907
2908
// Parses import declaration.
2909
2910
pp.parseImport = function (node) {
2911
this.next();
2912
// import '...'
2913
if (this.type === tt.string) {
2914
node.specifiers = empty;
2915
node.source = this.parseExprAtom();
2916
node.kind = "";
2917
} else {
2918
node.specifiers = this.parseImportSpecifiers();
2919
this.expectContextual("from");
2920
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2921
}
2922
this.semicolon();
2923
return this.finishNode(node, "ImportDeclaration");
2924
};
2925
2926
// Parses a comma-separated list of module imports.
2927
2928
pp.parseImportSpecifiers = function () {
2929
var nodes = [],
2930
first = true;
2931
if (this.type === tt.name) {
2932
// import defaultObj, { x, y as z } from '...'
2933
var node = this.startNode();
2934
node.local = this.parseIdent();
2935
this.checkLVal(node.local, true);
2936
nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
2937
if (!this.eat(tt.comma)) return nodes;
2938
}
2939
if (this.type === tt.star) {
2940
var node = this.startNode();
2941
this.next();
2942
this.expectContextual("as");
2943
node.local = this.parseIdent();
2944
this.checkLVal(node.local, true);
2945
nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
2946
return nodes;
2947
}
2948
this.expect(tt.braceL);
2949
while (!this.eat(tt.braceR)) {
2950
if (!first) {
2951
this.expect(tt.comma);
2952
if (this.afterTrailingComma(tt.braceR)) break;
2953
} else first = false;
2954
2955
var node = this.startNode();
2956
node.imported = this.parseIdent(true);
2957
node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
2958
this.checkLVal(node.local, true);
2959
nodes.push(this.finishNode(node, "ImportSpecifier"));
2960
}
2961
return nodes;
2962
};
2963
2964
},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){
2965
"use strict";
2966
2967
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
2968
2969
exports.__esModule = true;
2970
// The algorithm used to determine whether a regexp can appear at a
2971
// given point in the program is loosely based on sweet.js' approach.
2972
// See https://github.com/mozilla/sweet.js/wiki/design
2973
2974
var Parser = _dereq_("./state").Parser;
2975
2976
var tt = _dereq_("./tokentype").types;
2977
2978
var lineBreak = _dereq_("./whitespace").lineBreak;
2979
2980
var TokContext = exports.TokContext = function TokContext(token, isExpr, preserveSpace, override) {
2981
_classCallCheck(this, TokContext);
2982
2983
this.token = token;
2984
this.isExpr = isExpr;
2985
this.preserveSpace = preserveSpace;
2986
this.override = override;
2987
};
2988
2989
var types = {
2990
b_stat: new TokContext("{", false),
2991
b_expr: new TokContext("{", true),
2992
b_tmpl: new TokContext("${", true),
2993
p_stat: new TokContext("(", false),
2994
p_expr: new TokContext("(", true),
2995
q_tmpl: new TokContext("`", true, true, function (p) {
2996
return p.readTmplToken();
2997
}),
2998
f_expr: new TokContext("function", true)
2999
};
3000
3001
exports.types = types;
3002
var pp = Parser.prototype;
3003
3004
pp.initialContext = function () {
3005
return [types.b_stat];
3006
};
3007
3008
pp.braceIsBlock = function (prevType) {
3009
var parent = undefined;
3010
if (prevType === tt.colon && (parent = this.curContext()).token == "{") return !parent.isExpr;
3011
if (prevType === tt._return) return lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
3012
if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof) return true;
3013
if (prevType == tt.braceL) return this.curContext() === types.b_stat;
3014
return !this.exprAllowed;
3015
};
3016
3017
pp.updateContext = function (prevType) {
3018
var update = undefined,
3019
type = this.type;
3020
if (type.keyword && prevType == tt.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
3021
};
3022
3023
// Token-specific context update code
3024
3025
tt.parenR.updateContext = tt.braceR.updateContext = function () {
3026
if (this.context.length == 1) {
3027
this.exprAllowed = true;
3028
return;
3029
}
3030
var out = this.context.pop();
3031
if (out === types.b_stat && this.curContext() === types.f_expr) {
3032
this.context.pop();
3033
this.exprAllowed = false;
3034
} else if (out === types.b_tmpl) {
3035
this.exprAllowed = true;
3036
} else {
3037
this.exprAllowed = !out.isExpr;
3038
}
3039
};
3040
3041
tt.braceL.updateContext = function (prevType) {
3042
this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
3043
this.exprAllowed = true;
3044
};
3045
3046
tt.dollarBraceL.updateContext = function () {
3047
this.context.push(types.b_tmpl);
3048
this.exprAllowed = true;
3049
};
3050
3051
tt.parenL.updateContext = function (prevType) {
3052
var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
3053
this.context.push(statementParens ? types.p_stat : types.p_expr);
3054
this.exprAllowed = true;
3055
};
3056
3057
tt.incDec.updateContext = function () {};
3058
3059
tt._function.updateContext = function () {
3060
if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
3061
this.exprAllowed = false;
3062
};
3063
3064
tt.backQuote.updateContext = function () {
3065
if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
3066
this.exprAllowed = false;
3067
};
3068
3069
// tokExprAllowed stays unchanged
3070
3071
},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){
3072
"use strict";
3073
3074
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
3075
3076
exports.__esModule = true;
3077
3078
var _identifier = _dereq_("./identifier");
3079
3080
var isIdentifierStart = _identifier.isIdentifierStart;
3081
var isIdentifierChar = _identifier.isIdentifierChar;
3082
3083
var _tokentype = _dereq_("./tokentype");
3084
3085
var tt = _tokentype.types;
3086
var keywordTypes = _tokentype.keywords;
3087
3088
var Parser = _dereq_("./state").Parser;
3089
3090
var SourceLocation = _dereq_("./location").SourceLocation;
3091
3092
var _whitespace = _dereq_("./whitespace");
3093
3094
var lineBreak = _whitespace.lineBreak;
3095
var lineBreakG = _whitespace.lineBreakG;
3096
var isNewLine = _whitespace.isNewLine;
3097
var nonASCIIwhitespace = _whitespace.nonASCIIwhitespace;
3098
3099
// Object type used to represent tokens. Note that normally, tokens
3100
// simply exist as properties on the parser object. This is only
3101
// used for the onToken callback and the external tokenizer.
3102
3103
var Token = exports.Token = function Token(p) {
3104
_classCallCheck(this, Token);
3105
3106
this.type = p.type;
3107
this.value = p.value;
3108
this.start = p.start;
3109
this.end = p.end;
3110
if (p.options.locations) this.loc = new SourceLocation(p, p.startLoc, p.endLoc);
3111
if (p.options.ranges) this.range = [p.start, p.end];
3112
};
3113
3114
// ## Tokenizer
3115
3116
var pp = Parser.prototype;
3117
3118
// Are we running under Rhino?
3119
var isRhino = typeof Packages !== "undefined";
3120
3121
// Move to the next token
3122
3123
pp.next = function () {
3124
if (this.options.onToken) this.options.onToken(new Token(this));
3125
3126
this.lastTokEnd = this.end;
3127
this.lastTokStart = this.start;
3128
this.lastTokEndLoc = this.endLoc;
3129
this.lastTokStartLoc = this.startLoc;
3130
this.nextToken();
3131
};
3132
3133
pp.getToken = function () {
3134
this.next();
3135
return new Token(this);
3136
};
3137
3138
// If we're in an ES6 environment, make parsers iterable
3139
if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
3140
var self = this;
3141
return { next: function next() {
3142
var token = self.getToken();
3143
return {
3144
done: token.type === tt.eof,
3145
value: token
3146
};
3147
} };
3148
};
3149
3150
// Toggle strict mode. Re-reads the next number or string to please
3151
// pedantic tests (`"use strict"; 010;` should fail).
3152
3153
pp.setStrict = function (strict) {
3154
this.strict = strict;
3155
if (this.type !== tt.num && this.type !== tt.string) return;
3156
this.pos = this.start;
3157
if (this.options.locations) {
3158
while (this.pos < this.lineStart) {
3159
this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
3160
--this.curLine;
3161
}
3162
}
3163
this.nextToken();
3164
};
3165
3166
pp.curContext = function () {
3167
return this.context[this.context.length - 1];
3168
};
3169
3170
// Read a single token, updating the parser object's token-related
3171
// properties.
3172
3173
pp.nextToken = function () {
3174
var curContext = this.curContext();
3175
if (!curContext || !curContext.preserveSpace) this.skipSpace();
3176
3177
this.start = this.pos;
3178
if (this.options.locations) this.startLoc = this.curPosition();
3179
if (this.pos >= this.input.length) return this.finishToken(tt.eof);
3180
3181
if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
3182
};
3183
3184
pp.readToken = function (code) {
3185
// Identifier or keyword. '\uXXXX' sequences are allowed in
3186
// identifiers, so '\' also dispatches to that.
3187
if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
3188
3189
return this.getTokenFromCode(code);
3190
};
3191
3192
pp.fullCharCodeAtPos = function () {
3193
var code = this.input.charCodeAt(this.pos);
3194
if (code <= 55295 || code >= 57344) return code;
3195
var next = this.input.charCodeAt(this.pos + 1);
3196
return (code << 10) + next - 56613888;
3197
};
3198
3199
pp.skipBlockComment = function () {
3200
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
3201
var start = this.pos,
3202
end = this.input.indexOf("*/", this.pos += 2);
3203
if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
3204
this.pos = end + 2;
3205
if (this.options.locations) {
3206
lineBreakG.lastIndex = start;
3207
var match = undefined;
3208
while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
3209
++this.curLine;
3210
this.lineStart = match.index + match[0].length;
3211
}
3212
}
3213
if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.options.locations && this.curPosition());
3214
};
3215
3216
pp.skipLineComment = function (startSkip) {
3217
var start = this.pos;
3218
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
3219
var ch = this.input.charCodeAt(this.pos += startSkip);
3220
while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
3221
++this.pos;
3222
ch = this.input.charCodeAt(this.pos);
3223
}
3224
if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.options.locations && this.curPosition());
3225
};
3226
3227
// Called at the start of the parse and after every token. Skips
3228
// whitespace and comments, and.
3229
3230
pp.skipSpace = function () {
3231
while (this.pos < this.input.length) {
3232
var ch = this.input.charCodeAt(this.pos);
3233
if (ch === 32) {
3234
// ' '
3235
++this.pos;
3236
} else if (ch === 13) {
3237
++this.pos;
3238
var next = this.input.charCodeAt(this.pos);
3239
if (next === 10) {
3240
++this.pos;
3241
}
3242
if (this.options.locations) {
3243
++this.curLine;
3244
this.lineStart = this.pos;
3245
}
3246
} else if (ch === 10 || ch === 8232 || ch === 8233) {
3247
++this.pos;
3248
if (this.options.locations) {
3249
++this.curLine;
3250
this.lineStart = this.pos;
3251
}
3252
} else if (ch > 8 && ch < 14) {
3253
++this.pos;
3254
} else if (ch === 47) {
3255
// '/'
3256
var next = this.input.charCodeAt(this.pos + 1);
3257
if (next === 42) {
3258
// '*'
3259
this.skipBlockComment();
3260
} else if (next === 47) {
3261
// '/'
3262
this.skipLineComment(2);
3263
} else break;
3264
} else if (ch === 160) {
3265
// '\xa0'
3266
++this.pos;
3267
} else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
3268
++this.pos;
3269
} else {
3270
break;
3271
}
3272
}
3273
};
3274
3275
// Called at the end of every token. Sets `end`, `val`, and
3276
// maintains `context` and `exprAllowed`, and skips the space after
3277
// the token, so that the next one's `start` will point at the
3278
// right position.
3279
3280
pp.finishToken = function (type, val) {
3281
this.end = this.pos;
3282
if (this.options.locations) this.endLoc = this.curPosition();
3283
var prevType = this.type;
3284
this.type = type;
3285
this.value = val;
3286
3287
this.updateContext(prevType);
3288
};
3289
3290
// ### Token reading
3291
3292
// This is the function that is called to fetch the next token. It
3293
// is somewhat obscure, because it works in character codes rather
3294
// than characters, and because operator parsing has been inlined
3295
// into it.
3296
//
3297
// All in the name of speed.
3298
//
3299
pp.readToken_dot = function () {
3300
var next = this.input.charCodeAt(this.pos + 1);
3301
if (next >= 48 && next <= 57) return this.readNumber(true);
3302
var next2 = this.input.charCodeAt(this.pos + 2);
3303
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
3304
// 46 = dot '.'
3305
this.pos += 3;
3306
return this.finishToken(tt.ellipsis);
3307
} else {
3308
++this.pos;
3309
return this.finishToken(tt.dot);
3310
}
3311
};
3312
3313
pp.readToken_slash = function () {
3314
// '/'
3315
var next = this.input.charCodeAt(this.pos + 1);
3316
if (this.exprAllowed) {
3317
++this.pos;return this.readRegexp();
3318
}
3319
if (next === 61) return this.finishOp(tt.assign, 2);
3320
return this.finishOp(tt.slash, 1);
3321
};
3322
3323
pp.readToken_mult_modulo = function (code) {
3324
// '%*'
3325
var next = this.input.charCodeAt(this.pos + 1);
3326
if (next === 61) return this.finishOp(tt.assign, 2);
3327
return this.finishOp(code === 42 ? tt.star : tt.modulo, 1);
3328
};
3329
3330
pp.readToken_pipe_amp = function (code) {
3331
// '|&'
3332
var next = this.input.charCodeAt(this.pos + 1);
3333
if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
3334
if (next === 61) return this.finishOp(tt.assign, 2);
3335
return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
3336
};
3337
3338
pp.readToken_caret = function () {
3339
// '^'
3340
var next = this.input.charCodeAt(this.pos + 1);
3341
if (next === 61) return this.finishOp(tt.assign, 2);
3342
return this.finishOp(tt.bitwiseXOR, 1);
3343
};
3344
3345
pp.readToken_plus_min = function (code) {
3346
// '+-'
3347
var next = this.input.charCodeAt(this.pos + 1);
3348
if (next === code) {
3349
if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
3350
// A `-->` line comment
3351
this.skipLineComment(3);
3352
this.skipSpace();
3353
return this.nextToken();
3354
}
3355
return this.finishOp(tt.incDec, 2);
3356
}
3357
if (next === 61) return this.finishOp(tt.assign, 2);
3358
return this.finishOp(tt.plusMin, 1);
3359
};
3360
3361
pp.readToken_lt_gt = function (code) {
3362
// '<>'
3363
var next = this.input.charCodeAt(this.pos + 1);
3364
var size = 1;
3365
if (next === code) {
3366
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
3367
if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1);
3368
return this.finishOp(tt.bitShift, size);
3369
}
3370
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
3371
if (this.inModule) this.unexpected();
3372
// `<!--`, an XML-style comment that should be interpreted as a line comment
3373
this.skipLineComment(4);
3374
this.skipSpace();
3375
return this.nextToken();
3376
}
3377
if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
3378
return this.finishOp(tt.relational, size);
3379
};
3380
3381
pp.readToken_eq_excl = function (code) {
3382
// '=!'
3383
var next = this.input.charCodeAt(this.pos + 1);
3384
if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
3385
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
3386
// '=>'
3387
this.pos += 2;
3388
return this.finishToken(tt.arrow);
3389
}
3390
return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
3391
};
3392
3393
pp.getTokenFromCode = function (code) {
3394
switch (code) {
3395
// The interpretation of a dot depends on whether it is followed
3396
// by a digit or another two dots.
3397
case 46:
3398
// '.'
3399
return this.readToken_dot();
3400
3401
// Punctuation tokens.
3402
case 40:
3403
++this.pos;return this.finishToken(tt.parenL);
3404
case 41:
3405
++this.pos;return this.finishToken(tt.parenR);
3406
case 59:
3407
++this.pos;return this.finishToken(tt.semi);
3408
case 44:
3409
++this.pos;return this.finishToken(tt.comma);
3410
case 91:
3411
++this.pos;return this.finishToken(tt.bracketL);
3412
case 93:
3413
++this.pos;return this.finishToken(tt.bracketR);
3414
case 123:
3415
++this.pos;return this.finishToken(tt.braceL);
3416
case 125:
3417
++this.pos;return this.finishToken(tt.braceR);
3418
case 58:
3419
++this.pos;return this.finishToken(tt.colon);
3420
case 63:
3421
++this.pos;return this.finishToken(tt.question);
3422
3423
case 96:
3424
// '`'
3425
if (this.options.ecmaVersion < 6) break;
3426
++this.pos;
3427
return this.finishToken(tt.backQuote);
3428
3429
case 48:
3430
// '0'
3431
var next = this.input.charCodeAt(this.pos + 1);
3432
if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
3433
if (this.options.ecmaVersion >= 6) {
3434
if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
3435
if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
3436
}
3437
// Anything else beginning with a digit is an integer, octal
3438
// number, or float.
3439
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
3440
// 1-9
3441
return this.readNumber(false);
3442
3443
// Quotes produce strings.
3444
case 34:case 39:
3445
// '"', "'"
3446
return this.readString(code);
3447
3448
// Operators are parsed inline in tiny state machines. '=' (61) is
3449
// often referred to. `finishOp` simply skips the amount of
3450
// characters it is given as second argument, and returns a token
3451
// of the type given by its first argument.
3452
3453
case 47:
3454
// '/'
3455
return this.readToken_slash();
3456
3457
case 37:case 42:
3458
// '%*'
3459
return this.readToken_mult_modulo(code);
3460
3461
case 124:case 38:
3462
// '|&'
3463
return this.readToken_pipe_amp(code);
3464
3465
case 94:
3466
// '^'
3467
return this.readToken_caret();
3468
3469
case 43:case 45:
3470
// '+-'
3471
return this.readToken_plus_min(code);
3472
3473
case 60:case 62:
3474
// '<>'
3475
return this.readToken_lt_gt(code);
3476
3477
case 61:case 33:
3478
// '=!'
3479
return this.readToken_eq_excl(code);
3480
3481
case 126:
3482
// '~'
3483
return this.finishOp(tt.prefix, 1);
3484
}
3485
3486
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
3487
};
3488
3489
pp.finishOp = function (type, size) {
3490
var str = this.input.slice(this.pos, this.pos + size);
3491
this.pos += size;
3492
return this.finishToken(type, str);
3493
};
3494
3495
var regexpUnicodeSupport = false;
3496
try {
3497
new RegExp("￿", "u");regexpUnicodeSupport = true;
3498
} catch (e) {}
3499
3500
// Parse a regular expression. Some context-awareness is necessary,
3501
// since a '/' inside a '[]' set does not end the expression.
3502
3503
pp.readRegexp = function () {
3504
var escaped = undefined,
3505
inClass = undefined,
3506
start = this.pos;
3507
for (;;) {
3508
if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
3509
var ch = this.input.charAt(this.pos);
3510
if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
3511
if (!escaped) {
3512
if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
3513
escaped = ch === "\\";
3514
} else escaped = false;
3515
++this.pos;
3516
}
3517
var content = this.input.slice(start, this.pos);
3518
++this.pos;
3519
// Need to use `readWord1` because '\uXXXX' sequences are allowed
3520
// here (don't ask).
3521
var mods = this.readWord1();
3522
var tmp = content;
3523
if (mods) {
3524
var validFlags = /^[gmsiy]*$/;
3525
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
3526
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
3527
if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
3528
// Replace each astral symbol and every Unicode escape sequence that
3529
// possibly represents an astral symbol or a paired surrogate with a
3530
// single ASCII symbol to avoid throwing on regular expressions that
3531
// are only valid in combination with the `/u` flag.
3532
// Note: replacing with the ASCII symbol `x` might cause false
3533
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
3534
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
3535
// be replaced by `[x-b]` which throws an error.
3536
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
3537
}
3538
}
3539
// Detect invalid regular expressions.
3540
var value = null;
3541
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
3542
// so don't do detection if we are running under Rhino
3543
if (!isRhino) {
3544
try {
3545
new RegExp(tmp);
3546
} catch (e) {
3547
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message);
3548
this.raise(e);
3549
}
3550
// Get a regular expression object for this pattern-flag pair, or `null` in
3551
// case the current environment doesn't support the flags it uses.
3552
try {
3553
value = new RegExp(content, mods);
3554
} catch (err) {}
3555
}
3556
return this.finishToken(tt.regexp, { pattern: content, flags: mods, value: value });
3557
};
3558
3559
// Read an integer in the given radix. Return null if zero digits
3560
// were read, the integer value otherwise. When `len` is given, this
3561
// will return `null` unless the integer has exactly `len` digits.
3562
3563
pp.readInt = function (radix, len) {
3564
var start = this.pos,
3565
total = 0;
3566
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
3567
var code = this.input.charCodeAt(this.pos),
3568
val = undefined;
3569
if (code >= 97) val = code - 97 + 10; // a
3570
else if (code >= 65) val = code - 65 + 10; // A
3571
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
3572
else val = Infinity;
3573
if (val >= radix) break;
3574
++this.pos;
3575
total = total * radix + val;
3576
}
3577
if (this.pos === start || len != null && this.pos - start !== len) return null;
3578
3579
return total;
3580
};
3581
3582
pp.readRadixNumber = function (radix) {
3583
this.pos += 2; // 0x
3584
var val = this.readInt(radix);
3585
if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
3586
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
3587
return this.finishToken(tt.num, val);
3588
};
3589
3590
// Read an integer, octal integer, or floating-point number.
3591
3592
pp.readNumber = function (startsWithDot) {
3593
var start = this.pos,
3594
isFloat = false,
3595
octal = this.input.charCodeAt(this.pos) === 48;
3596
if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
3597
if (this.input.charCodeAt(this.pos) === 46) {
3598
++this.pos;
3599
this.readInt(10);
3600
isFloat = true;
3601
}
3602
var next = this.input.charCodeAt(this.pos);
3603
if (next === 69 || next === 101) {
3604
// 'eE'
3605
next = this.input.charCodeAt(++this.pos);
3606
if (next === 43 || next === 45) ++this.pos; // '+-'
3607
if (this.readInt(10) === null) this.raise(start, "Invalid number");
3608
isFloat = true;
3609
}
3610
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
3611
3612
var str = this.input.slice(start, this.pos),
3613
val = undefined;
3614
if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
3615
return this.finishToken(tt.num, val);
3616
};
3617
3618
// Read a string value, interpreting backslash-escapes.
3619
3620
pp.readCodePoint = function () {
3621
var ch = this.input.charCodeAt(this.pos),
3622
code = undefined;
3623
3624
if (ch === 123) {
3625
if (this.options.ecmaVersion < 6) this.unexpected();
3626
++this.pos;
3627
code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
3628
++this.pos;
3629
if (code > 1114111) this.unexpected();
3630
} else {
3631
code = this.readHexChar(4);
3632
}
3633
return code;
3634
};
3635
3636
function codePointToString(code) {
3637
// UTF-16 Decoding
3638
if (code <= 65535) {
3639
return String.fromCharCode(code);
3640
}return String.fromCharCode((code - 65536 >> 10) + 55296, (code - 65536 & 1023) + 56320);
3641
}
3642
3643
pp.readString = function (quote) {
3644
var out = "",
3645
chunkStart = ++this.pos;
3646
for (;;) {
3647
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
3648
var ch = this.input.charCodeAt(this.pos);
3649
if (ch === quote) break;
3650
if (ch === 92) {
3651
// '\'
3652
out += this.input.slice(chunkStart, this.pos);
3653
out += this.readEscapedChar();
3654
chunkStart = this.pos;
3655
} else {
3656
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
3657
++this.pos;
3658
}
3659
}
3660
out += this.input.slice(chunkStart, this.pos++);
3661
return this.finishToken(tt.string, out);
3662
};
3663
3664
// Reads template string tokens.
3665
3666
pp.readTmplToken = function () {
3667
var out = "",
3668
chunkStart = this.pos;
3669
for (;;) {
3670
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
3671
var ch = this.input.charCodeAt(this.pos);
3672
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
3673
// '`', '${'
3674
if (this.pos === this.start && this.type === tt.template) {
3675
if (ch === 36) {
3676
this.pos += 2;
3677
return this.finishToken(tt.dollarBraceL);
3678
} else {
3679
++this.pos;
3680
return this.finishToken(tt.backQuote);
3681
}
3682
}
3683
out += this.input.slice(chunkStart, this.pos);
3684
return this.finishToken(tt.template, out);
3685
}
3686
if (ch === 92) {
3687
// '\'
3688
out += this.input.slice(chunkStart, this.pos);
3689
out += this.readEscapedChar();
3690
chunkStart = this.pos;
3691
} else if (isNewLine(ch)) {
3692
out += this.input.slice(chunkStart, this.pos);
3693
++this.pos;
3694
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
3695
++this.pos;
3696
out += "\n";
3697
} else {
3698
out += String.fromCharCode(ch);
3699
}
3700
if (this.options.locations) {
3701
++this.curLine;
3702
this.lineStart = this.pos;
3703
}
3704
chunkStart = this.pos;
3705
} else {
3706
++this.pos;
3707
}
3708
}
3709
};
3710
3711
// Used to read escaped characters
3712
3713
pp.readEscapedChar = function () {
3714
var ch = this.input.charCodeAt(++this.pos);
3715
var octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3));
3716
if (octal) octal = octal[0];
3717
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
3718
if (octal === "0") octal = null;
3719
++this.pos;
3720
if (octal) {
3721
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode");
3722
this.pos += octal.length - 1;
3723
return String.fromCharCode(parseInt(octal, 8));
3724
} else {
3725
switch (ch) {
3726
case 110:
3727
return "\n"; // 'n' -> '\n'
3728
case 114:
3729
return "\r"; // 'r' -> '\r'
3730
case 120:
3731
return String.fromCharCode(this.readHexChar(2)); // 'x'
3732
case 117:
3733
return codePointToString(this.readCodePoint()); // 'u'
3734
case 116:
3735
return "\t"; // 't' -> '\t'
3736
case 98:
3737
return "\b"; // 'b' -> '\b'
3738
case 118:
3739
return "\u000b"; // 'v' -> '\u000b'
3740
case 102:
3741
return "\f"; // 'f' -> '\f'
3742
case 48:
3743
return "\u0000"; // 0 -> '\0'
3744
case 13:
3745
if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
3746
case 10:
3747
// ' \n'
3748
if (this.options.locations) {
3749
this.lineStart = this.pos;++this.curLine;
3750
}
3751
return "";
3752
default:
3753
return String.fromCharCode(ch);
3754
}
3755
}
3756
};
3757
3758
// Used to read character escape sequences ('\x', '\u', '\U').
3759
3760
pp.readHexChar = function (len) {
3761
var n = this.readInt(16, len);
3762
if (n === null) this.raise(this.start, "Bad character escape sequence");
3763
return n;
3764
};
3765
3766
// Used to signal to callers of `readWord1` whether the word
3767
// contained any escape sequences. This is needed because words with
3768
// escape sequences must not be interpreted as keywords.
3769
3770
var containsEsc;
3771
3772
// Read an identifier, and return it as a string. Sets `containsEsc`
3773
// to whether the word contained a '\u' escape.
3774
//
3775
// Incrementally adds only escaped chars, adding other chunks as-is
3776
// as a micro-optimization.
3777
3778
pp.readWord1 = function () {
3779
containsEsc = false;
3780
var word = "",
3781
first = true,
3782
chunkStart = this.pos;
3783
var astral = this.options.ecmaVersion >= 6;
3784
while (this.pos < this.input.length) {
3785
var ch = this.fullCharCodeAtPos();
3786
if (isIdentifierChar(ch, astral)) {
3787
this.pos += ch <= 65535 ? 1 : 2;
3788
} else if (ch === 92) {
3789
// "\"
3790
containsEsc = true;
3791
word += this.input.slice(chunkStart, this.pos);
3792
var escStart = this.pos;
3793
if (this.input.charCodeAt(++this.pos) != 117) // "u"
3794
this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
3795
++this.pos;
3796
var esc = this.readCodePoint();
3797
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
3798
word += codePointToString(esc);
3799
chunkStart = this.pos;
3800
} else {
3801
break;
3802
}
3803
first = false;
3804
}
3805
return word + this.input.slice(chunkStart, this.pos);
3806
};
3807
3808
// Read an identifier or keyword token. Will check for reserved
3809
// words when necessary.
3810
3811
pp.readWord = function () {
3812
var word = this.readWord1();
3813
var type = tt.name;
3814
if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = keywordTypes[word];
3815
return this.finishToken(type, word);
3816
};
3817
3818
},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){
3819
"use strict";
3820
3821
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
3822
3823
exports.__esModule = true;
3824
// ## Token types
3825
3826
// The assignment of fine-grained, information-carrying type objects
3827
// allows the tokenizer to store the information it has about a
3828
// token in a way that is very cheap for the parser to look up.
3829
3830
// All token type variables start with an underscore, to make them
3831
// easy to recognize.
3832
3833
// The `beforeExpr` property is used to disambiguate between regular
3834
// expressions and divisions. It is set on all token types that can
3835
// be followed by an expression (thus, a slash after them would be a
3836
// regular expression).
3837
//
3838
// `isLoop` marks a keyword as starting a loop, which is important
3839
// to know when parsing a label, in order to allow or disallow
3840
// continue jumps to that label.
3841
3842
var TokenType = exports.TokenType = function TokenType(label) {
3843
var conf = arguments[1] === undefined ? {} : arguments[1];
3844
3845
_classCallCheck(this, TokenType);
3846
3847
this.label = label;
3848
this.keyword = conf.keyword;
3849
this.beforeExpr = !!conf.beforeExpr;
3850
this.startsExpr = !!conf.startsExpr;
3851
this.isLoop = !!conf.isLoop;
3852
this.isAssign = !!conf.isAssign;
3853
this.prefix = !!conf.prefix;
3854
this.postfix = !!conf.postfix;
3855
this.binop = conf.binop || null;
3856
this.updateContext = null;
3857
};
3858
3859
function binop(name, prec) {
3860
return new TokenType(name, { beforeExpr: true, binop: prec });
3861
}
3862
var beforeExpr = { beforeExpr: true },
3863
startsExpr = { startsExpr: true };
3864
3865
var types = {
3866
num: new TokenType("num", startsExpr),
3867
regexp: new TokenType("regexp", startsExpr),
3868
string: new TokenType("string", startsExpr),
3869
name: new TokenType("name", startsExpr),
3870
eof: new TokenType("eof"),
3871
3872
// Punctuation token types.
3873
bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
3874
bracketR: new TokenType("]"),
3875
braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
3876
braceR: new TokenType("}"),
3877
parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
3878
parenR: new TokenType(")"),
3879
comma: new TokenType(",", beforeExpr),
3880
semi: new TokenType(";", beforeExpr),
3881
colon: new TokenType(":", beforeExpr),
3882
dot: new TokenType("."),
3883
question: new TokenType("?", beforeExpr),
3884
arrow: new TokenType("=>", beforeExpr),
3885
template: new TokenType("template"),
3886
ellipsis: new TokenType("...", beforeExpr),
3887
backQuote: new TokenType("`", startsExpr),
3888
dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
3889
3890
// Operators. These carry several kinds of properties to help the
3891
// parser use them properly (the presence of these properties is
3892
// what categorizes them as operators).
3893
//
3894
// `binop`, when present, specifies that this operator is a binary
3895
// operator, and will refer to its precedence.
3896
//
3897
// `prefix` and `postfix` mark the operator as a prefix or postfix
3898
// unary operator.
3899
//
3900
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
3901
// binary operators with a very low precedence, that should result
3902
// in AssignmentExpression nodes.
3903
3904
eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
3905
assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
3906
incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
3907
prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
3908
logicalOR: binop("||", 1),
3909
logicalAND: binop("&&", 2),
3910
bitwiseOR: binop("|", 3),
3911
bitwiseXOR: binop("^", 4),
3912
bitwiseAND: binop("&", 5),
3913
equality: binop("==/!=", 6),
3914
relational: binop("</>", 7),
3915
bitShift: binop("<</>>", 8),
3916
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
3917
modulo: binop("%", 10),
3918
star: binop("*", 10),
3919
slash: binop("/", 10)
3920
};
3921
3922
exports.types = types;
3923
// Map keyword names to token types.
3924
3925
var keywords = {};
3926
3927
exports.keywords = keywords;
3928
// Succinct definitions of keyword token types
3929
function kw(name) {
3930
var options = arguments[1] === undefined ? {} : arguments[1];
3931
3932
options.keyword = name;
3933
keywords[name] = types["_" + name] = new TokenType(name, options);
3934
}
3935
3936
kw("break");
3937
kw("case", beforeExpr);
3938
kw("catch");
3939
kw("continue");
3940
kw("debugger");
3941
kw("default");
3942
kw("do", { isLoop: true });
3943
kw("else", beforeExpr);
3944
kw("finally");
3945
kw("for", { isLoop: true });
3946
kw("function", startsExpr);
3947
kw("if");
3948
kw("return", beforeExpr);
3949
kw("switch");
3950
kw("throw", beforeExpr);
3951
kw("try");
3952
kw("var");
3953
kw("let");
3954
kw("const");
3955
kw("while", { isLoop: true });
3956
kw("with");
3957
kw("new", { beforeExpr: true, startsExpr: true });
3958
kw("this", startsExpr);
3959
kw("super", startsExpr);
3960
kw("class");
3961
kw("extends", beforeExpr);
3962
kw("export");
3963
kw("import");
3964
kw("yield", { beforeExpr: true, startsExpr: true });
3965
kw("null", startsExpr);
3966
kw("true", startsExpr);
3967
kw("false", startsExpr);
3968
kw("in", { beforeExpr: true, binop: 7 });
3969
kw("instanceof", { beforeExpr: true, binop: 7 });
3970
kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
3971
kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
3972
kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
3973
3974
},{}],18:[function(_dereq_,module,exports){
3975
"use strict";
3976
3977
exports.isArray = isArray;
3978
3979
// Checks if an object has a property.
3980
3981
exports.has = has;
3982
exports.__esModule = true;
3983
3984
function isArray(obj) {
3985
return Object.prototype.toString.call(obj) === "[object Array]";
3986
}
3987
3988
function has(obj, propName) {
3989
return Object.prototype.hasOwnProperty.call(obj, propName);
3990
}
3991
3992
},{}],19:[function(_dereq_,module,exports){
3993
"use strict";
3994
3995
exports.isNewLine = isNewLine;
3996
exports.__esModule = true;
3997
// Matches a whole line break (where CRLF is considered a single
3998
// line break). Used to count lines.
3999
4000
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
4001
exports.lineBreak = lineBreak;
4002
var lineBreakG = new RegExp(lineBreak.source, "g");
4003
4004
exports.lineBreakG = lineBreakG;
4005
4006
function isNewLine(code) {
4007
return code === 10 || code === 13 || code === 8232 || code == 8233;
4008
}
4009
4010
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
4011
exports.nonASCIIwhitespace = nonASCIIwhitespace;
4012
4013
},{}]},{},[1])(1)
4014
});
4015