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