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