Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80551 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 || (g.acorn = {})).loose = 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
"use strict";
3
4
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
5
6
exports.parse_dammit = parse_dammit;
7
exports.__esModule = true;
8
// Acorn: Loose parser
9
//
10
// This module provides an alternative parser (`parse_dammit`) that
11
// exposes that same interface as `parse`, but will try to parse
12
// anything as JavaScript, repairing syntax error the best it can.
13
// There are circumstances in which it will raise an error and give
14
// up, but they are very rare. The resulting AST will be a mostly
15
// valid JavaScript AST (as per the [Mozilla parser API][api], except
16
// that:
17
//
18
// - Return outside functions is allowed
19
//
20
// - Label consistency (no conflicts, break only to existing labels)
21
// is not enforced.
22
//
23
// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
24
// the parser got too confused to return anything meaningful.
25
//
26
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
27
//
28
// The expected use for this is to *first* try `acorn.parse`, and only
29
// if that fails switch to `parse_dammit`. The loose parser might
30
// parse badly indented code incorrectly, so **don't** use it as
31
// your default parser.
32
//
33
// Quite a lot of acorn.js is duplicated here. The alternative was to
34
// add a *lot* of extra cruft to that file, making it less readable
35
// and slower. Copying and editing the code allowed me to make
36
// invasive changes and simplifications without creating a complicated
37
// tangle.
38
39
var acorn = _interopRequireWildcard(_dereq_(".."));
40
41
var _state = _dereq_("./state");
42
43
var LooseParser = _state.LooseParser;
44
45
_dereq_("./tokenize");
46
47
_dereq_("./parseutil");
48
49
_dereq_("./statement");
50
51
_dereq_("./expression");
52
53
exports.LooseParser = _state.LooseParser;
54
55
acorn.defaultOptions.tabSize = 4;
56
57
function parse_dammit(input, options) {
58
var p = new LooseParser(input, options);
59
p.next();
60
return p.parseTopLevel();
61
}
62
63
acorn.parse_dammit = parse_dammit;
64
acorn.LooseParser = LooseParser;
65
66
},{"..":2,"./expression":3,"./parseutil":4,"./state":5,"./statement":6,"./tokenize":7}],2:[function(_dereq_,module,exports){
67
"use strict";
68
69
module.exports = typeof acorn != "undefined" ? acorn : _dereq_("./acorn");
70
71
},{}],3:[function(_dereq_,module,exports){
72
"use strict";
73
74
var LooseParser = _dereq_("./state").LooseParser;
75
76
var isDummy = _dereq_("./parseutil").isDummy;
77
78
var tt = _dereq_("..").tokTypes;
79
80
var lp = LooseParser.prototype;
81
82
lp.checkLVal = function (expr, binding) {
83
if (!expr) return expr;
84
switch (expr.type) {
85
case "Identifier":
86
return expr;
87
88
case "MemberExpression":
89
return binding ? this.dummyIdent() : expr;
90
91
case "ParenthesizedExpression":
92
expr.expression = this.checkLVal(expr.expression, binding);
93
return expr;
94
95
// FIXME recursively check contents
96
case "ObjectPattern":
97
case "ArrayPattern":
98
case "RestElement":
99
case "AssignmentPattern":
100
if (this.options.ecmaVersion >= 6) return expr;
101
102
default:
103
return this.dummyIdent();
104
}
105
};
106
107
lp.parseExpression = function (noIn) {
108
var start = this.storeCurrentPos();
109
var expr = this.parseMaybeAssign(noIn);
110
if (this.tok.type === tt.comma) {
111
var node = this.startNodeAt(start);
112
node.expressions = [expr];
113
while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn));
114
return this.finishNode(node, "SequenceExpression");
115
}
116
return expr;
117
};
118
119
lp.parseParenExpression = function () {
120
this.pushCx();
121
this.expect(tt.parenL);
122
var val = this.parseExpression();
123
this.popCx();
124
this.expect(tt.parenR);
125
return val;
126
};
127
128
lp.parseMaybeAssign = function (noIn) {
129
var start = this.storeCurrentPos();
130
var left = this.parseMaybeConditional(noIn);
131
if (this.tok.type.isAssign) {
132
var node = this.startNodeAt(start);
133
node.operator = this.tok.value;
134
node.left = this.tok.type === tt.eq ? this.toAssignable(left) : this.checkLVal(left);
135
this.next();
136
node.right = this.parseMaybeAssign(noIn);
137
return this.finishNode(node, "AssignmentExpression");
138
}
139
return left;
140
};
141
142
lp.parseMaybeConditional = function (noIn) {
143
var start = this.storeCurrentPos();
144
var expr = this.parseExprOps(noIn);
145
if (this.eat(tt.question)) {
146
var node = this.startNodeAt(start);
147
node.test = expr;
148
node.consequent = this.parseMaybeAssign();
149
node.alternate = this.expect(tt.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent();
150
return this.finishNode(node, "ConditionalExpression");
151
}
152
return expr;
153
};
154
155
lp.parseExprOps = function (noIn) {
156
var start = this.storeCurrentPos();
157
var indent = this.curIndent,
158
line = this.curLineStart;
159
return this.parseExprOp(this.parseMaybeUnary(noIn), start, -1, noIn, indent, line);
160
};
161
162
lp.parseExprOp = function (left, start, minPrec, noIn, indent, line) {
163
if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left;
164
var prec = this.tok.type.binop;
165
if (prec != null && (!noIn || this.tok.type !== tt._in)) {
166
if (prec > minPrec) {
167
var node = this.startNodeAt(start);
168
node.left = left;
169
node.operator = this.tok.value;
170
this.next();
171
if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) {
172
node.right = this.dummyIdent();
173
} else {
174
var rightStart = this.storeCurrentPos();
175
node.right = this.parseExprOp(this.parseMaybeUnary(noIn), rightStart, prec, noIn, indent, line);
176
}
177
this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression");
178
return this.parseExprOp(node, start, minPrec, noIn, indent, line);
179
}
180
}
181
return left;
182
};
183
184
lp.parseMaybeUnary = function (noIn) {
185
if (this.tok.type.prefix) {
186
var node = this.startNode(),
187
update = this.tok.type === tt.incDec;
188
node.operator = this.tok.value;
189
node.prefix = true;
190
this.next();
191
node.argument = this.parseMaybeUnary(noIn);
192
if (update) node.argument = this.checkLVal(node.argument);
193
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
194
} else if (this.tok.type === tt.ellipsis) {
195
var node = this.startNode();
196
this.next();
197
node.argument = this.parseMaybeUnary(noIn);
198
return this.finishNode(node, "SpreadElement");
199
}
200
var start = this.storeCurrentPos();
201
var expr = this.parseExprSubscripts();
202
while (this.tok.type.postfix && !this.canInsertSemicolon()) {
203
var node = this.startNodeAt(start);
204
node.operator = this.tok.value;
205
node.prefix = false;
206
node.argument = this.checkLVal(expr);
207
this.next();
208
expr = this.finishNode(node, "UpdateExpression");
209
}
210
return expr;
211
};
212
213
lp.parseExprSubscripts = function () {
214
var start = this.storeCurrentPos();
215
return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart);
216
};
217
218
lp.parseSubscripts = function (base, start, noCalls, startIndent, line) {
219
for (;;) {
220
if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) {
221
if (this.tok.type == tt.dot && this.curIndent == startIndent) --startIndent;else return base;
222
}
223
224
if (this.eat(tt.dot)) {
225
var node = this.startNodeAt(start);
226
node.object = base;
227
if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) node.property = this.dummyIdent();else node.property = this.parsePropertyAccessor() || this.dummyIdent();
228
node.computed = false;
229
base = this.finishNode(node, "MemberExpression");
230
} else if (this.tok.type == tt.bracketL) {
231
this.pushCx();
232
this.next();
233
var node = this.startNodeAt(start);
234
node.object = base;
235
node.property = this.parseExpression();
236
node.computed = true;
237
this.popCx();
238
this.expect(tt.bracketR);
239
base = this.finishNode(node, "MemberExpression");
240
} else if (!noCalls && this.tok.type == tt.parenL) {
241
var node = this.startNodeAt(start);
242
node.callee = base;
243
node.arguments = this.parseExprList(tt.parenR);
244
base = this.finishNode(node, "CallExpression");
245
} else if (this.tok.type == tt.backQuote) {
246
var node = this.startNodeAt(start);
247
node.tag = base;
248
node.quasi = this.parseTemplate();
249
base = this.finishNode(node, "TaggedTemplateExpression");
250
} else {
251
return base;
252
}
253
}
254
};
255
256
lp.parseExprAtom = function () {
257
var node = undefined;
258
switch (this.tok.type) {
259
case tt._this:
260
case tt._super:
261
var type = this.tok.type === tt._this ? "ThisExpression" : "Super";
262
node = this.startNode();
263
this.next();
264
return this.finishNode(node, type);
265
266
case tt.name:
267
var start = this.storeCurrentPos();
268
var id = this.parseIdent();
269
return this.eat(tt.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id]) : id;
270
271
case tt.regexp:
272
node = this.startNode();
273
var val = this.tok.value;
274
node.regex = { pattern: val.pattern, flags: val.flags };
275
node.value = val.value;
276
node.raw = this.input.slice(this.tok.start, this.tok.end);
277
this.next();
278
return this.finishNode(node, "Literal");
279
280
case tt.num:case tt.string:
281
node = this.startNode();
282
node.value = this.tok.value;
283
node.raw = this.input.slice(this.tok.start, this.tok.end);
284
this.next();
285
return this.finishNode(node, "Literal");
286
287
case tt._null:case tt._true:case tt._false:
288
node = this.startNode();
289
node.value = this.tok.type === tt._null ? null : this.tok.type === tt._true;
290
node.raw = this.tok.type.keyword;
291
this.next();
292
return this.finishNode(node, "Literal");
293
294
case tt.parenL:
295
var parenStart = this.storeCurrentPos();
296
this.next();
297
var inner = this.parseExpression();
298
this.expect(tt.parenR);
299
if (this.eat(tt.arrow)) {
300
return this.parseArrowExpression(this.startNodeAt(parenStart), inner.expressions || (isDummy(inner) ? [] : [inner]));
301
}
302
if (this.options.preserveParens) {
303
var par = this.startNodeAt(parenStart);
304
par.expression = inner;
305
inner = this.finishNode(par, "ParenthesizedExpression");
306
}
307
return inner;
308
309
case tt.bracketL:
310
node = this.startNode();
311
node.elements = this.parseExprList(tt.bracketR, true);
312
return this.finishNode(node, "ArrayExpression");
313
314
case tt.braceL:
315
return this.parseObj();
316
317
case tt._class:
318
return this.parseClass();
319
320
case tt._function:
321
node = this.startNode();
322
this.next();
323
return this.parseFunction(node, false);
324
325
case tt._new:
326
return this.parseNew();
327
328
case tt._yield:
329
node = this.startNode();
330
this.next();
331
if (this.semicolon() || this.canInsertSemicolon() || this.tok.type != tt.star && !this.tok.type.startsExpr) {
332
node.delegate = false;
333
node.argument = null;
334
} else {
335
node.delegate = this.eat(tt.star);
336
node.argument = this.parseMaybeAssign();
337
}
338
return this.finishNode(node, "YieldExpression");
339
340
case tt.backQuote:
341
return this.parseTemplate();
342
343
default:
344
return this.dummyIdent();
345
}
346
};
347
348
lp.parseNew = function () {
349
var node = this.startNode(),
350
startIndent = this.curIndent,
351
line = this.curLineStart;
352
var meta = this.parseIdent(true);
353
if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
354
node.meta = meta;
355
node.property = this.parseIdent(true);
356
return this.finishNode(node, "MetaProperty");
357
}
358
var start = this.storeCurrentPos();
359
node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line);
360
if (this.tok.type == tt.parenL) {
361
node.arguments = this.parseExprList(tt.parenR);
362
} else {
363
node.arguments = [];
364
}
365
return this.finishNode(node, "NewExpression");
366
};
367
368
lp.parseTemplateElement = function () {
369
var elem = this.startNode();
370
elem.value = {
371
raw: this.input.slice(this.tok.start, this.tok.end),
372
cooked: this.tok.value
373
};
374
this.next();
375
elem.tail = this.tok.type === tt.backQuote;
376
return this.finishNode(elem, "TemplateElement");
377
};
378
379
lp.parseTemplate = function () {
380
var node = this.startNode();
381
this.next();
382
node.expressions = [];
383
var curElt = this.parseTemplateElement();
384
node.quasis = [curElt];
385
while (!curElt.tail) {
386
this.next();
387
node.expressions.push(this.parseExpression());
388
if (this.expect(tt.braceR)) {
389
curElt = this.parseTemplateElement();
390
} else {
391
curElt = this.startNode();
392
curElt.value = { cooked: "", raw: "" };
393
curElt.tail = true;
394
}
395
node.quasis.push(curElt);
396
}
397
this.expect(tt.backQuote);
398
return this.finishNode(node, "TemplateLiteral");
399
};
400
401
lp.parseObj = function () {
402
var node = this.startNode();
403
node.properties = [];
404
this.pushCx();
405
var indent = this.curIndent + 1,
406
line = this.curLineStart;
407
this.eat(tt.braceL);
408
if (this.curIndent + 1 < indent) {
409
indent = this.curIndent;line = this.curLineStart;
410
}
411
while (!this.closes(tt.braceR, indent, line)) {
412
var prop = this.startNode(),
413
isGenerator = undefined,
414
start = undefined;
415
if (this.options.ecmaVersion >= 6) {
416
start = this.storeCurrentPos();
417
prop.method = false;
418
prop.shorthand = false;
419
isGenerator = this.eat(tt.star);
420
}
421
this.parsePropertyName(prop);
422
if (isDummy(prop.key)) {
423
if (isDummy(this.parseMaybeAssign())) this.next();this.eat(tt.comma);continue;
424
}
425
if (this.eat(tt.colon)) {
426
prop.kind = "init";
427
prop.value = this.parseMaybeAssign();
428
} else if (this.options.ecmaVersion >= 6 && (this.tok.type === tt.parenL || this.tok.type === tt.braceL)) {
429
prop.kind = "init";
430
prop.method = true;
431
prop.value = this.parseMethod(isGenerator);
432
} else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && (this.tok.type != tt.comma && this.tok.type != tt.braceR)) {
433
prop.kind = prop.key.name;
434
this.parsePropertyName(prop);
435
prop.value = this.parseMethod(false);
436
} else {
437
prop.kind = "init";
438
if (this.options.ecmaVersion >= 6) {
439
if (this.eat(tt.eq)) {
440
var assign = this.startNodeAt(start);
441
assign.operator = "=";
442
assign.left = prop.key;
443
assign.right = this.parseMaybeAssign();
444
prop.value = this.finishNode(assign, "AssignmentExpression");
445
} else {
446
prop.value = prop.key;
447
}
448
} else {
449
prop.value = this.dummyIdent();
450
}
451
prop.shorthand = true;
452
}
453
node.properties.push(this.finishNode(prop, "Property"));
454
this.eat(tt.comma);
455
}
456
this.popCx();
457
if (!this.eat(tt.braceR)) {
458
// If there is no closing brace, make the node span to the start
459
// of the next token (this is useful for Tern)
460
this.last.end = this.tok.start;
461
if (this.options.locations) this.last.loc.end = this.tok.loc.start;
462
}
463
return this.finishNode(node, "ObjectExpression");
464
};
465
466
lp.parsePropertyName = function (prop) {
467
if (this.options.ecmaVersion >= 6) {
468
if (this.eat(tt.bracketL)) {
469
prop.computed = true;
470
prop.key = this.parseExpression();
471
this.expect(tt.bracketR);
472
return;
473
} else {
474
prop.computed = false;
475
}
476
}
477
var key = this.tok.type === tt.num || this.tok.type === tt.string ? this.parseExprAtom() : this.parseIdent();
478
prop.key = key || this.dummyIdent();
479
};
480
481
lp.parsePropertyAccessor = function () {
482
if (this.tok.type === tt.name || this.tok.type.keyword) return this.parseIdent();
483
};
484
485
lp.parseIdent = function () {
486
var name = this.tok.type === tt.name ? this.tok.value : this.tok.type.keyword;
487
if (!name) return this.dummyIdent();
488
var node = this.startNode();
489
this.next();
490
node.name = name;
491
return this.finishNode(node, "Identifier");
492
};
493
494
lp.initFunction = function (node) {
495
node.id = null;
496
node.params = [];
497
if (this.options.ecmaVersion >= 6) {
498
node.generator = false;
499
node.expression = false;
500
}
501
};
502
503
// Convert existing expression atom to assignable pattern
504
// if possible.
505
506
lp.toAssignable = function (node, binding) {
507
if (this.options.ecmaVersion >= 6 && node) {
508
switch (node.type) {
509
case "ObjectExpression":
510
node.type = "ObjectPattern";
511
var props = node.properties;
512
for (var i = 0; i < props.length; i++) {
513
this.toAssignable(props[i].value, binding);
514
}break;
515
516
case "ArrayExpression":
517
node.type = "ArrayPattern";
518
this.toAssignableList(node.elements, binding);
519
break;
520
521
case "SpreadElement":
522
node.type = "RestElement";
523
node.argument = this.toAssignable(node.argument, binding);
524
break;
525
526
case "AssignmentExpression":
527
node.type = "AssignmentPattern";
528
break;
529
}
530
}
531
return this.checkLVal(node, binding);
532
};
533
534
lp.toAssignableList = function (exprList, binding) {
535
for (var i = 0; i < exprList.length; i++) {
536
exprList[i] = this.toAssignable(exprList[i], binding);
537
}return exprList;
538
};
539
540
lp.parseFunctionParams = function (params) {
541
params = this.parseExprList(tt.parenR);
542
return this.toAssignableList(params, true);
543
};
544
545
lp.parseMethod = function (isGenerator) {
546
var node = this.startNode();
547
this.initFunction(node);
548
node.params = this.parseFunctionParams();
549
node.generator = isGenerator || false;
550
node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tt.braceL;
551
node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();
552
return this.finishNode(node, "FunctionExpression");
553
};
554
555
lp.parseArrowExpression = function (node, params) {
556
this.initFunction(node);
557
node.params = this.toAssignableList(params, true);
558
node.expression = this.tok.type !== tt.braceL;
559
node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();
560
return this.finishNode(node, "ArrowFunctionExpression");
561
};
562
563
lp.parseExprList = function (close, allowEmpty) {
564
this.pushCx();
565
var indent = this.curIndent,
566
line = this.curLineStart,
567
elts = [];
568
this.next(); // Opening bracket
569
while (!this.closes(close, indent + 1, line)) {
570
if (this.eat(tt.comma)) {
571
elts.push(allowEmpty ? null : this.dummyIdent());
572
continue;
573
}
574
var elt = this.parseMaybeAssign();
575
if (isDummy(elt)) {
576
if (this.closes(close, indent, line)) break;
577
this.next();
578
} else {
579
elts.push(elt);
580
}
581
this.eat(tt.comma);
582
}
583
this.popCx();
584
if (!this.eat(close)) {
585
// If there is no closing brace, make the node span to the start
586
// of the next token (this is useful for Tern)
587
this.last.end = this.tok.start;
588
if (this.options.locations) this.last.loc.end = this.tok.loc.start;
589
}
590
return elts;
591
};
592
593
},{"..":2,"./parseutil":4,"./state":5}],4:[function(_dereq_,module,exports){
594
"use strict";
595
596
exports.isDummy = isDummy;
597
exports.__esModule = true;
598
599
var LooseParser = _dereq_("./state").LooseParser;
600
601
var _ = _dereq_("..");
602
603
var Node = _.Node;
604
var SourceLocation = _.SourceLocation;
605
var lineBreak = _.lineBreak;
606
var isNewLine = _.isNewLine;
607
var tt = _.tokTypes;
608
609
var lp = LooseParser.prototype;
610
611
lp.startNode = function () {
612
var node = new Node();
613
node.start = this.tok.start;
614
if (this.options.locations) node.loc = new SourceLocation(this.toks, this.tok.loc.start);
615
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
616
if (this.options.ranges) node.range = [this.tok.start, 0];
617
return node;
618
};
619
620
lp.storeCurrentPos = function () {
621
return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start;
622
};
623
624
lp.startNodeAt = function (pos) {
625
var node = new Node();
626
if (this.options.locations) {
627
node.start = pos[0];
628
node.loc = new SourceLocation(this.toks, pos[1]);
629
pos = pos[0];
630
} else {
631
node.start = pos;
632
}
633
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
634
if (this.options.ranges) node.range = [pos, 0];
635
return node;
636
};
637
638
lp.finishNode = function (node, type) {
639
node.type = type;
640
node.end = this.last.end;
641
if (this.options.locations) node.loc.end = this.last.loc.end;
642
if (this.options.ranges) node.range[1] = this.last.end;
643
return node;
644
};
645
646
lp.dummyIdent = function () {
647
var dummy = this.startNode();
648
dummy.name = "✖";
649
return this.finishNode(dummy, "Identifier");
650
};
651
652
function isDummy(node) {
653
return node.name == "✖";
654
}
655
656
lp.eat = function (type) {
657
if (this.tok.type === type) {
658
this.next();
659
return true;
660
} else {
661
return false;
662
}
663
};
664
665
lp.isContextual = function (name) {
666
return this.tok.type === tt.name && this.tok.value === name;
667
};
668
669
lp.eatContextual = function (name) {
670
return this.tok.value === name && this.eat(tt.name);
671
};
672
673
lp.canInsertSemicolon = function () {
674
return this.tok.type === tt.eof || this.tok.type === tt.braceR || lineBreak.test(this.input.slice(this.last.end, this.tok.start));
675
};
676
677
lp.semicolon = function () {
678
return this.eat(tt.semi);
679
};
680
681
lp.expect = function (type) {
682
if (this.eat(type)) return true;
683
for (var i = 1; i <= 2; i++) {
684
if (this.lookAhead(i).type == type) {
685
for (var j = 0; j < i; j++) {
686
this.next();
687
}return true;
688
}
689
}
690
};
691
692
lp.pushCx = function () {
693
this.context.push(this.curIndent);
694
};
695
lp.popCx = function () {
696
this.curIndent = this.context.pop();
697
};
698
699
lp.lineEnd = function (pos) {
700
while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos;
701
return pos;
702
};
703
704
lp.indentationAfter = function (pos) {
705
for (var count = 0;; ++pos) {
706
var ch = this.input.charCodeAt(pos);
707
if (ch === 32) ++count;else if (ch === 9) count += this.options.tabSize;else return count;
708
}
709
};
710
711
lp.closes = function (closeTok, indent, line, blockHeuristic) {
712
if (this.tok.type === closeTok || this.tok.type === tt.eof) return true;
713
return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && (!blockHeuristic || this.nextLineStart >= this.input.length || this.indentationAfter(this.nextLineStart) < indent);
714
};
715
716
lp.tokenStartsLine = function () {
717
for (var p = this.tok.start - 1; p >= this.curLineStart; --p) {
718
var ch = this.input.charCodeAt(p);
719
if (ch !== 9 && ch !== 32) return false;
720
}
721
return true;
722
};
723
724
},{"..":2,"./state":5}],5:[function(_dereq_,module,exports){
725
"use strict";
726
727
exports.LooseParser = LooseParser;
728
exports.__esModule = true;
729
730
var _ = _dereq_("..");
731
732
var tokenizer = _.tokenizer;
733
var SourceLocation = _.SourceLocation;
734
var tt = _.tokTypes;
735
736
function LooseParser(input, options) {
737
this.toks = tokenizer(input, options);
738
this.options = this.toks.options;
739
this.input = this.toks.input;
740
this.tok = this.last = { type: tt.eof, start: 0, end: 0 };
741
if (this.options.locations) {
742
var here = this.toks.curPosition();
743
this.tok.loc = new SourceLocation(this.toks, here, here);
744
}
745
this.ahead = []; // Tokens ahead
746
this.context = []; // Indentation contexted
747
this.curIndent = 0;
748
this.curLineStart = 0;
749
this.nextLineStart = this.lineEnd(this.curLineStart) + 1;
750
}
751
752
},{"..":2}],6:[function(_dereq_,module,exports){
753
"use strict";
754
755
var LooseParser = _dereq_("./state").LooseParser;
756
757
var isDummy = _dereq_("./parseutil").isDummy;
758
759
var _ = _dereq_("..");
760
761
var getLineInfo = _.getLineInfo;
762
var tt = _.tokTypes;
763
764
var lp = LooseParser.prototype;
765
766
lp.parseTopLevel = function () {
767
var node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0);
768
node.body = [];
769
while (this.tok.type !== tt.eof) node.body.push(this.parseStatement());
770
this.last = this.tok;
771
if (this.options.ecmaVersion >= 6) {
772
node.sourceType = this.options.sourceType;
773
}
774
return this.finishNode(node, "Program");
775
};
776
777
lp.parseStatement = function () {
778
var starttype = this.tok.type,
779
node = this.startNode();
780
781
switch (starttype) {
782
case tt._break:case tt._continue:
783
this.next();
784
var isBreak = starttype === tt._break;
785
if (this.semicolon() || this.canInsertSemicolon()) {
786
node.label = null;
787
} else {
788
node.label = this.tok.type === tt.name ? this.parseIdent() : null;
789
this.semicolon();
790
}
791
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
792
793
case tt._debugger:
794
this.next();
795
this.semicolon();
796
return this.finishNode(node, "DebuggerStatement");
797
798
case tt._do:
799
this.next();
800
node.body = this.parseStatement();
801
node.test = this.eat(tt._while) ? this.parseParenExpression() : this.dummyIdent();
802
this.semicolon();
803
return this.finishNode(node, "DoWhileStatement");
804
805
case tt._for:
806
this.next();
807
this.pushCx();
808
this.expect(tt.parenL);
809
if (this.tok.type === tt.semi) return this.parseFor(node, null);
810
if (this.tok.type === tt._var || this.tok.type === tt._let || this.tok.type === tt._const) {
811
var _init = this.parseVar(true);
812
if (_init.declarations.length === 1 && (this.tok.type === tt._in || this.isContextual("of"))) {
813
return this.parseForIn(node, _init);
814
}
815
return this.parseFor(node, _init);
816
}
817
var init = this.parseExpression(true);
818
if (this.tok.type === tt._in || this.isContextual("of")) return this.parseForIn(node, this.toAssignable(init));
819
return this.parseFor(node, init);
820
821
case tt._function:
822
this.next();
823
return this.parseFunction(node, true);
824
825
case tt._if:
826
this.next();
827
node.test = this.parseParenExpression();
828
node.consequent = this.parseStatement();
829
node.alternate = this.eat(tt._else) ? this.parseStatement() : null;
830
return this.finishNode(node, "IfStatement");
831
832
case tt._return:
833
this.next();
834
if (this.eat(tt.semi) || this.canInsertSemicolon()) node.argument = null;else {
835
node.argument = this.parseExpression();this.semicolon();
836
}
837
return this.finishNode(node, "ReturnStatement");
838
839
case tt._switch:
840
var blockIndent = this.curIndent,
841
line = this.curLineStart;
842
this.next();
843
node.discriminant = this.parseParenExpression();
844
node.cases = [];
845
this.pushCx();
846
this.expect(tt.braceL);
847
848
var cur = undefined;
849
while (!this.closes(tt.braceR, blockIndent, line, true)) {
850
if (this.tok.type === tt._case || this.tok.type === tt._default) {
851
var isCase = this.tok.type === tt._case;
852
if (cur) this.finishNode(cur, "SwitchCase");
853
node.cases.push(cur = this.startNode());
854
cur.consequent = [];
855
this.next();
856
if (isCase) cur.test = this.parseExpression();else cur.test = null;
857
this.expect(tt.colon);
858
} else {
859
if (!cur) {
860
node.cases.push(cur = this.startNode());
861
cur.consequent = [];
862
cur.test = null;
863
}
864
cur.consequent.push(this.parseStatement());
865
}
866
}
867
if (cur) this.finishNode(cur, "SwitchCase");
868
this.popCx();
869
this.eat(tt.braceR);
870
return this.finishNode(node, "SwitchStatement");
871
872
case tt._throw:
873
this.next();
874
node.argument = this.parseExpression();
875
this.semicolon();
876
return this.finishNode(node, "ThrowStatement");
877
878
case tt._try:
879
this.next();
880
node.block = this.parseBlock();
881
node.handler = null;
882
if (this.tok.type === tt._catch) {
883
var clause = this.startNode();
884
this.next();
885
this.expect(tt.parenL);
886
clause.param = this.toAssignable(this.parseExprAtom(), true);
887
this.expect(tt.parenR);
888
clause.guard = null;
889
clause.body = this.parseBlock();
890
node.handler = this.finishNode(clause, "CatchClause");
891
}
892
node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
893
if (!node.handler && !node.finalizer) return node.block;
894
return this.finishNode(node, "TryStatement");
895
896
case tt._var:
897
case tt._let:
898
case tt._const:
899
return this.parseVar();
900
901
case tt._while:
902
this.next();
903
node.test = this.parseParenExpression();
904
node.body = this.parseStatement();
905
return this.finishNode(node, "WhileStatement");
906
907
case tt._with:
908
this.next();
909
node.object = this.parseParenExpression();
910
node.body = this.parseStatement();
911
return this.finishNode(node, "WithStatement");
912
913
case tt.braceL:
914
return this.parseBlock();
915
916
case tt.semi:
917
this.next();
918
return this.finishNode(node, "EmptyStatement");
919
920
case tt._class:
921
return this.parseClass(true);
922
923
case tt._import:
924
return this.parseImport();
925
926
case tt._export:
927
return this.parseExport();
928
929
default:
930
var expr = this.parseExpression();
931
if (isDummy(expr)) {
932
this.next();
933
if (this.tok.type === tt.eof) return this.finishNode(node, "EmptyStatement");
934
return this.parseStatement();
935
} else if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) {
936
node.body = this.parseStatement();
937
node.label = expr;
938
return this.finishNode(node, "LabeledStatement");
939
} else {
940
node.expression = expr;
941
this.semicolon();
942
return this.finishNode(node, "ExpressionStatement");
943
}
944
}
945
};
946
947
lp.parseBlock = function () {
948
var node = this.startNode();
949
this.pushCx();
950
this.expect(tt.braceL);
951
var blockIndent = this.curIndent,
952
line = this.curLineStart;
953
node.body = [];
954
while (!this.closes(tt.braceR, blockIndent, line, true)) node.body.push(this.parseStatement());
955
this.popCx();
956
this.eat(tt.braceR);
957
return this.finishNode(node, "BlockStatement");
958
};
959
960
lp.parseFor = function (node, init) {
961
node.init = init;
962
node.test = node.update = null;
963
if (this.eat(tt.semi) && this.tok.type !== tt.semi) node.test = this.parseExpression();
964
if (this.eat(tt.semi) && this.tok.type !== tt.parenR) node.update = this.parseExpression();
965
this.popCx();
966
this.expect(tt.parenR);
967
node.body = this.parseStatement();
968
return this.finishNode(node, "ForStatement");
969
};
970
971
lp.parseForIn = function (node, init) {
972
var type = this.tok.type === tt._in ? "ForInStatement" : "ForOfStatement";
973
this.next();
974
node.left = init;
975
node.right = this.parseExpression();
976
this.popCx();
977
this.expect(tt.parenR);
978
node.body = this.parseStatement();
979
return this.finishNode(node, type);
980
};
981
982
lp.parseVar = function (noIn) {
983
var node = this.startNode();
984
node.kind = this.tok.type.keyword;
985
this.next();
986
node.declarations = [];
987
do {
988
var decl = this.startNode();
989
decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent();
990
decl.init = this.eat(tt.eq) ? this.parseMaybeAssign(noIn) : null;
991
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
992
} while (this.eat(tt.comma));
993
if (!node.declarations.length) {
994
var decl = this.startNode();
995
decl.id = this.dummyIdent();
996
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
997
}
998
if (!noIn) this.semicolon();
999
return this.finishNode(node, "VariableDeclaration");
1000
};
1001
1002
lp.parseClass = function (isStatement) {
1003
var node = this.startNode();
1004
this.next();
1005
if (this.tok.type === tt.name) node.id = this.parseIdent();else if (isStatement) node.id = this.dummyIdent();else node.id = null;
1006
node.superClass = this.eat(tt._extends) ? this.parseExpression() : null;
1007
node.body = this.startNode();
1008
node.body.body = [];
1009
this.pushCx();
1010
var indent = this.curIndent + 1,
1011
line = this.curLineStart;
1012
this.eat(tt.braceL);
1013
if (this.curIndent + 1 < indent) {
1014
indent = this.curIndent;line = this.curLineStart;
1015
}
1016
while (!this.closes(tt.braceR, indent, line)) {
1017
if (this.semicolon()) continue;
1018
var method = this.startNode(),
1019
isGenerator = undefined;
1020
if (this.options.ecmaVersion >= 6) {
1021
method["static"] = false;
1022
isGenerator = this.eat(tt.star);
1023
}
1024
this.parsePropertyName(method);
1025
if (isDummy(method.key)) {
1026
if (isDummy(this.parseMaybeAssign())) this.next();this.eat(tt.comma);continue;
1027
}
1028
if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" && (this.tok.type != tt.parenL && this.tok.type != tt.braceL)) {
1029
method["static"] = true;
1030
isGenerator = this.eat(tt.star);
1031
this.parsePropertyName(method);
1032
} else {
1033
method["static"] = false;
1034
}
1035
if (this.options.ecmaVersion >= 5 && method.key.type === "Identifier" && !method.computed && (method.key.name === "get" || method.key.name === "set") && this.tok.type !== tt.parenL && this.tok.type !== tt.braceL) {
1036
method.kind = method.key.name;
1037
this.parsePropertyName(method);
1038
method.value = this.parseMethod(false);
1039
} else {
1040
if (!method.computed && !method["static"] && !isGenerator && (method.key.type === "Identifier" && method.key.name === "constructor" || method.key.type === "Literal" && method.key.value === "constructor")) {
1041
method.kind = "constructor";
1042
} else {
1043
method.kind = "method";
1044
}
1045
method.value = this.parseMethod(isGenerator);
1046
}
1047
node.body.body.push(this.finishNode(method, "MethodDefinition"));
1048
}
1049
this.popCx();
1050
if (!this.eat(tt.braceR)) {
1051
// If there is no closing brace, make the node span to the start
1052
// of the next token (this is useful for Tern)
1053
this.last.end = this.tok.start;
1054
if (this.options.locations) this.last.loc.end = this.tok.loc.start;
1055
}
1056
this.semicolon();
1057
this.finishNode(node.body, "ClassBody");
1058
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
1059
};
1060
1061
lp.parseFunction = function (node, isStatement) {
1062
this.initFunction(node);
1063
if (this.options.ecmaVersion >= 6) {
1064
node.generator = this.eat(tt.star);
1065
}
1066
if (this.tok.type === tt.name) node.id = this.parseIdent();else if (isStatement) node.id = this.dummyIdent();
1067
node.params = this.parseFunctionParams();
1068
node.body = this.parseBlock();
1069
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
1070
};
1071
1072
lp.parseExport = function () {
1073
var node = this.startNode();
1074
this.next();
1075
if (this.eat(tt.star)) {
1076
node.source = this.eatContextual("from") ? this.parseExprAtom() : null;
1077
return this.finishNode(node, "ExportAllDeclaration");
1078
}
1079
if (this.eat(tt._default)) {
1080
var expr = this.parseMaybeAssign();
1081
if (expr.id) {
1082
switch (expr.type) {
1083
case "FunctionExpression":
1084
expr.type = "FunctionDeclaration";break;
1085
case "ClassExpression":
1086
expr.type = "ClassDeclaration";break;
1087
}
1088
}
1089
node.declaration = expr;
1090
this.semicolon();
1091
return this.finishNode(node, "ExportDefaultDeclaration");
1092
}
1093
if (this.tok.type.keyword) {
1094
node.declaration = this.parseStatement();
1095
node.specifiers = [];
1096
node.source = null;
1097
} else {
1098
node.declaration = null;
1099
node.specifiers = this.parseExportSpecifierList();
1100
node.source = this.eatContextual("from") ? this.parseExprAtom() : null;
1101
this.semicolon();
1102
}
1103
return this.finishNode(node, "ExportNamedDeclaration");
1104
};
1105
1106
lp.parseImport = function () {
1107
var node = this.startNode();
1108
this.next();
1109
if (this.tok.type === tt.string) {
1110
node.specifiers = [];
1111
node.source = this.parseExprAtom();
1112
node.kind = "";
1113
} else {
1114
var elt = undefined;
1115
if (this.tok.type === tt.name && this.tok.value !== "from") {
1116
elt = this.startNode();
1117
elt.local = this.parseIdent();
1118
this.finishNode(elt, "ImportDefaultSpecifier");
1119
this.eat(tt.comma);
1120
}
1121
node.specifiers = this.parseImportSpecifierList();
1122
node.source = this.eatContextual("from") ? this.parseExprAtom() : null;
1123
if (elt) node.specifiers.unshift(elt);
1124
}
1125
this.semicolon();
1126
return this.finishNode(node, "ImportDeclaration");
1127
};
1128
1129
lp.parseImportSpecifierList = function () {
1130
var elts = [];
1131
if (this.tok.type === tt.star) {
1132
var elt = this.startNode();
1133
this.next();
1134
if (this.eatContextual("as")) elt.local = this.parseIdent();
1135
elts.push(this.finishNode(elt, "ImportNamespaceSpecifier"));
1136
} else {
1137
var indent = this.curIndent,
1138
line = this.curLineStart,
1139
continuedLine = this.nextLineStart;
1140
this.pushCx();
1141
this.eat(tt.braceL);
1142
if (this.curLineStart > continuedLine) continuedLine = this.curLineStart;
1143
while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
1144
var elt = this.startNode();
1145
if (this.eat(tt.star)) {
1146
if (this.eatContextual("as")) elt.local = this.parseIdent();
1147
this.finishNode(elt, "ImportNamespaceSpecifier");
1148
} else {
1149
if (this.isContextual("from")) break;
1150
elt.imported = this.parseIdent();
1151
elt.local = this.eatContextual("as") ? this.parseIdent() : elt.imported;
1152
this.finishNode(elt, "ImportSpecifier");
1153
}
1154
elts.push(elt);
1155
this.eat(tt.comma);
1156
}
1157
this.eat(tt.braceR);
1158
this.popCx();
1159
}
1160
return elts;
1161
};
1162
1163
lp.parseExportSpecifierList = function () {
1164
var elts = [];
1165
var indent = this.curIndent,
1166
line = this.curLineStart,
1167
continuedLine = this.nextLineStart;
1168
this.pushCx();
1169
this.eat(tt.braceL);
1170
if (this.curLineStart > continuedLine) continuedLine = this.curLineStart;
1171
while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
1172
if (this.isContextual("from")) break;
1173
var elt = this.startNode();
1174
elt.local = this.parseIdent();
1175
elt.exported = this.eatContextual("as") ? this.parseIdent() : elt.local;
1176
this.finishNode(elt, "ExportSpecifier");
1177
elts.push(elt);
1178
this.eat(tt.comma);
1179
}
1180
this.eat(tt.braceR);
1181
this.popCx();
1182
return elts;
1183
};
1184
1185
},{"..":2,"./parseutil":4,"./state":5}],7:[function(_dereq_,module,exports){
1186
"use strict";
1187
1188
var _ = _dereq_("..");
1189
1190
var tt = _.tokTypes;
1191
var Token = _.Token;
1192
var isNewLine = _.isNewLine;
1193
var SourceLocation = _.SourceLocation;
1194
var getLineInfo = _.getLineInfo;
1195
var lineBreakG = _.lineBreakG;
1196
1197
var LooseParser = _dereq_("./state").LooseParser;
1198
1199
var lp = LooseParser.prototype;
1200
1201
function isSpace(ch) {
1202
return ch < 14 && ch > 8 || ch === 32 || ch === 160 || isNewLine(ch);
1203
}
1204
1205
lp.next = function () {
1206
this.last = this.tok;
1207
if (this.ahead.length) this.tok = this.ahead.shift();else this.tok = this.readToken();
1208
1209
if (this.tok.start >= this.nextLineStart) {
1210
while (this.tok.start >= this.nextLineStart) {
1211
this.curLineStart = this.nextLineStart;
1212
this.nextLineStart = this.lineEnd(this.curLineStart) + 1;
1213
}
1214
this.curIndent = this.indentationAfter(this.curLineStart);
1215
}
1216
};
1217
1218
lp.readToken = function () {
1219
for (;;) {
1220
try {
1221
this.toks.next();
1222
if (this.toks.type === tt.dot && this.input.substr(this.toks.end, 1) === "." && this.options.ecmaVersion >= 6) {
1223
this.toks.end++;
1224
this.toks.type = tt.ellipsis;
1225
}
1226
return new Token(this.toks);
1227
} catch (e) {
1228
if (!(e instanceof SyntaxError)) throw e;
1229
1230
// Try to skip some text, based on the error message, and then continue
1231
var msg = e.message,
1232
pos = e.raisedAt,
1233
replace = true;
1234
if (/unterminated/i.test(msg)) {
1235
pos = this.lineEnd(e.pos + 1);
1236
if (/string/.test(msg)) {
1237
replace = { start: e.pos, end: pos, type: tt.string, value: this.input.slice(e.pos + 1, pos) };
1238
} else if (/regular expr/i.test(msg)) {
1239
var re = this.input.slice(e.pos, pos);
1240
try {
1241
re = new RegExp(re);
1242
} catch (e) {}
1243
replace = { start: e.pos, end: pos, type: tt.regexp, value: re };
1244
} else if (/template/.test(msg)) {
1245
replace = { start: e.pos, end: pos,
1246
type: tt.template,
1247
value: this.input.slice(e.pos, pos) };
1248
} else {
1249
replace = false;
1250
}
1251
} else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {
1252
while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos;
1253
} else if (/character escape|expected hexadecimal/i.test(msg)) {
1254
while (pos < this.input.length) {
1255
var ch = this.input.charCodeAt(pos++);
1256
if (ch === 34 || ch === 39 || isNewLine(ch)) break;
1257
}
1258
} else if (/unexpected character/i.test(msg)) {
1259
pos++;
1260
replace = false;
1261
} else if (/regular expression/i.test(msg)) {
1262
replace = true;
1263
} else {
1264
throw e;
1265
}
1266
this.resetTo(pos);
1267
if (replace === true) replace = { start: pos, end: pos, type: tt.name, value: "✖" };
1268
if (replace) {
1269
if (this.options.locations) replace.loc = new SourceLocation(this.toks, getLineInfo(this.input, replace.start), getLineInfo(this.input, replace.end));
1270
return replace;
1271
}
1272
}
1273
}
1274
};
1275
1276
lp.resetTo = function (pos) {
1277
this.toks.pos = pos;
1278
var ch = this.input.charAt(pos - 1);
1279
this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos));
1280
1281
if (this.options.locations) {
1282
this.toks.curLine = 1;
1283
this.toks.lineStart = lineBreakG.lastIndex = 0;
1284
var match = undefined;
1285
while ((match = lineBreakG.exec(this.input)) && match.index < pos) {
1286
++this.toks.curLine;
1287
this.toks.lineStart = match.index + match[0].length;
1288
}
1289
}
1290
};
1291
1292
lp.lookAhead = function (n) {
1293
while (n > this.ahead.length) this.ahead.push(this.readToken());
1294
return this.ahead[n - 1];
1295
};
1296
1297
},{"..":2,"./state":5}]},{},[1])(1)
1298
});
1299