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
// Removed to create an eval-free library
1535
1536
// Reserved word lists for various dialects of the language
1537
1538
var reservedWords = {
1539
3: function anonymous(str) {
1540
switch(str.length){case 6:switch(str){case "double":case "export":case "import":case "native":case "public":case "static":case "throws":return true}return false;case 4:switch(str){case "byte":case "char":case "enum":case "goto":case "long":return true}return false;case 5:switch(str){case "class":case "final":case "float":case "short":case "super":return true}return false;case 7:switch(str){case "boolean":case "extends":case "package":case "private":return true}return false;case 9:switch(str){case "interface":case "protected":case "transient":return true}return false;case 8:switch(str){case "abstract":case "volatile":return true}return false;case 10:return str === "implements";case 3:return str === "int";case 12:return str === "synchronized";}
1541
},
1542
5: function anonymous(str) {
1543
switch(str.length){case 5:switch(str){case "class":case "super":case "const":return true}return false;case 6:switch(str){case "export":case "import":return true}return false;case 4:return str === "enum";case 7:return str === "extends";}
1544
},
1545
6: function anonymous(str) {
1546
switch(str){case "enum":case "await":return true}return false;
1547
},
1548
strict: function anonymous(str) {
1549
switch(str.length){case 9:switch(str){case "interface":case "protected":return true}return false;case 7:switch(str){case "package":case "private":return true}return false;case 6:switch(str){case "public":case "static":return true}return false;case 10:return str === "implements";case 3:return str === "let";case 5:return str === "yield";}
1550
},
1551
strictBind: function anonymous(str) {
1552
switch(str){case "eval":case "arguments":return true}return false;
1553
}
1554
};
1555
1556
exports.reservedWords = reservedWords;
1557
// And the keywords
1558
1559
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";
1560
1561
var keywords = {
1562
5: function anonymous(str) {
1563
switch(str.length){case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 7:switch(str){case "default":case "finally":return true}return false;case 10:return str === "instanceof";}
1564
},
1565
6: function anonymous(str) {
1566
switch(str.length){case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":case "const":case "class":case "yield":case "super":return true}return false;case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":case "export":case "import":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":case "let":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 7:switch(str){case "default":case "finally":case "extends":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 10:return str === "instanceof";}
1567
}
1568
};
1569
1570
exports.keywords = keywords;
1571
// ## Character categories
1572
1573
// Big ugly regular expressions that match characters in the
1574
// whitespace, identifier, and identifier-start categories. These
1575
// are only applied when a character is found to actually have a
1576
// code point above 128.
1577
// Generated by `tools/generate-identifier-regex.js`.
1578
1579
var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
1580
var nonASCIIidentifierChars = "‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
1581
1582
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
1583
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
1584
1585
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
1586
1587
// These are a run-length and offset encoded representation of the
1588
// >0xffff code points that are a valid part of identifiers. The
1589
// offset starts at 0x10000, and each pair of numbers represents an
1590
// offset to the next range, and then a size of the range. They were
1591
// generated by tools/generate-identifier-regex.js
1592
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];
1593
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];
1594
1595
// This has a complexity linear to the value of the code. The
1596
// assumption is that looking up astral identifier characters is
1597
// rare.
1598
function isInAstralSet(code, set) {
1599
var pos = 65536;
1600
for (var i = 0; i < set.length; i += 2) {
1601
pos += set[i];
1602
if (pos > code) {
1603
return false;
1604
}pos += set[i + 1];
1605
if (pos >= code) {
1606
return true;
1607
}
1608
}
1609
}
1610
function isIdentifierStart(code, astral) {
1611
if (code < 65) {
1612
return code === 36;
1613
}if (code < 91) {
1614
return true;
1615
}if (code < 97) {
1616
return code === 95;
1617
}if (code < 123) {
1618
return true;
1619
}if (code <= 65535) {
1620
return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
1621
}if (astral === false) {
1622
return false;
1623
}return isInAstralSet(code, astralIdentifierStartCodes);
1624
}
1625
1626
function isIdentifierChar(code, astral) {
1627
if (code < 48) {
1628
return code === 36;
1629
}if (code < 58) {
1630
return true;
1631
}if (code < 65) {
1632
return false;
1633
}if (code < 91) {
1634
return true;
1635
}if (code < 97) {
1636
return code === 95;
1637
}if (code < 123) {
1638
return true;
1639
}if (code <= 65535) {
1640
return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
1641
}if (astral === false) {
1642
return false;
1643
}return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
1644
}
1645
1646
},{}],8:[function(_dereq_,module,exports){
1647
"use strict";
1648
1649
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
1650
1651
// The `getLineInfo` function is mostly useful when the
1652
// `locations` option is off (for performance reasons) and you
1653
// want to find the line/column position for a given character
1654
// offset. `input` should be the code string that the offset refers
1655
// into.
1656
1657
exports.getLineInfo = getLineInfo;
1658
exports.__esModule = true;
1659
1660
var Parser = _dereq_("./state").Parser;
1661
1662
var lineBreakG = _dereq_("./whitespace").lineBreakG;
1663
1664
var deprecate = _dereq_("util").deprecate;
1665
1666
// These are used when `options.locations` is on, for the
1667
// `startLoc` and `endLoc` properties.
1668
1669
var Position = exports.Position = (function () {
1670
function Position(line, col) {
1671
_classCallCheck(this, Position);
1672
1673
this.line = line;
1674
this.column = col;
1675
}
1676
1677
Position.prototype.offset = function offset(n) {
1678
return new Position(this.line, this.column + n);
1679
};
1680
1681
return Position;
1682
})();
1683
1684
var SourceLocation = exports.SourceLocation = function SourceLocation(p, start, end) {
1685
_classCallCheck(this, SourceLocation);
1686
1687
this.start = start;
1688
this.end = end;
1689
if (p.sourceFile !== null) this.source = p.sourceFile;
1690
};
1691
1692
function getLineInfo(input, offset) {
1693
for (var line = 1, cur = 0;;) {
1694
lineBreakG.lastIndex = cur;
1695
var match = lineBreakG.exec(input);
1696
if (match && match.index < offset) {
1697
++line;
1698
cur = match.index + match[0].length;
1699
} else {
1700
return new Position(line, offset - cur);
1701
}
1702
}
1703
}
1704
1705
var pp = Parser.prototype;
1706
1707
// This function is used to raise exceptions on parse errors. It
1708
// takes an offset integer (into the current `input`) to indicate
1709
// the location of the error, attaches the position to the end
1710
// of the error message, and then raises a `SyntaxError` with that
1711
// message.
1712
1713
pp.raise = function (pos, message) {
1714
var loc = getLineInfo(this.input, pos);
1715
message += " (" + loc.line + ":" + loc.column + ")";
1716
var err = new SyntaxError(message);
1717
err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
1718
throw err;
1719
};
1720
1721
pp.curPosition = function () {
1722
return new Position(this.curLine, this.pos - this.lineStart);
1723
};
1724
1725
pp.markPosition = function () {
1726
return this.options.locations ? [this.start, this.startLoc] : this.start;
1727
};
1728
1729
},{"./state":13,"./whitespace":19,"util":5}],9:[function(_dereq_,module,exports){
1730
"use strict";
1731
1732
var tt = _dereq_("./tokentype").types;
1733
1734
var Parser = _dereq_("./state").Parser;
1735
1736
var reservedWords = _dereq_("./identifier").reservedWords;
1737
1738
var has = _dereq_("./util").has;
1739
1740
var pp = Parser.prototype;
1741
1742
// Convert existing expression atom to assignable pattern
1743
// if possible.
1744
1745
pp.toAssignable = function (node, isBinding) {
1746
if (this.options.ecmaVersion >= 6 && node) {
1747
switch (node.type) {
1748
case "Identifier":
1749
case "ObjectPattern":
1750
case "ArrayPattern":
1751
case "AssignmentPattern":
1752
break;
1753
1754
case "ObjectExpression":
1755
node.type = "ObjectPattern";
1756
for (var i = 0; i < node.properties.length; i++) {
1757
var prop = node.properties[i];
1758
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
1759
this.toAssignable(prop.value, isBinding);
1760
}
1761
break;
1762
1763
case "ArrayExpression":
1764
node.type = "ArrayPattern";
1765
this.toAssignableList(node.elements, isBinding);
1766
break;
1767
1768
case "AssignmentExpression":
1769
if (node.operator === "=") {
1770
node.type = "AssignmentPattern";
1771
} else {
1772
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
1773
}
1774
break;
1775
1776
case "ParenthesizedExpression":
1777
node.expression = this.toAssignable(node.expression, isBinding);
1778
break;
1779
1780
case "MemberExpression":
1781
if (!isBinding) break;
1782
1783
default:
1784
this.raise(node.start, "Assigning to rvalue");
1785
}
1786
}
1787
return node;
1788
};
1789
1790
// Convert list of expression atoms to binding list.
1791
1792
pp.toAssignableList = function (exprList, isBinding) {
1793
var end = exprList.length;
1794
if (end) {
1795
var last = exprList[end - 1];
1796
if (last && last.type == "RestElement") {
1797
--end;
1798
} else if (last && last.type == "SpreadElement") {
1799
last.type = "RestElement";
1800
var arg = last.argument;
1801
this.toAssignable(arg, isBinding);
1802
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
1803
--end;
1804
}
1805
}
1806
for (var i = 0; i < end; i++) {
1807
var elt = exprList[i];
1808
if (elt) this.toAssignable(elt, isBinding);
1809
}
1810
return exprList;
1811
};
1812
1813
// Parses spread element.
1814
1815
pp.parseSpread = function (refShorthandDefaultPos) {
1816
var node = this.startNode();
1817
this.next();
1818
node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
1819
return this.finishNode(node, "SpreadElement");
1820
};
1821
1822
pp.parseRest = function () {
1823
var node = this.startNode();
1824
this.next();
1825
node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected();
1826
return this.finishNode(node, "RestElement");
1827
};
1828
1829
// Parses lvalue (assignable) atom.
1830
1831
pp.parseBindingAtom = function () {
1832
if (this.options.ecmaVersion < 6) return this.parseIdent();
1833
switch (this.type) {
1834
case tt.name:
1835
return this.parseIdent();
1836
1837
case tt.bracketL:
1838
var node = this.startNode();
1839
this.next();
1840
node.elements = this.parseBindingList(tt.bracketR, true, true);
1841
return this.finishNode(node, "ArrayPattern");
1842
1843
case tt.braceL:
1844
return this.parseObj(true);
1845
1846
default:
1847
this.unexpected();
1848
}
1849
};
1850
1851
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
1852
var elts = [],
1853
first = true;
1854
while (!this.eat(close)) {
1855
if (first) first = false;else this.expect(tt.comma);
1856
if (allowEmpty && this.type === tt.comma) {
1857
elts.push(null);
1858
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
1859
break;
1860
} else if (this.type === tt.ellipsis) {
1861
var rest = this.parseRest();
1862
this.parseBindingListItem(rest);
1863
elts.push(rest);
1864
this.expect(close);
1865
break;
1866
} else {
1867
var elem = this.parseMaybeDefault(this.start, this.startLoc);
1868
this.parseBindingListItem(elem);
1869
elts.push(elem);
1870
}
1871
}
1872
return elts;
1873
};
1874
1875
pp.parseBindingListItem = function (param) {
1876
return param;
1877
};
1878
1879
// Parses assignment pattern around given atom if possible.
1880
1881
pp.parseMaybeDefault = function (startPos, startLoc, left) {
1882
if (Array.isArray(startPos)) {
1883
if (this.options.locations && noCalls === undefined) {
1884
// shift arguments to left by one
1885
left = startLoc;
1886
// flatten startPos
1887
startLoc = startPos[1];
1888
startPos = startPos[0];
1889
}
1890
}
1891
left = left || this.parseBindingAtom();
1892
if (!this.eat(tt.eq)) return left;
1893
var node = this.startNodeAt(startPos, startLoc);
1894
node.operator = "=";
1895
node.left = left;
1896
node.right = this.parseMaybeAssign();
1897
return this.finishNode(node, "AssignmentPattern");
1898
};
1899
1900
// Verify that a node is an lval — something that can be assigned
1901
// to.
1902
1903
pp.checkLVal = function (expr, isBinding, checkClashes) {
1904
switch (expr.type) {
1905
case "Identifier":
1906
if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
1907
if (checkClashes) {
1908
if (has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
1909
checkClashes[expr.name] = true;
1910
}
1911
break;
1912
1913
case "MemberExpression":
1914
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
1915
break;
1916
1917
case "ObjectPattern":
1918
for (var i = 0; i < expr.properties.length; i++) {
1919
this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
1920
}break;
1921
1922
case "ArrayPattern":
1923
for (var i = 0; i < expr.elements.length; i++) {
1924
var elem = expr.elements[i];
1925
if (elem) this.checkLVal(elem, isBinding, checkClashes);
1926
}
1927
break;
1928
1929
case "AssignmentPattern":
1930
this.checkLVal(expr.left, isBinding, checkClashes);
1931
break;
1932
1933
case "RestElement":
1934
this.checkLVal(expr.argument, isBinding, checkClashes);
1935
break;
1936
1937
case "ParenthesizedExpression":
1938
this.checkLVal(expr.expression, isBinding, checkClashes);
1939
break;
1940
1941
default:
1942
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
1943
}
1944
};
1945
1946
},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],10:[function(_dereq_,module,exports){
1947
"use strict";
1948
1949
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
1950
1951
exports.__esModule = true;
1952
1953
var Parser = _dereq_("./state").Parser;
1954
1955
var SourceLocation = _dereq_("./location").SourceLocation;
1956
1957
// Start an AST node, attaching a start offset.
1958
1959
var pp = Parser.prototype;
1960
1961
var Node = exports.Node = function Node() {
1962
_classCallCheck(this, Node);
1963
};
1964
1965
pp.startNode = function () {
1966
var node = new Node();
1967
node.start = this.start;
1968
if (this.options.locations) node.loc = new SourceLocation(this, this.startLoc);
1969
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
1970
if (this.options.ranges) node.range = [this.start, 0];
1971
return node;
1972
};
1973
1974
pp.startNodeAt = function (pos, loc) {
1975
var node = new Node();
1976
if (Array.isArray(pos)) {
1977
if (this.options.locations && loc === undefined) {
1978
// flatten pos
1979
loc = pos[1];
1980
pos = pos[0];
1981
}
1982
}
1983
node.start = pos;
1984
if (this.options.locations) node.loc = new SourceLocation(this, loc);
1985
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
1986
if (this.options.ranges) node.range = [pos, 0];
1987
return node;
1988
};
1989
1990
// Finish an AST node, adding `type` and `end` properties.
1991
1992
pp.finishNode = function (node, type) {
1993
node.type = type;
1994
node.end = this.lastTokEnd;
1995
if (this.options.locations) node.loc.end = this.lastTokEndLoc;
1996
if (this.options.ranges) node.range[1] = this.lastTokEnd;
1997
return node;
1998
};
1999
2000
// Finish node at given position
2001
2002
pp.finishNodeAt = function (node, type, pos, loc) {
2003
node.type = type;
2004
if (Array.isArray(pos)) {
2005
if (this.options.locations && loc === undefined) {
2006
// flatten pos
2007
loc = pos[1];
2008
pos = pos[0];
2009
}
2010
}
2011
node.end = pos;
2012
if (this.options.locations) node.loc.end = loc;
2013
if (this.options.ranges) node.range[1] = pos;
2014
return node;
2015
};
2016
2017
},{"./location":8,"./state":13}],11:[function(_dereq_,module,exports){
2018
2019
2020
// Interpret and default an options object
2021
2022
"use strict";
2023
2024
exports.getOptions = getOptions;
2025
exports.__esModule = true;
2026
2027
var _util = _dereq_("./util");
2028
2029
var has = _util.has;
2030
var isArray = _util.isArray;
2031
2032
var SourceLocation = _dereq_("./location").SourceLocation;
2033
2034
// A second optional argument can be given to further configure
2035
// the parser process. These options are recognized:
2036
2037
var defaultOptions = {
2038
// `ecmaVersion` indicates the ECMAScript version to parse. Must
2039
// be either 3, or 5, or 6. This influences support for strict
2040
// mode, the set of reserved words, support for getters and
2041
// setters and other features.
2042
ecmaVersion: 5,
2043
// Source type ("script" or "module") for different semantics
2044
sourceType: "script",
2045
// `onInsertedSemicolon` can be a callback that will be called
2046
// when a semicolon is automatically inserted. It will be passed
2047
// th position of the comma as an offset, and if `locations` is
2048
// enabled, it is given the location as a `{line, column}` object
2049
// as second argument.
2050
onInsertedSemicolon: null,
2051
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
2052
// trailing commas.
2053
onTrailingComma: null,
2054
// By default, reserved words are not enforced. Disable
2055
// `allowReserved` to enforce them. When this option has the
2056
// value "never", reserved words and keywords can also not be
2057
// used as property names.
2058
allowReserved: true,
2059
// When enabled, a return at the top level is not considered an
2060
// error.
2061
allowReturnOutsideFunction: false,
2062
// When enabled, import/export statements are not constrained to
2063
// appearing at the top of the program.
2064
allowImportExportEverywhere: false,
2065
// When enabled, hashbang directive in the beginning of file
2066
// is allowed and treated as a line comment.
2067
allowHashBang: false,
2068
// When `locations` is on, `loc` properties holding objects with
2069
// `start` and `end` properties in `{line, column}` form (with
2070
// line being 1-based and column 0-based) will be attached to the
2071
// nodes.
2072
locations: false,
2073
// A function can be passed as `onToken` option, which will
2074
// cause Acorn to call that function with object in the same
2075
// format as tokenize() returns. Note that you are not
2076
// allowed to call the parser from the callback—that will
2077
// corrupt its internal state.
2078
onToken: null,
2079
// A function can be passed as `onComment` option, which will
2080
// cause Acorn to call that function with `(block, text, start,
2081
// end)` parameters whenever a comment is skipped. `block` is a
2082
// boolean indicating whether this is a block (`/* */`) comment,
2083
// `text` is the content of the comment, and `start` and `end` are
2084
// character offsets that denote the start and end of the comment.
2085
// When the `locations` option is on, two more parameters are
2086
// passed, the full `{line, column}` locations of the start and
2087
// end of the comments. Note that you are not allowed to call the
2088
// parser from the callback—that will corrupt its internal state.
2089
onComment: null,
2090
// Nodes have their start and end characters offsets recorded in
2091
// `start` and `end` properties (directly on the node, rather than
2092
// the `loc` object, which holds line/column data. To also add a
2093
// [semi-standardized][range] `range` property holding a `[start,
2094
// end]` array with the same numbers, set the `ranges` option to
2095
// `true`.
2096
//
2097
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
2098
ranges: false,
2099
// It is possible to parse multiple files into a single AST by
2100
// passing the tree produced by parsing the first file as
2101
// `program` option in subsequent parses. This will add the
2102
// toplevel forms of the parsed file to the `Program` (top) node
2103
// of an existing parse tree.
2104
program: null,
2105
// When `locations` is on, you can pass this to record the source
2106
// file in every node's `loc` object.
2107
sourceFile: null,
2108
// This value, if given, is stored in every node, whether
2109
// `locations` is on or off.
2110
directSourceFile: null,
2111
// When enabled, parenthesized expressions are represented by
2112
// (non-standard) ParenthesizedExpression nodes
2113
preserveParens: false,
2114
plugins: {}
2115
};exports.defaultOptions = defaultOptions;
2116
2117
function getOptions(opts) {
2118
var options = {};
2119
for (var opt in defaultOptions) {
2120
options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt];
2121
}if (isArray(options.onToken)) {
2122
(function () {
2123
var tokens = options.onToken;
2124
options.onToken = function (token) {
2125
return tokens.push(token);
2126
};
2127
})();
2128
}
2129
if (isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
2130
2131
return options;
2132
}
2133
2134
function pushComment(options, array) {
2135
return function (block, text, start, end, startLoc, endLoc) {
2136
var comment = {
2137
type: block ? "Block" : "Line",
2138
value: text,
2139
start: start,
2140
end: end
2141
};
2142
if (options.locations) comment.loc = new SourceLocation(this, startLoc, endLoc);
2143
if (options.ranges) comment.range = [start, end];
2144
array.push(comment);
2145
};
2146
}
2147
2148
},{"./location":8,"./util":18}],12:[function(_dereq_,module,exports){
2149
"use strict";
2150
2151
var tt = _dereq_("./tokentype").types;
2152
2153
var Parser = _dereq_("./state").Parser;
2154
2155
var lineBreak = _dereq_("./whitespace").lineBreak;
2156
2157
var pp = Parser.prototype;
2158
2159
// ## Parser utilities
2160
2161
// Test whether a statement node is the string literal `"use strict"`.
2162
2163
pp.isUseStrict = function (stmt) {
2164
return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
2165
};
2166
2167
// Predicate that tests whether the next token is of the given
2168
// type, and if yes, consumes it as a side effect.
2169
2170
pp.eat = function (type) {
2171
if (this.type === type) {
2172
this.next();
2173
return true;
2174
} else {
2175
return false;
2176
}
2177
};
2178
2179
// Tests whether parsed token is a contextual keyword.
2180
2181
pp.isContextual = function (name) {
2182
return this.type === tt.name && this.value === name;
2183
};
2184
2185
// Consumes contextual keyword if possible.
2186
2187
pp.eatContextual = function (name) {
2188
return this.value === name && this.eat(tt.name);
2189
};
2190
2191
// Asserts that following token is given contextual keyword.
2192
2193
pp.expectContextual = function (name) {
2194
if (!this.eatContextual(name)) this.unexpected();
2195
};
2196
2197
// Test whether a semicolon can be inserted at the current position.
2198
2199
pp.canInsertSemicolon = function () {
2200
return this.type === tt.eof || this.type === tt.braceR || lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
2201
};
2202
2203
pp.insertSemicolon = function () {
2204
if (this.canInsertSemicolon()) {
2205
if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
2206
return true;
2207
}
2208
};
2209
2210
// Consume a semicolon, or, failing that, see if we are allowed to
2211
// pretend that there is a semicolon at this position.
2212
2213
pp.semicolon = function () {
2214
if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected();
2215
};
2216
2217
pp.afterTrailingComma = function (tokType) {
2218
if (this.type == tokType) {
2219
if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
2220
this.next();
2221
return true;
2222
}
2223
};
2224
2225
// Expect a token of a given type. If found, consume it, otherwise,
2226
// raise an unexpected token error.
2227
2228
pp.expect = function (type) {
2229
this.eat(type) || this.unexpected();
2230
};
2231
2232
// Raise an unexpected token error.
2233
2234
pp.unexpected = function (pos) {
2235
this.raise(pos != null ? pos : this.start, "Unexpected token");
2236
};
2237
2238
},{"./state":13,"./tokentype":17,"./whitespace":19}],13:[function(_dereq_,module,exports){
2239
"use strict";
2240
2241
exports.Parser = Parser;
2242
exports.__esModule = true;
2243
2244
var _identifier = _dereq_("./identifier");
2245
2246
var reservedWords = _identifier.reservedWords;
2247
var keywords = _identifier.keywords;
2248
2249
var tt = _dereq_("./tokentype").types;
2250
2251
var lineBreak = _dereq_("./whitespace").lineBreak;
2252
2253
function Parser(options, input, startPos) {
2254
this.options = options;
2255
this.sourceFile = this.options.sourceFile || null;
2256
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
2257
this.isReservedWord = reservedWords[this.options.ecmaVersion];
2258
this.input = input;
2259
2260
// Load plugins
2261
this.loadPlugins(this.options.plugins);
2262
2263
// Set up token state
2264
2265
// The current position of the tokenizer in the input.
2266
if (startPos) {
2267
this.pos = startPos;
2268
this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
2269
this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
2270
} else {
2271
this.pos = this.lineStart = 0;
2272
this.curLine = 1;
2273
}
2274
2275
// Properties of the current token:
2276
// Its type
2277
this.type = tt.eof;
2278
// For tokens that include more information than their type, the value
2279
this.value = null;
2280
// Its start and end offset
2281
this.start = this.end = this.pos;
2282
// And, if locations are used, the {line, column} object
2283
// corresponding to those offsets
2284
this.startLoc = this.endLoc = null;
2285
2286
// Position information for the previous token
2287
this.lastTokEndLoc = this.lastTokStartLoc = null;
2288
this.lastTokStart = this.lastTokEnd = this.pos;
2289
2290
// The context stack is used to superficially track syntactic
2291
// context to predict whether a regular expression is allowed in a
2292
// given position.
2293
this.context = this.initialContext();
2294
this.exprAllowed = true;
2295
2296
// Figure out if it's a module code.
2297
this.strict = this.inModule = this.options.sourceType === "module";
2298
2299
// Used to signify the start of a potential arrow function
2300
this.potentialArrowAt = -1;
2301
2302
// Flags to track whether we are in a function, a generator.
2303
this.inFunction = this.inGenerator = false;
2304
// Labels in scope.
2305
this.labels = [];
2306
2307
// If enabled, skip leading hashbang line.
2308
if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
2309
}
2310
2311
Parser.prototype.extend = function (name, f) {
2312
this[name] = f(this[name]);
2313
};
2314
2315
// Registered plugins
2316
2317
var plugins = {};
2318
2319
exports.plugins = plugins;
2320
Parser.prototype.loadPlugins = function (plugins) {
2321
for (var _name in plugins) {
2322
var plugin = exports.plugins[_name];
2323
if (!plugin) throw new Error("Plugin '" + _name + "' not found");
2324
plugin(this, plugins[_name]);
2325
}
2326
};
2327
2328
},{"./identifier":7,"./tokentype":17,"./whitespace":19}],14:[function(_dereq_,module,exports){
2329
"use strict";
2330
2331
var tt = _dereq_("./tokentype").types;
2332
2333
var Parser = _dereq_("./state").Parser;
2334
2335
var lineBreak = _dereq_("./whitespace").lineBreak;
2336
2337
var pp = Parser.prototype;
2338
2339
// ### Statement parsing
2340
2341
// Parse a program. Initializes the parser, reads any number of
2342
// statements, and wraps them in a Program node. Optionally takes a
2343
// `program` argument. If present, the statements will be appended
2344
// to its body instead of creating a new node.
2345
2346
pp.parseTopLevel = function (node) {
2347
var first = true;
2348
if (!node.body) node.body = [];
2349
while (this.type !== tt.eof) {
2350
var stmt = this.parseStatement(true, true);
2351
node.body.push(stmt);
2352
if (first && this.isUseStrict(stmt)) this.setStrict(true);
2353
first = false;
2354
}
2355
this.next();
2356
if (this.options.ecmaVersion >= 6) {
2357
node.sourceType = this.options.sourceType;
2358
}
2359
return this.finishNode(node, "Program");
2360
};
2361
2362
var loopLabel = { kind: "loop" },
2363
switchLabel = { kind: "switch" };
2364
2365
// Parse a single statement.
2366
//
2367
// If expecting a statement and finding a slash operator, parse a
2368
// regular expression literal. This is to handle cases like
2369
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
2370
// does not help.
2371
2372
pp.parseStatement = function (declaration, topLevel) {
2373
var starttype = this.type,
2374
node = this.startNode();
2375
2376
// Most types of statements are recognized by the keyword they
2377
// start with. Many are trivial to parse, some require a bit of
2378
// complexity.
2379
2380
switch (starttype) {
2381
case tt._break:case tt._continue:
2382
return this.parseBreakContinueStatement(node, starttype.keyword);
2383
case tt._debugger:
2384
return this.parseDebuggerStatement(node);
2385
case tt._do:
2386
return this.parseDoStatement(node);
2387
case tt._for:
2388
return this.parseForStatement(node);
2389
case tt._function:
2390
if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
2391
return this.parseFunctionStatement(node);
2392
case tt._class:
2393
if (!declaration) this.unexpected();
2394
return this.parseClass(node, true);
2395
case tt._if:
2396
return this.parseIfStatement(node);
2397
case tt._return:
2398
return this.parseReturnStatement(node);
2399
case tt._switch:
2400
return this.parseSwitchStatement(node);
2401
case tt._throw:
2402
return this.parseThrowStatement(node);
2403
case tt._try:
2404
return this.parseTryStatement(node);
2405
case tt._let:case tt._const:
2406
if (!declaration) this.unexpected(); // NOTE: falls through to _var
2407
case tt._var:
2408
return this.parseVarStatement(node, starttype);
2409
case tt._while:
2410
return this.parseWhileStatement(node);
2411
case tt._with:
2412
return this.parseWithStatement(node);
2413
case tt.braceL:
2414
return this.parseBlock();
2415
case tt.semi:
2416
return this.parseEmptyStatement(node);
2417
case tt._export:
2418
case tt._import:
2419
if (!this.options.allowImportExportEverywhere) {
2420
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
2421
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
2422
}
2423
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
2424
2425
// If the statement does not start with a statement keyword or a
2426
// brace, it's an ExpressionStatement or LabeledStatement. We
2427
// simply start parsing an expression, and afterwards, if the
2428
// next token is a colon and the expression was a simple
2429
// Identifier node, we switch to interpreting it as a label.
2430
default:
2431
var maybeName = this.value,
2432
expr = this.parseExpression();
2433
if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
2434
}
2435
};
2436
2437
pp.parseBreakContinueStatement = function (node, keyword) {
2438
var isBreak = keyword == "break";
2439
this.next();
2440
if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== tt.name) this.unexpected();else {
2441
node.label = this.parseIdent();
2442
this.semicolon();
2443
}
2444
2445
// Verify that there is an actual destination to break or
2446
// continue to.
2447
for (var i = 0; i < this.labels.length; ++i) {
2448
var lab = this.labels[i];
2449
if (node.label == null || lab.name === node.label.name) {
2450
if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
2451
if (node.label && isBreak) break;
2452
}
2453
}
2454
if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
2455
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
2456
};
2457
2458
pp.parseDebuggerStatement = function (node) {
2459
this.next();
2460
this.semicolon();
2461
return this.finishNode(node, "DebuggerStatement");
2462
};
2463
2464
pp.parseDoStatement = function (node) {
2465
this.next();
2466
this.labels.push(loopLabel);
2467
node.body = this.parseStatement(false);
2468
this.labels.pop();
2469
this.expect(tt._while);
2470
node.test = this.parseParenExpression();
2471
if (this.options.ecmaVersion >= 6) this.eat(tt.semi);else this.semicolon();
2472
return this.finishNode(node, "DoWhileStatement");
2473
};
2474
2475
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
2476
// loop is non-trivial. Basically, we have to parse the init `var`
2477
// statement or expression, disallowing the `in` operator (see
2478
// the second parameter to `parseExpression`), and then check
2479
// whether the next token is `in` or `of`. When there is no init
2480
// part (semicolon immediately after the opening parenthesis), it
2481
// is a regular `for` loop.
2482
2483
pp.parseForStatement = function (node) {
2484
this.next();
2485
this.labels.push(loopLabel);
2486
this.expect(tt.parenL);
2487
if (this.type === tt.semi) return this.parseFor(node, null);
2488
if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
2489
var _init = this.startNode(),
2490
varKind = this.type;
2491
this.next();
2492
this.parseVar(_init, true, varKind);
2493
this.finishNode(_init, "VariableDeclaration");
2494
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);
2495
return this.parseFor(node, _init);
2496
}
2497
var refShorthandDefaultPos = { start: 0 };
2498
var init = this.parseExpression(true, refShorthandDefaultPos);
2499
if (this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
2500
this.toAssignable(init);
2501
this.checkLVal(init);
2502
return this.parseForIn(node, init);
2503
} else if (refShorthandDefaultPos.start) {
2504
this.unexpected(refShorthandDefaultPos.start);
2505
}
2506
return this.parseFor(node, init);
2507
};
2508
2509
pp.parseFunctionStatement = function (node) {
2510
this.next();
2511
return this.parseFunction(node, true);
2512
};
2513
2514
pp.parseIfStatement = function (node) {
2515
this.next();
2516
node.test = this.parseParenExpression();
2517
node.consequent = this.parseStatement(false);
2518
node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
2519
return this.finishNode(node, "IfStatement");
2520
};
2521
2522
pp.parseReturnStatement = function (node) {
2523
if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
2524
this.next();
2525
2526
// In `return` (and `break`/`continue`), the keywords with
2527
// optional arguments, we eagerly look for a semicolon or the
2528
// possibility to insert one.
2529
2530
if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null;else {
2531
node.argument = this.parseExpression();this.semicolon();
2532
}
2533
return this.finishNode(node, "ReturnStatement");
2534
};
2535
2536
pp.parseSwitchStatement = function (node) {
2537
this.next();
2538
node.discriminant = this.parseParenExpression();
2539
node.cases = [];
2540
this.expect(tt.braceL);
2541
this.labels.push(switchLabel);
2542
2543
// Statements under must be grouped (by label) in SwitchCase
2544
// nodes. `cur` is used to keep the node that we are currently
2545
// adding statements to.
2546
2547
for (var cur, sawDefault; this.type != tt.braceR;) {
2548
if (this.type === tt._case || this.type === tt._default) {
2549
var isCase = this.type === tt._case;
2550
if (cur) this.finishNode(cur, "SwitchCase");
2551
node.cases.push(cur = this.startNode());
2552
cur.consequent = [];
2553
this.next();
2554
if (isCase) {
2555
cur.test = this.parseExpression();
2556
} else {
2557
if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
2558
sawDefault = true;
2559
cur.test = null;
2560
}
2561
this.expect(tt.colon);
2562
} else {
2563
if (!cur) this.unexpected();
2564
cur.consequent.push(this.parseStatement(true));
2565
}
2566
}
2567
if (cur) this.finishNode(cur, "SwitchCase");
2568
this.next(); // Closing brace
2569
this.labels.pop();
2570
return this.finishNode(node, "SwitchStatement");
2571
};
2572
2573
pp.parseThrowStatement = function (node) {
2574
this.next();
2575
if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
2576
node.argument = this.parseExpression();
2577
this.semicolon();
2578
return this.finishNode(node, "ThrowStatement");
2579
};
2580
2581
// Reused empty array added for node fields that are always empty.
2582
2583
var empty = [];
2584
2585
pp.parseTryStatement = function (node) {
2586
this.next();
2587
node.block = this.parseBlock();
2588
node.handler = null;
2589
if (this.type === tt._catch) {
2590
var clause = this.startNode();
2591
this.next();
2592
this.expect(tt.parenL);
2593
clause.param = this.parseBindingAtom();
2594
this.checkLVal(clause.param, true);
2595
this.expect(tt.parenR);
2596
clause.guard = null;
2597
clause.body = this.parseBlock();
2598
node.handler = this.finishNode(clause, "CatchClause");
2599
}
2600
node.guardedHandlers = empty;
2601
node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
2602
if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
2603
return this.finishNode(node, "TryStatement");
2604
};
2605
2606
pp.parseVarStatement = function (node, kind) {
2607
this.next();
2608
this.parseVar(node, false, kind);
2609
this.semicolon();
2610
return this.finishNode(node, "VariableDeclaration");
2611
};
2612
2613
pp.parseWhileStatement = function (node) {
2614
this.next();
2615
node.test = this.parseParenExpression();
2616
this.labels.push(loopLabel);
2617
node.body = this.parseStatement(false);
2618
this.labels.pop();
2619
return this.finishNode(node, "WhileStatement");
2620
};
2621
2622
pp.parseWithStatement = function (node) {
2623
if (this.strict) this.raise(this.start, "'with' in strict mode");
2624
this.next();
2625
node.object = this.parseParenExpression();
2626
node.body = this.parseStatement(false);
2627
return this.finishNode(node, "WithStatement");
2628
};
2629
2630
pp.parseEmptyStatement = function (node) {
2631
this.next();
2632
return this.finishNode(node, "EmptyStatement");
2633
};
2634
2635
pp.parseLabeledStatement = function (node, maybeName, expr) {
2636
for (var i = 0; i < this.labels.length; ++i) {
2637
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
2638
}var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null;
2639
this.labels.push({ name: maybeName, kind: kind });
2640
node.body = this.parseStatement(true);
2641
this.labels.pop();
2642
node.label = expr;
2643
return this.finishNode(node, "LabeledStatement");
2644
};
2645
2646
pp.parseExpressionStatement = function (node, expr) {
2647
node.expression = expr;
2648
this.semicolon();
2649
return this.finishNode(node, "ExpressionStatement");
2650
};
2651
2652
// Parse a semicolon-enclosed block of statements, handling `"use
2653
// strict"` declarations when `allowStrict` is true (used for
2654
// function bodies).
2655
2656
pp.parseBlock = function (allowStrict) {
2657
var node = this.startNode(),
2658
first = true,
2659
oldStrict = undefined;
2660
node.body = [];
2661
this.expect(tt.braceL);
2662
while (!this.eat(tt.braceR)) {
2663
var stmt = this.parseStatement(true);
2664
node.body.push(stmt);
2665
if (first && allowStrict && this.isUseStrict(stmt)) {
2666
oldStrict = this.strict;
2667
this.setStrict(this.strict = true);
2668
}
2669
first = false;
2670
}
2671
if (oldStrict === false) this.setStrict(false);
2672
return this.finishNode(node, "BlockStatement");
2673
};
2674
2675
// Parse a regular `for` loop. The disambiguation code in
2676
// `parseStatement` will already have parsed the init statement or
2677
// expression.
2678
2679
pp.parseFor = function (node, init) {
2680
node.init = init;
2681
this.expect(tt.semi);
2682
node.test = this.type === tt.semi ? null : this.parseExpression();
2683
this.expect(tt.semi);
2684
node.update = this.type === tt.parenR ? null : this.parseExpression();
2685
this.expect(tt.parenR);
2686
node.body = this.parseStatement(false);
2687
this.labels.pop();
2688
return this.finishNode(node, "ForStatement");
2689
};
2690
2691
// Parse a `for`/`in` and `for`/`of` loop, which are almost
2692
// same from parser's perspective.
2693
2694
pp.parseForIn = function (node, init) {
2695
var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement";
2696
this.next();
2697
node.left = init;
2698
node.right = this.parseExpression();
2699
this.expect(tt.parenR);
2700
node.body = this.parseStatement(false);
2701
this.labels.pop();
2702
return this.finishNode(node, type);
2703
};
2704
2705
// Parse a list of variable declarations.
2706
2707
pp.parseVar = function (node, isFor, kind) {
2708
node.declarations = [];
2709
node.kind = kind.keyword;
2710
for (;;) {
2711
var decl = this.startNode();
2712
this.parseVarId(decl);
2713
if (this.eat(tt.eq)) {
2714
decl.init = this.parseMaybeAssign(isFor);
2715
} else if (kind === tt._const && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
2716
this.unexpected();
2717
} else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
2718
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
2719
} else {
2720
decl.init = null;
2721
}
2722
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
2723
if (!this.eat(tt.comma)) break;
2724
}
2725
return node;
2726
};
2727
2728
pp.parseVarId = function (decl) {
2729
decl.id = this.parseBindingAtom();
2730
this.checkLVal(decl.id, true);
2731
};
2732
2733
// Parse a function declaration or literal (depending on the
2734
// `isStatement` parameter).
2735
2736
pp.parseFunction = function (node, isStatement, allowExpressionBody) {
2737
this.initFunction(node);
2738
if (this.options.ecmaVersion >= 6) node.generator = this.eat(tt.star);
2739
if (isStatement || this.type === tt.name) node.id = this.parseIdent();
2740
this.parseFunctionParams(node);
2741
this.parseFunctionBody(node, allowExpressionBody);
2742
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
2743
};
2744
2745
pp.parseFunctionParams = function (node) {
2746
this.expect(tt.parenL);
2747
node.params = this.parseBindingList(tt.parenR, false, false);
2748
};
2749
2750
// Parse a class declaration or literal (depending on the
2751
// `isStatement` parameter).
2752
2753
pp.parseClass = function (node, isStatement) {
2754
this.next();
2755
this.parseClassId(node, isStatement);
2756
this.parseClassSuper(node);
2757
var classBody = this.startNode();
2758
var hadConstructor = false;
2759
classBody.body = [];
2760
this.expect(tt.braceL);
2761
while (!this.eat(tt.braceR)) {
2762
if (this.eat(tt.semi)) continue;
2763
var method = this.startNode();
2764
var isGenerator = this.eat(tt.star);
2765
var isMaybeStatic = this.type === tt.name && this.value === "static";
2766
this.parsePropertyName(method);
2767
method["static"] = isMaybeStatic && this.type !== tt.parenL;
2768
if (method["static"]) {
2769
if (isGenerator) this.unexpected();
2770
isGenerator = this.eat(tt.star);
2771
this.parsePropertyName(method);
2772
}
2773
method.kind = "method";
2774
if (!method.computed) {
2775
var key = method.key;
2776
2777
var isGetSet = false;
2778
if (!isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
2779
isGetSet = true;
2780
method.kind = key.name;
2781
key = this.parsePropertyName(method);
2782
}
2783
if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
2784
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
2785
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
2786
if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
2787
method.kind = "constructor";
2788
hadConstructor = true;
2789
}
2790
}
2791
this.parseClassMethod(classBody, method, isGenerator);
2792
}
2793
node.body = this.finishNode(classBody, "ClassBody");
2794
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
2795
};
2796
2797
pp.parseClassMethod = function (classBody, method, isGenerator) {
2798
method.value = this.parseMethod(isGenerator);
2799
classBody.body.push(this.finishNode(method, "MethodDefinition"));
2800
};
2801
2802
pp.parseClassId = function (node, isStatement) {
2803
node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
2804
};
2805
2806
pp.parseClassSuper = function (node) {
2807
node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
2808
};
2809
2810
// Parses module export declaration.
2811
2812
pp.parseExport = function (node) {
2813
this.next();
2814
// export * from '...'
2815
if (this.eat(tt.star)) {
2816
this.expectContextual("from");
2817
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2818
this.semicolon();
2819
return this.finishNode(node, "ExportAllDeclaration");
2820
}
2821
if (this.eat(tt._default)) {
2822
// export default ...
2823
var expr = this.parseMaybeAssign();
2824
var needsSemi = true;
2825
if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
2826
needsSemi = false;
2827
if (expr.id) {
2828
expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
2829
}
2830
}
2831
node.declaration = expr;
2832
if (needsSemi) this.semicolon();
2833
return this.finishNode(node, "ExportDefaultDeclaration");
2834
}
2835
// export var|const|let|function|class ...
2836
if (this.shouldParseExportStatement()) {
2837
node.declaration = this.parseStatement(true);
2838
node.specifiers = [];
2839
node.source = null;
2840
} else {
2841
// export { x, y as z } [from '...']
2842
node.declaration = null;
2843
node.specifiers = this.parseExportSpecifiers();
2844
if (this.eatContextual("from")) {
2845
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2846
} else {
2847
node.source = null;
2848
}
2849
this.semicolon();
2850
}
2851
return this.finishNode(node, "ExportNamedDeclaration");
2852
};
2853
2854
pp.shouldParseExportStatement = function () {
2855
return this.type.keyword;
2856
};
2857
2858
// Parses a comma-separated list of module exports.
2859
2860
pp.parseExportSpecifiers = function () {
2861
var nodes = [],
2862
first = true;
2863
// export { x, y as z } [from '...']
2864
this.expect(tt.braceL);
2865
while (!this.eat(tt.braceR)) {
2866
if (!first) {
2867
this.expect(tt.comma);
2868
if (this.afterTrailingComma(tt.braceR)) break;
2869
} else first = false;
2870
2871
var node = this.startNode();
2872
node.local = this.parseIdent(this.type === tt._default);
2873
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
2874
nodes.push(this.finishNode(node, "ExportSpecifier"));
2875
}
2876
return nodes;
2877
};
2878
2879
// Parses import declaration.
2880
2881
pp.parseImport = function (node) {
2882
this.next();
2883
// import '...'
2884
if (this.type === tt.string) {
2885
node.specifiers = empty;
2886
node.source = this.parseExprAtom();
2887
node.kind = "";
2888
} else {
2889
node.specifiers = this.parseImportSpecifiers();
2890
this.expectContextual("from");
2891
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
2892
}
2893
this.semicolon();
2894
return this.finishNode(node, "ImportDeclaration");
2895
};
2896
2897
// Parses a comma-separated list of module imports.
2898
2899
pp.parseImportSpecifiers = function () {
2900
var nodes = [],
2901
first = true;
2902
if (this.type === tt.name) {
2903
// import defaultObj, { x, y as z } from '...'
2904
var node = this.startNode();
2905
node.local = this.parseIdent();
2906
this.checkLVal(node.local, true);
2907
nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
2908
if (!this.eat(tt.comma)) return nodes;
2909
}
2910
if (this.type === tt.star) {
2911
var node = this.startNode();
2912
this.next();
2913
this.expectContextual("as");
2914
node.local = this.parseIdent();
2915
this.checkLVal(node.local, true);
2916
nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
2917
return nodes;
2918
}
2919
this.expect(tt.braceL);
2920
while (!this.eat(tt.braceR)) {
2921
if (!first) {
2922
this.expect(tt.comma);
2923
if (this.afterTrailingComma(tt.braceR)) break;
2924
} else first = false;
2925
2926
var node = this.startNode();
2927
node.imported = this.parseIdent(true);
2928
node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
2929
this.checkLVal(node.local, true);
2930
nodes.push(this.finishNode(node, "ImportSpecifier"));
2931
}
2932
return nodes;
2933
};
2934
2935
},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){
2936
"use strict";
2937
2938
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
2939
2940
exports.__esModule = true;
2941
// The algorithm used to determine whether a regexp can appear at a
2942
// given point in the program is loosely based on sweet.js' approach.
2943
// See https://github.com/mozilla/sweet.js/wiki/design
2944
2945
var Parser = _dereq_("./state").Parser;
2946
2947
var tt = _dereq_("./tokentype").types;
2948
2949
var lineBreak = _dereq_("./whitespace").lineBreak;
2950
2951
var TokContext = exports.TokContext = function TokContext(token, isExpr, preserveSpace, override) {
2952
_classCallCheck(this, TokContext);
2953
2954
this.token = token;
2955
this.isExpr = isExpr;
2956
this.preserveSpace = preserveSpace;
2957
this.override = override;
2958
};
2959
2960
var types = {
2961
b_stat: new TokContext("{", false),
2962
b_expr: new TokContext("{", true),
2963
b_tmpl: new TokContext("${", true),
2964
p_stat: new TokContext("(", false),
2965
p_expr: new TokContext("(", true),
2966
q_tmpl: new TokContext("`", true, true, function (p) {
2967
return p.readTmplToken();
2968
}),
2969
f_expr: new TokContext("function", true)
2970
};
2971
2972
exports.types = types;
2973
var pp = Parser.prototype;
2974
2975
pp.initialContext = function () {
2976
return [types.b_stat];
2977
};
2978
2979
pp.braceIsBlock = function (prevType) {
2980
var parent = undefined;
2981
if (prevType === tt.colon && (parent = this.curContext()).token == "{") return !parent.isExpr;
2982
if (prevType === tt._return) return lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
2983
if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof) return true;
2984
if (prevType == tt.braceL) return this.curContext() === types.b_stat;
2985
return !this.exprAllowed;
2986
};
2987
2988
pp.updateContext = function (prevType) {
2989
var update = undefined,
2990
type = this.type;
2991
if (type.keyword && prevType == tt.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
2992
};
2993
2994
// Token-specific context update code
2995
2996
tt.parenR.updateContext = tt.braceR.updateContext = function () {
2997
if (this.context.length == 1) {
2998
this.exprAllowed = true;
2999
return;
3000
}
3001
var out = this.context.pop();
3002
if (out === types.b_stat && this.curContext() === types.f_expr) {
3003
this.context.pop();
3004
this.exprAllowed = false;
3005
} else if (out === types.b_tmpl) {
3006
this.exprAllowed = true;
3007
} else {
3008
this.exprAllowed = !out.isExpr;
3009
}
3010
};
3011
3012
tt.braceL.updateContext = function (prevType) {
3013
this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
3014
this.exprAllowed = true;
3015
};
3016
3017
tt.dollarBraceL.updateContext = function () {
3018
this.context.push(types.b_tmpl);
3019
this.exprAllowed = true;
3020
};
3021
3022
tt.parenL.updateContext = function (prevType) {
3023
var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
3024
this.context.push(statementParens ? types.p_stat : types.p_expr);
3025
this.exprAllowed = true;
3026
};
3027
3028
tt.incDec.updateContext = function () {};
3029
3030
tt._function.updateContext = function () {
3031
if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
3032
this.exprAllowed = false;
3033
};
3034
3035
tt.backQuote.updateContext = function () {
3036
if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
3037
this.exprAllowed = false;
3038
};
3039
3040
// tokExprAllowed stays unchanged
3041
3042
},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){
3043
"use strict";
3044
3045
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
3046
3047
exports.__esModule = true;
3048
3049
var _identifier = _dereq_("./identifier");
3050
3051
var isIdentifierStart = _identifier.isIdentifierStart;
3052
var isIdentifierChar = _identifier.isIdentifierChar;
3053
3054
var _tokentype = _dereq_("./tokentype");
3055
3056
var tt = _tokentype.types;
3057
var keywordTypes = _tokentype.keywords;
3058
3059
var Parser = _dereq_("./state").Parser;
3060
3061
var SourceLocation = _dereq_("./location").SourceLocation;
3062
3063
var _whitespace = _dereq_("./whitespace");
3064
3065
var lineBreak = _whitespace.lineBreak;
3066
var lineBreakG = _whitespace.lineBreakG;
3067
var isNewLine = _whitespace.isNewLine;
3068
var nonASCIIwhitespace = _whitespace.nonASCIIwhitespace;
3069
3070
// Object type used to represent tokens. Note that normally, tokens
3071
// simply exist as properties on the parser object. This is only
3072
// used for the onToken callback and the external tokenizer.
3073
3074
var Token = exports.Token = function Token(p) {
3075
_classCallCheck(this, Token);
3076
3077
this.type = p.type;
3078
this.value = p.value;
3079
this.start = p.start;
3080
this.end = p.end;
3081
if (p.options.locations) this.loc = new SourceLocation(p, p.startLoc, p.endLoc);
3082
if (p.options.ranges) this.range = [p.start, p.end];
3083
};
3084
3085
// ## Tokenizer
3086
3087
var pp = Parser.prototype;
3088
3089
// Are we running under Rhino?
3090
var isRhino = typeof Packages !== "undefined";
3091
3092
// Move to the next token
3093
3094
pp.next = function () {
3095
if (this.options.onToken) this.options.onToken(new Token(this));
3096
3097
this.lastTokEnd = this.end;
3098
this.lastTokStart = this.start;
3099
this.lastTokEndLoc = this.endLoc;
3100
this.lastTokStartLoc = this.startLoc;
3101
this.nextToken();
3102
};
3103
3104
pp.getToken = function () {
3105
this.next();
3106
return new Token(this);
3107
};
3108
3109
// If we're in an ES6 environment, make parsers iterable
3110
if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
3111
var self = this;
3112
return { next: function next() {
3113
var token = self.getToken();
3114
return {
3115
done: token.type === tt.eof,
3116
value: token
3117
};
3118
} };
3119
};
3120
3121
// Toggle strict mode. Re-reads the next number or string to please
3122
// pedantic tests (`"use strict"; 010;` should fail).
3123
3124
pp.setStrict = function (strict) {
3125
this.strict = strict;
3126
if (this.type !== tt.num && this.type !== tt.string) return;
3127
this.pos = this.start;
3128
if (this.options.locations) {
3129
while (this.pos < this.lineStart) {
3130
this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
3131
--this.curLine;
3132
}
3133
}
3134
this.nextToken();
3135
};
3136
3137
pp.curContext = function () {
3138
return this.context[this.context.length - 1];
3139
};
3140
3141
// Read a single token, updating the parser object's token-related
3142
// properties.
3143
3144
pp.nextToken = function () {
3145
var curContext = this.curContext();
3146
if (!curContext || !curContext.preserveSpace) this.skipSpace();
3147
3148
this.start = this.pos;
3149
if (this.options.locations) this.startLoc = this.curPosition();
3150
if (this.pos >= this.input.length) return this.finishToken(tt.eof);
3151
3152
if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
3153
};
3154
3155
pp.readToken = function (code) {
3156
// Identifier or keyword. '\uXXXX' sequences are allowed in
3157
// identifiers, so '\' also dispatches to that.
3158
if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
3159
3160
return this.getTokenFromCode(code);
3161
};
3162
3163
pp.fullCharCodeAtPos = function () {
3164
var code = this.input.charCodeAt(this.pos);
3165
if (code <= 55295 || code >= 57344) return code;
3166
var next = this.input.charCodeAt(this.pos + 1);
3167
return (code << 10) + next - 56613888;
3168
};
3169
3170
pp.skipBlockComment = function () {
3171
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
3172
var start = this.pos,
3173
end = this.input.indexOf("*/", this.pos += 2);
3174
if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
3175
this.pos = end + 2;
3176
if (this.options.locations) {
3177
lineBreakG.lastIndex = start;
3178
var match = undefined;
3179
while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
3180
++this.curLine;
3181
this.lineStart = match.index + match[0].length;
3182
}
3183
}
3184
if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.options.locations && this.curPosition());
3185
};
3186
3187
pp.skipLineComment = function (startSkip) {
3188
var start = this.pos;
3189
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
3190
var ch = this.input.charCodeAt(this.pos += startSkip);
3191
while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
3192
++this.pos;
3193
ch = this.input.charCodeAt(this.pos);
3194
}
3195
if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.options.locations && this.curPosition());
3196
};
3197
3198
// Called at the start of the parse and after every token. Skips
3199
// whitespace and comments, and.
3200
3201
pp.skipSpace = function () {
3202
while (this.pos < this.input.length) {
3203
var ch = this.input.charCodeAt(this.pos);
3204
if (ch === 32) {
3205
// ' '
3206
++this.pos;
3207
} else if (ch === 13) {
3208
++this.pos;
3209
var next = this.input.charCodeAt(this.pos);
3210
if (next === 10) {
3211
++this.pos;
3212
}
3213
if (this.options.locations) {
3214
++this.curLine;
3215
this.lineStart = this.pos;
3216
}
3217
} else if (ch === 10 || ch === 8232 || ch === 8233) {
3218
++this.pos;
3219
if (this.options.locations) {
3220
++this.curLine;
3221
this.lineStart = this.pos;
3222
}
3223
} else if (ch > 8 && ch < 14) {
3224
++this.pos;
3225
} else if (ch === 47) {
3226
// '/'
3227
var next = this.input.charCodeAt(this.pos + 1);
3228
if (next === 42) {
3229
// '*'
3230
this.skipBlockComment();
3231
} else if (next === 47) {
3232
// '/'
3233
this.skipLineComment(2);
3234
} else break;
3235
} else if (ch === 160) {
3236
// '\xa0'
3237
++this.pos;
3238
} else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
3239
++this.pos;
3240
} else {
3241
break;
3242
}
3243
}
3244
};
3245
3246
// Called at the end of every token. Sets `end`, `val`, and
3247
// maintains `context` and `exprAllowed`, and skips the space after
3248
// the token, so that the next one's `start` will point at the
3249
// right position.
3250
3251
pp.finishToken = function (type, val) {
3252
this.end = this.pos;
3253
if (this.options.locations) this.endLoc = this.curPosition();
3254
var prevType = this.type;
3255
this.type = type;
3256
this.value = val;
3257
3258
this.updateContext(prevType);
3259
};
3260
3261
// ### Token reading
3262
3263
// This is the function that is called to fetch the next token. It
3264
// is somewhat obscure, because it works in character codes rather
3265
// than characters, and because operator parsing has been inlined
3266
// into it.
3267
//
3268
// All in the name of speed.
3269
//
3270
pp.readToken_dot = function () {
3271
var next = this.input.charCodeAt(this.pos + 1);
3272
if (next >= 48 && next <= 57) return this.readNumber(true);
3273
var next2 = this.input.charCodeAt(this.pos + 2);
3274
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
3275
// 46 = dot '.'
3276
this.pos += 3;
3277
return this.finishToken(tt.ellipsis);
3278
} else {
3279
++this.pos;
3280
return this.finishToken(tt.dot);
3281
}
3282
};
3283
3284
pp.readToken_slash = function () {
3285
// '/'
3286
var next = this.input.charCodeAt(this.pos + 1);
3287
if (this.exprAllowed) {
3288
++this.pos;return this.readRegexp();
3289
}
3290
if (next === 61) return this.finishOp(tt.assign, 2);
3291
return this.finishOp(tt.slash, 1);
3292
};
3293
3294
pp.readToken_mult_modulo = function (code) {
3295
// '%*'
3296
var next = this.input.charCodeAt(this.pos + 1);
3297
if (next === 61) return this.finishOp(tt.assign, 2);
3298
return this.finishOp(code === 42 ? tt.star : tt.modulo, 1);
3299
};
3300
3301
pp.readToken_pipe_amp = function (code) {
3302
// '|&'
3303
var next = this.input.charCodeAt(this.pos + 1);
3304
if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
3305
if (next === 61) return this.finishOp(tt.assign, 2);
3306
return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
3307
};
3308
3309
pp.readToken_caret = function () {
3310
// '^'
3311
var next = this.input.charCodeAt(this.pos + 1);
3312
if (next === 61) return this.finishOp(tt.assign, 2);
3313
return this.finishOp(tt.bitwiseXOR, 1);
3314
};
3315
3316
pp.readToken_plus_min = function (code) {
3317
// '+-'
3318
var next = this.input.charCodeAt(this.pos + 1);
3319
if (next === code) {
3320
if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
3321
// A `-->` line comment
3322
this.skipLineComment(3);
3323
this.skipSpace();
3324
return this.nextToken();
3325
}
3326
return this.finishOp(tt.incDec, 2);
3327
}
3328
if (next === 61) return this.finishOp(tt.assign, 2);
3329
return this.finishOp(tt.plusMin, 1);
3330
};
3331
3332
pp.readToken_lt_gt = function (code) {
3333
// '<>'
3334
var next = this.input.charCodeAt(this.pos + 1);
3335
var size = 1;
3336
if (next === code) {
3337
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
3338
if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1);
3339
return this.finishOp(tt.bitShift, size);
3340
}
3341
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
3342
if (this.inModule) this.unexpected();
3343
// `<!--`, an XML-style comment that should be interpreted as a line comment
3344
this.skipLineComment(4);
3345
this.skipSpace();
3346
return this.nextToken();
3347
}
3348
if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
3349
return this.finishOp(tt.relational, size);
3350
};
3351
3352
pp.readToken_eq_excl = function (code) {
3353
// '=!'
3354
var next = this.input.charCodeAt(this.pos + 1);
3355
if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
3356
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
3357
// '=>'
3358
this.pos += 2;
3359
return this.finishToken(tt.arrow);
3360
}
3361
return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
3362
};
3363
3364
pp.getTokenFromCode = function (code) {
3365
switch (code) {
3366
// The interpretation of a dot depends on whether it is followed
3367
// by a digit or another two dots.
3368
case 46:
3369
// '.'
3370
return this.readToken_dot();
3371
3372
// Punctuation tokens.
3373
case 40:
3374
++this.pos;return this.finishToken(tt.parenL);
3375
case 41:
3376
++this.pos;return this.finishToken(tt.parenR);
3377
case 59:
3378
++this.pos;return this.finishToken(tt.semi);
3379
case 44:
3380
++this.pos;return this.finishToken(tt.comma);
3381
case 91:
3382
++this.pos;return this.finishToken(tt.bracketL);
3383
case 93:
3384
++this.pos;return this.finishToken(tt.bracketR);
3385
case 123:
3386
++this.pos;return this.finishToken(tt.braceL);
3387
case 125:
3388
++this.pos;return this.finishToken(tt.braceR);
3389
case 58:
3390
++this.pos;return this.finishToken(tt.colon);
3391
case 63:
3392
++this.pos;return this.finishToken(tt.question);
3393
3394
case 96:
3395
// '`'
3396
if (this.options.ecmaVersion < 6) break;
3397
++this.pos;
3398
return this.finishToken(tt.backQuote);
3399
3400
case 48:
3401
// '0'
3402
var next = this.input.charCodeAt(this.pos + 1);
3403
if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
3404
if (this.options.ecmaVersion >= 6) {
3405
if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
3406
if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
3407
}
3408
// Anything else beginning with a digit is an integer, octal
3409
// number, or float.
3410
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
3411
// 1-9
3412
return this.readNumber(false);
3413
3414
// Quotes produce strings.
3415
case 34:case 39:
3416
// '"', "'"
3417
return this.readString(code);
3418
3419
// Operators are parsed inline in tiny state machines. '=' (61) is
3420
// often referred to. `finishOp` simply skips the amount of
3421
// characters it is given as second argument, and returns a token
3422
// of the type given by its first argument.
3423
3424
case 47:
3425
// '/'
3426
return this.readToken_slash();
3427
3428
case 37:case 42:
3429
// '%*'
3430
return this.readToken_mult_modulo(code);
3431
3432
case 124:case 38:
3433
// '|&'
3434
return this.readToken_pipe_amp(code);
3435
3436
case 94:
3437
// '^'
3438
return this.readToken_caret();
3439
3440
case 43:case 45:
3441
// '+-'
3442
return this.readToken_plus_min(code);
3443
3444
case 60:case 62:
3445
// '<>'
3446
return this.readToken_lt_gt(code);
3447
3448
case 61:case 33:
3449
// '=!'
3450
return this.readToken_eq_excl(code);
3451
3452
case 126:
3453
// '~'
3454
return this.finishOp(tt.prefix, 1);
3455
}
3456
3457
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
3458
};
3459
3460
pp.finishOp = function (type, size) {
3461
var str = this.input.slice(this.pos, this.pos + size);
3462
this.pos += size;
3463
return this.finishToken(type, str);
3464
};
3465
3466
var regexpUnicodeSupport = false;
3467
try {
3468
new RegExp("￿", "u");regexpUnicodeSupport = true;
3469
} catch (e) {}
3470
3471
// Parse a regular expression. Some context-awareness is necessary,
3472
// since a '/' inside a '[]' set does not end the expression.
3473
3474
pp.readRegexp = function () {
3475
var escaped = undefined,
3476
inClass = undefined,
3477
start = this.pos;
3478
for (;;) {
3479
if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
3480
var ch = this.input.charAt(this.pos);
3481
if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
3482
if (!escaped) {
3483
if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
3484
escaped = ch === "\\";
3485
} else escaped = false;
3486
++this.pos;
3487
}
3488
var content = this.input.slice(start, this.pos);
3489
++this.pos;
3490
// Need to use `readWord1` because '\uXXXX' sequences are allowed
3491
// here (don't ask).
3492
var mods = this.readWord1();
3493
var tmp = content;
3494
if (mods) {
3495
var validFlags = /^[gmsiy]*$/;
3496
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
3497
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
3498
if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
3499
// Replace each astral symbol and every Unicode escape sequence that
3500
// possibly represents an astral symbol or a paired surrogate with a
3501
// single ASCII symbol to avoid throwing on regular expressions that
3502
// are only valid in combination with the `/u` flag.
3503
// Note: replacing with the ASCII symbol `x` might cause false
3504
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
3505
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
3506
// be replaced by `[x-b]` which throws an error.
3507
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
3508
}
3509
}
3510
// Detect invalid regular expressions.
3511
var value = null;
3512
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
3513
// so don't do detection if we are running under Rhino
3514
if (!isRhino) {
3515
try {
3516
new RegExp(tmp);
3517
} catch (e) {
3518
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message);
3519
this.raise(e);
3520
}
3521
// Get a regular expression object for this pattern-flag pair, or `null` in
3522
// case the current environment doesn't support the flags it uses.
3523
try {
3524
value = new RegExp(content, mods);
3525
} catch (err) {}
3526
}
3527
return this.finishToken(tt.regexp, { pattern: content, flags: mods, value: value });
3528
};
3529
3530
// Read an integer in the given radix. Return null if zero digits
3531
// were read, the integer value otherwise. When `len` is given, this
3532
// will return `null` unless the integer has exactly `len` digits.
3533
3534
pp.readInt = function (radix, len) {
3535
var start = this.pos,
3536
total = 0;
3537
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
3538
var code = this.input.charCodeAt(this.pos),
3539
val = undefined;
3540
if (code >= 97) val = code - 97 + 10; // a
3541
else if (code >= 65) val = code - 65 + 10; // A
3542
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
3543
else val = Infinity;
3544
if (val >= radix) break;
3545
++this.pos;
3546
total = total * radix + val;
3547
}
3548
if (this.pos === start || len != null && this.pos - start !== len) return null;
3549
3550
return total;
3551
};
3552
3553
pp.readRadixNumber = function (radix) {
3554
this.pos += 2; // 0x
3555
var val = this.readInt(radix);
3556
if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
3557
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
3558
return this.finishToken(tt.num, val);
3559
};
3560
3561
// Read an integer, octal integer, or floating-point number.
3562
3563
pp.readNumber = function (startsWithDot) {
3564
var start = this.pos,
3565
isFloat = false,
3566
octal = this.input.charCodeAt(this.pos) === 48;
3567
if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
3568
if (this.input.charCodeAt(this.pos) === 46) {
3569
++this.pos;
3570
this.readInt(10);
3571
isFloat = true;
3572
}
3573
var next = this.input.charCodeAt(this.pos);
3574
if (next === 69 || next === 101) {
3575
// 'eE'
3576
next = this.input.charCodeAt(++this.pos);
3577
if (next === 43 || next === 45) ++this.pos; // '+-'
3578
if (this.readInt(10) === null) this.raise(start, "Invalid number");
3579
isFloat = true;
3580
}
3581
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
3582
3583
var str = this.input.slice(start, this.pos),
3584
val = undefined;
3585
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);
3586
return this.finishToken(tt.num, val);
3587
};
3588
3589
// Read a string value, interpreting backslash-escapes.
3590
3591
pp.readCodePoint = function () {
3592
var ch = this.input.charCodeAt(this.pos),
3593
code = undefined;
3594
3595
if (ch === 123) {
3596
if (this.options.ecmaVersion < 6) this.unexpected();
3597
++this.pos;
3598
code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
3599
++this.pos;
3600
if (code > 1114111) this.unexpected();
3601
} else {
3602
code = this.readHexChar(4);
3603
}
3604
return code;
3605
};
3606
3607
function codePointToString(code) {
3608
// UTF-16 Decoding
3609
if (code <= 65535) {
3610
return String.fromCharCode(code);
3611
}return String.fromCharCode((code - 65536 >> 10) + 55296, (code - 65536 & 1023) + 56320);
3612
}
3613
3614
pp.readString = function (quote) {
3615
var out = "",
3616
chunkStart = ++this.pos;
3617
for (;;) {
3618
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
3619
var ch = this.input.charCodeAt(this.pos);
3620
if (ch === quote) break;
3621
if (ch === 92) {
3622
// '\'
3623
out += this.input.slice(chunkStart, this.pos);
3624
out += this.readEscapedChar();
3625
chunkStart = this.pos;
3626
} else {
3627
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
3628
++this.pos;
3629
}
3630
}
3631
out += this.input.slice(chunkStart, this.pos++);
3632
return this.finishToken(tt.string, out);
3633
};
3634
3635
// Reads template string tokens.
3636
3637
pp.readTmplToken = function () {
3638
var out = "",
3639
chunkStart = this.pos;
3640
for (;;) {
3641
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
3642
var ch = this.input.charCodeAt(this.pos);
3643
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
3644
// '`', '${'
3645
if (this.pos === this.start && this.type === tt.template) {
3646
if (ch === 36) {
3647
this.pos += 2;
3648
return this.finishToken(tt.dollarBraceL);
3649
} else {
3650
++this.pos;
3651
return this.finishToken(tt.backQuote);
3652
}
3653
}
3654
out += this.input.slice(chunkStart, this.pos);
3655
return this.finishToken(tt.template, out);
3656
}
3657
if (ch === 92) {
3658
// '\'
3659
out += this.input.slice(chunkStart, this.pos);
3660
out += this.readEscapedChar();
3661
chunkStart = this.pos;
3662
} else if (isNewLine(ch)) {
3663
out += this.input.slice(chunkStart, this.pos);
3664
++this.pos;
3665
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
3666
++this.pos;
3667
out += "\n";
3668
} else {
3669
out += String.fromCharCode(ch);
3670
}
3671
if (this.options.locations) {
3672
++this.curLine;
3673
this.lineStart = this.pos;
3674
}
3675
chunkStart = this.pos;
3676
} else {
3677
++this.pos;
3678
}
3679
}
3680
};
3681
3682
// Used to read escaped characters
3683
3684
pp.readEscapedChar = function () {
3685
var ch = this.input.charCodeAt(++this.pos);
3686
var octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3));
3687
if (octal) octal = octal[0];
3688
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
3689
if (octal === "0") octal = null;
3690
++this.pos;
3691
if (octal) {
3692
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode");
3693
this.pos += octal.length - 1;
3694
return String.fromCharCode(parseInt(octal, 8));
3695
} else {
3696
switch (ch) {
3697
case 110:
3698
return "\n"; // 'n' -> '\n'
3699
case 114:
3700
return "\r"; // 'r' -> '\r'
3701
case 120:
3702
return String.fromCharCode(this.readHexChar(2)); // 'x'
3703
case 117:
3704
return codePointToString(this.readCodePoint()); // 'u'
3705
case 116:
3706
return "\t"; // 't' -> '\t'
3707
case 98:
3708
return "\b"; // 'b' -> '\b'
3709
case 118:
3710
return "\u000b"; // 'v' -> '\u000b'
3711
case 102:
3712
return "\f"; // 'f' -> '\f'
3713
case 48:
3714
return "\u0000"; // 0 -> '\0'
3715
case 13:
3716
if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
3717
case 10:
3718
// ' \n'
3719
if (this.options.locations) {
3720
this.lineStart = this.pos;++this.curLine;
3721
}
3722
return "";
3723
default:
3724
return String.fromCharCode(ch);
3725
}
3726
}
3727
};
3728
3729
// Used to read character escape sequences ('\x', '\u', '\U').
3730
3731
pp.readHexChar = function (len) {
3732
var n = this.readInt(16, len);
3733
if (n === null) this.raise(this.start, "Bad character escape sequence");
3734
return n;
3735
};
3736
3737
// Used to signal to callers of `readWord1` whether the word
3738
// contained any escape sequences. This is needed because words with
3739
// escape sequences must not be interpreted as keywords.
3740
3741
var containsEsc;
3742
3743
// Read an identifier, and return it as a string. Sets `containsEsc`
3744
// to whether the word contained a '\u' escape.
3745
//
3746
// Incrementally adds only escaped chars, adding other chunks as-is
3747
// as a micro-optimization.
3748
3749
pp.readWord1 = function () {
3750
containsEsc = false;
3751
var word = "",
3752
first = true,
3753
chunkStart = this.pos;
3754
var astral = this.options.ecmaVersion >= 6;
3755
while (this.pos < this.input.length) {
3756
var ch = this.fullCharCodeAtPos();
3757
if (isIdentifierChar(ch, astral)) {
3758
this.pos += ch <= 65535 ? 1 : 2;
3759
} else if (ch === 92) {
3760
// "\"
3761
containsEsc = true;
3762
word += this.input.slice(chunkStart, this.pos);
3763
var escStart = this.pos;
3764
if (this.input.charCodeAt(++this.pos) != 117) // "u"
3765
this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
3766
++this.pos;
3767
var esc = this.readCodePoint();
3768
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
3769
word += codePointToString(esc);
3770
chunkStart = this.pos;
3771
} else {
3772
break;
3773
}
3774
first = false;
3775
}
3776
return word + this.input.slice(chunkStart, this.pos);
3777
};
3778
3779
// Read an identifier or keyword token. Will check for reserved
3780
// words when necessary.
3781
3782
pp.readWord = function () {
3783
var word = this.readWord1();
3784
var type = tt.name;
3785
if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = keywordTypes[word];
3786
return this.finishToken(type, word);
3787
};
3788
3789
},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){
3790
"use strict";
3791
3792
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
3793
3794
exports.__esModule = true;
3795
// ## Token types
3796
3797
// The assignment of fine-grained, information-carrying type objects
3798
// allows the tokenizer to store the information it has about a
3799
// token in a way that is very cheap for the parser to look up.
3800
3801
// All token type variables start with an underscore, to make them
3802
// easy to recognize.
3803
3804
// The `beforeExpr` property is used to disambiguate between regular
3805
// expressions and divisions. It is set on all token types that can
3806
// be followed by an expression (thus, a slash after them would be a
3807
// regular expression).
3808
//
3809
// `isLoop` marks a keyword as starting a loop, which is important
3810
// to know when parsing a label, in order to allow or disallow
3811
// continue jumps to that label.
3812
3813
var TokenType = exports.TokenType = function TokenType(label) {
3814
var conf = arguments[1] === undefined ? {} : arguments[1];
3815
3816
_classCallCheck(this, TokenType);
3817
3818
this.label = label;
3819
this.keyword = conf.keyword;
3820
this.beforeExpr = !!conf.beforeExpr;
3821
this.startsExpr = !!conf.startsExpr;
3822
this.isLoop = !!conf.isLoop;
3823
this.isAssign = !!conf.isAssign;
3824
this.prefix = !!conf.prefix;
3825
this.postfix = !!conf.postfix;
3826
this.binop = conf.binop || null;
3827
this.updateContext = null;
3828
};
3829
3830
function binop(name, prec) {
3831
return new TokenType(name, { beforeExpr: true, binop: prec });
3832
}
3833
var beforeExpr = { beforeExpr: true },
3834
startsExpr = { startsExpr: true };
3835
3836
var types = {
3837
num: new TokenType("num", startsExpr),
3838
regexp: new TokenType("regexp", startsExpr),
3839
string: new TokenType("string", startsExpr),
3840
name: new TokenType("name", startsExpr),
3841
eof: new TokenType("eof"),
3842
3843
// Punctuation token types.
3844
bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
3845
bracketR: new TokenType("]"),
3846
braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
3847
braceR: new TokenType("}"),
3848
parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
3849
parenR: new TokenType(")"),
3850
comma: new TokenType(",", beforeExpr),
3851
semi: new TokenType(";", beforeExpr),
3852
colon: new TokenType(":", beforeExpr),
3853
dot: new TokenType("."),
3854
question: new TokenType("?", beforeExpr),
3855
arrow: new TokenType("=>", beforeExpr),
3856
template: new TokenType("template"),
3857
ellipsis: new TokenType("...", beforeExpr),
3858
backQuote: new TokenType("`", startsExpr),
3859
dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
3860
3861
// Operators. These carry several kinds of properties to help the
3862
// parser use them properly (the presence of these properties is
3863
// what categorizes them as operators).
3864
//
3865
// `binop`, when present, specifies that this operator is a binary
3866
// operator, and will refer to its precedence.
3867
//
3868
// `prefix` and `postfix` mark the operator as a prefix or postfix
3869
// unary operator.
3870
//
3871
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
3872
// binary operators with a very low precedence, that should result
3873
// in AssignmentExpression nodes.
3874
3875
eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
3876
assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
3877
incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
3878
prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
3879
logicalOR: binop("||", 1),
3880
logicalAND: binop("&&", 2),
3881
bitwiseOR: binop("|", 3),
3882
bitwiseXOR: binop("^", 4),
3883
bitwiseAND: binop("&", 5),
3884
equality: binop("==/!=", 6),
3885
relational: binop("</>", 7),
3886
bitShift: binop("<</>>", 8),
3887
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
3888
modulo: binop("%", 10),
3889
star: binop("*", 10),
3890
slash: binop("/", 10)
3891
};
3892
3893
exports.types = types;
3894
// Map keyword names to token types.
3895
3896
var keywords = {};
3897
3898
exports.keywords = keywords;
3899
// Succinct definitions of keyword token types
3900
function kw(name) {
3901
var options = arguments[1] === undefined ? {} : arguments[1];
3902
3903
options.keyword = name;
3904
keywords[name] = types["_" + name] = new TokenType(name, options);
3905
}
3906
3907
kw("break");
3908
kw("case", beforeExpr);
3909
kw("catch");
3910
kw("continue");
3911
kw("debugger");
3912
kw("default");
3913
kw("do", { isLoop: true });
3914
kw("else", beforeExpr);
3915
kw("finally");
3916
kw("for", { isLoop: true });
3917
kw("function", startsExpr);
3918
kw("if");
3919
kw("return", beforeExpr);
3920
kw("switch");
3921
kw("throw", beforeExpr);
3922
kw("try");
3923
kw("var");
3924
kw("let");
3925
kw("const");
3926
kw("while", { isLoop: true });
3927
kw("with");
3928
kw("new", { beforeExpr: true, startsExpr: true });
3929
kw("this", startsExpr);
3930
kw("super", startsExpr);
3931
kw("class");
3932
kw("extends", beforeExpr);
3933
kw("export");
3934
kw("import");
3935
kw("yield", { beforeExpr: true, startsExpr: true });
3936
kw("null", startsExpr);
3937
kw("true", startsExpr);
3938
kw("false", startsExpr);
3939
kw("in", { beforeExpr: true, binop: 7 });
3940
kw("instanceof", { beforeExpr: true, binop: 7 });
3941
kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
3942
kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
3943
kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
3944
3945
},{}],18:[function(_dereq_,module,exports){
3946
"use strict";
3947
3948
exports.isArray = isArray;
3949
3950
// Checks if an object has a property.
3951
3952
exports.has = has;
3953
exports.__esModule = true;
3954
3955
function isArray(obj) {
3956
return Object.prototype.toString.call(obj) === "[object Array]";
3957
}
3958
3959
function has(obj, propName) {
3960
return Object.prototype.hasOwnProperty.call(obj, propName);
3961
}
3962
3963
},{}],19:[function(_dereq_,module,exports){
3964
"use strict";
3965
3966
exports.isNewLine = isNewLine;
3967
exports.__esModule = true;
3968
// Matches a whole line break (where CRLF is considered a single
3969
// line break). Used to count lines.
3970
3971
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
3972
exports.lineBreak = lineBreak;
3973
var lineBreakG = new RegExp(lineBreak.source, "g");
3974
3975
exports.lineBreakG = lineBreakG;
3976
3977
function isNewLine(code) {
3978
return code === 10 || code === 13 || code === 8232 || code == 8233;
3979
}
3980
3981
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
3982
exports.nonASCIIwhitespace = nonASCIIwhitespace;
3983
3984
},{}]},{},[1])(1)
3985
});
3986