esperanto-source 0.6.17.1 → 0.6.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/esperanto/source/version.rb +1 -1
- data/vendor/acorn.js +531 -347
- metadata +1 -1
data/vendor/acorn.js
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
})(this, function(exports) {
|
29
29
|
"use strict";
|
30
30
|
|
31
|
-
exports.version = "0.
|
31
|
+
exports.version = "0.12.0";
|
32
32
|
|
33
33
|
// The main exported interface (under `self.acorn` when in the
|
34
34
|
// browser) is a `parse` function that takes a code string and
|
@@ -74,6 +74,9 @@
|
|
74
74
|
// When enabled, import/export statements are not constrained to
|
75
75
|
// appearing at the top of the program.
|
76
76
|
allowImportExportEverywhere: false,
|
77
|
+
// When enabled, hashbang directive in the beginning of file
|
78
|
+
// is allowed and treated as a line comment.
|
79
|
+
allowHashBang: false,
|
77
80
|
// When `locations` is on, `loc` properties holding objects with
|
78
81
|
// `start` and `end` properties in `{line, column}` form (with
|
79
82
|
// line being 1-based and column 0-based) will be attached to the
|
@@ -197,9 +200,6 @@
|
|
197
200
|
if (options.locations) {
|
198
201
|
this.loc = new SourceLocation();
|
199
202
|
this.loc.end = tokEndLoc;
|
200
|
-
// TODO: remove in next major release
|
201
|
-
this.startLoc = tokStartLoc;
|
202
|
-
this.endLoc = tokEndLoc;
|
203
203
|
}
|
204
204
|
if (options.ranges)
|
205
205
|
this.range = [tokStart, tokEnd];
|
@@ -220,12 +220,12 @@
|
|
220
220
|
initTokenState();
|
221
221
|
skipSpace();
|
222
222
|
|
223
|
-
function getToken(
|
223
|
+
function getToken() {
|
224
224
|
lastEnd = tokEnd;
|
225
|
-
readToken(
|
225
|
+
readToken();
|
226
226
|
return new Token();
|
227
227
|
}
|
228
|
-
getToken.jumpTo = function(pos,
|
228
|
+
getToken.jumpTo = function(pos, exprAllowed) {
|
229
229
|
tokPos = pos;
|
230
230
|
if (options.locations) {
|
231
231
|
tokCurLine = 1;
|
@@ -236,12 +236,23 @@
|
|
236
236
|
tokLineStart = match.index + match[0].length;
|
237
237
|
}
|
238
238
|
}
|
239
|
-
|
239
|
+
tokExprAllowed = !!exprAllowed;
|
240
240
|
skipSpace();
|
241
241
|
};
|
242
|
-
getToken.
|
243
|
-
|
244
|
-
|
242
|
+
getToken.current = function() { return new Token(); };
|
243
|
+
if (typeof Symbol !== 'undefined') {
|
244
|
+
getToken[Symbol.iterator] = function () {
|
245
|
+
return {
|
246
|
+
next: function () {
|
247
|
+
var token = getToken();
|
248
|
+
return {
|
249
|
+
done: token.type === _eof,
|
250
|
+
value: token
|
251
|
+
};
|
252
|
+
}
|
253
|
+
};
|
254
|
+
};
|
255
|
+
}
|
245
256
|
getToken.options = options;
|
246
257
|
return getToken;
|
247
258
|
};
|
@@ -274,12 +285,13 @@
|
|
274
285
|
|
275
286
|
// Internal state for the tokenizer. To distinguish between division
|
276
287
|
// operators and regular expressions, it remembers whether the last
|
277
|
-
// token was one that is allowed to be followed by an expression.
|
278
|
-
//
|
279
|
-
//
|
280
|
-
//
|
288
|
+
// token was one that is allowed to be followed by an expression. In
|
289
|
+
// some cases, notably after ')' or '}' tokens, the situation
|
290
|
+
// depends on the context before the matching opening bracket, so
|
291
|
+
// tokContext keeps a stack of information about current bracketed
|
292
|
+
// forms.
|
281
293
|
|
282
|
-
var
|
294
|
+
var tokContext, tokExprAllowed;
|
283
295
|
|
284
296
|
// When `options.locations` is true, these are used to keep
|
285
297
|
// track of the current line, and know when a new line has been
|
@@ -300,22 +312,10 @@
|
|
300
312
|
|
301
313
|
var inFunction, inGenerator, labels, strict;
|
302
314
|
|
303
|
-
// This counter is used for checking that arrow expressions did
|
304
|
-
// not contain nested parentheses in argument list.
|
305
|
-
|
306
|
-
var metParenL;
|
307
|
-
|
308
|
-
// This is used by the tokenizer to track the template strings it is
|
309
|
-
// inside, and count the amount of open braces seen inside them, to
|
310
|
-
// be able to switch back to a template token when the } to match ${
|
311
|
-
// is encountered. It will hold an array of integers.
|
312
|
-
|
313
|
-
var templates;
|
314
|
-
|
315
315
|
function initParserState() {
|
316
316
|
lastStart = lastEnd = tokPos;
|
317
317
|
if (options.locations) lastEndLoc = curPosition();
|
318
|
-
inFunction = inGenerator =
|
318
|
+
inFunction = inGenerator = false;
|
319
319
|
labels = [];
|
320
320
|
skipSpace();
|
321
321
|
readToken();
|
@@ -413,8 +413,9 @@
|
|
413
413
|
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
|
414
414
|
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
|
415
415
|
var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
|
416
|
-
var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"}
|
417
|
-
var _ellipsis = {type: "...",
|
416
|
+
var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"};
|
417
|
+
var _ellipsis = {type: "...", beforeExpr: true};
|
418
|
+
var _backQuote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
|
418
419
|
|
419
420
|
// Operators. These carry several kinds of properties to help the
|
420
421
|
// parser use them properly (the presence of these properties is
|
@@ -456,8 +457,8 @@
|
|
456
457
|
parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
|
457
458
|
dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
|
458
459
|
name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
|
459
|
-
arrow: _arrow, template: _template,
|
460
|
-
|
460
|
+
arrow: _arrow, template: _template, star: _star, assign: _assign,
|
461
|
+
backQuote: _backQuote, dollarBraceL: _dollarBraceL};
|
461
462
|
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
|
462
463
|
|
463
464
|
// This is a trick taken from Esprima. It turns out that, on
|
@@ -595,7 +596,7 @@
|
|
595
596
|
|
596
597
|
Position.prototype.offset = function(n) {
|
597
598
|
return new Position(this.line, this.column + n);
|
598
|
-
}
|
599
|
+
};
|
599
600
|
|
600
601
|
function curPosition() {
|
601
602
|
return new Position(tokCurLine, tokPos - tokLineStart);
|
@@ -612,25 +613,95 @@
|
|
612
613
|
tokCurLine = 1;
|
613
614
|
tokPos = tokLineStart = 0;
|
614
615
|
}
|
615
|
-
|
616
|
-
|
617
|
-
|
616
|
+
tokType = _eof;
|
617
|
+
tokContext = [b_stat];
|
618
|
+
tokExprAllowed = true;
|
619
|
+
strict = false;
|
620
|
+
if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') {
|
621
|
+
skipLineComment(2);
|
622
|
+
}
|
623
|
+
}
|
624
|
+
|
625
|
+
// The algorithm used to determine whether a regexp can appear at a
|
626
|
+
// given point in the program is loosely based on sweet.js' approach.
|
627
|
+
// See https://github.com/mozilla/sweet.js/wiki/design
|
628
|
+
|
629
|
+
var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true};
|
630
|
+
var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true};
|
631
|
+
var q_tmpl = {token: "`", isExpr: true}, f_expr = {token: "function", isExpr: true};
|
632
|
+
|
633
|
+
function curTokContext() {
|
634
|
+
return tokContext[tokContext.length - 1];
|
635
|
+
}
|
636
|
+
|
637
|
+
function braceIsBlock(prevType) {
|
638
|
+
var parent;
|
639
|
+
if (prevType === _colon && (parent = curTokContext()).token == "{")
|
640
|
+
return !parent.isExpr;
|
641
|
+
if (prevType === _return)
|
642
|
+
return newline.test(input.slice(lastEnd, tokStart));
|
643
|
+
if (prevType === _else || prevType === _semi || prevType === _eof)
|
644
|
+
return true;
|
645
|
+
if (prevType == _braceL)
|
646
|
+
return curTokContext() === b_stat;
|
647
|
+
return !tokExprAllowed;
|
618
648
|
}
|
619
649
|
|
620
650
|
// Called at the end of every token. Sets `tokEnd`, `tokVal`, and
|
621
|
-
// `
|
622
|
-
// the next one's `tokStart` will point at
|
651
|
+
// maintains `tokContext` and `tokExprAllowed`, and skips the space
|
652
|
+
// after the token, so that the next one's `tokStart` will point at
|
653
|
+
// the right position.
|
623
654
|
|
624
|
-
function finishToken(type, val
|
655
|
+
function finishToken(type, val) {
|
625
656
|
tokEnd = tokPos;
|
626
657
|
if (options.locations) tokEndLoc = curPosition();
|
658
|
+
var prevType = tokType, preserveSpace = false;
|
627
659
|
tokType = type;
|
628
|
-
if (shouldSkipSpace !== false) skipSpace();
|
629
660
|
tokVal = val;
|
630
|
-
|
631
|
-
|
632
|
-
|
661
|
+
|
662
|
+
// Update context info
|
663
|
+
if (type === _parenR || type === _braceR) {
|
664
|
+
var out = tokContext.pop();
|
665
|
+
if (out === b_tmpl) {
|
666
|
+
preserveSpace = true;
|
667
|
+
} else if (out === b_stat && curTokContext() === f_expr) {
|
668
|
+
tokContext.pop();
|
669
|
+
tokExprAllowed = false;
|
670
|
+
} else {
|
671
|
+
tokExprAllowed = !(out && out.isExpr);
|
672
|
+
}
|
673
|
+
} else if (type === _braceL) {
|
674
|
+
tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr);
|
675
|
+
tokExprAllowed = true;
|
676
|
+
} else if (type === _dollarBraceL) {
|
677
|
+
tokContext.push(b_tmpl);
|
678
|
+
tokExprAllowed = true;
|
679
|
+
} else if (type == _parenL) {
|
680
|
+
var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while;
|
681
|
+
tokContext.push(statementParens ? p_stat : p_expr);
|
682
|
+
tokExprAllowed = true;
|
683
|
+
} else if (type == _incDec) {
|
684
|
+
// tokExprAllowed stays unchanged
|
685
|
+
} else if (type.keyword && prevType == _dot) {
|
686
|
+
tokExprAllowed = false;
|
687
|
+
} else if (type == _function) {
|
688
|
+
if (curTokContext() !== b_stat) {
|
689
|
+
tokContext.push(f_expr);
|
690
|
+
}
|
691
|
+
tokExprAllowed = false;
|
692
|
+
} else if (type === _backQuote) {
|
693
|
+
if (curTokContext() === q_tmpl) {
|
694
|
+
tokContext.pop();
|
695
|
+
} else {
|
696
|
+
tokContext.push(q_tmpl);
|
697
|
+
preserveSpace = true;
|
698
|
+
}
|
699
|
+
tokExprAllowed = false;
|
700
|
+
} else {
|
701
|
+
tokExprAllowed = type.beforeExpr;
|
633
702
|
}
|
703
|
+
|
704
|
+
if (!preserveSpace) skipSpace();
|
634
705
|
}
|
635
706
|
|
636
707
|
function skipBlockComment() {
|
@@ -716,9 +787,6 @@
|
|
716
787
|
//
|
717
788
|
// All in the name of speed.
|
718
789
|
//
|
719
|
-
// The `forceRegexp` parameter is used in the one case where the
|
720
|
-
// `tokRegexpAllowed` trick does not work. See `parseStatement`.
|
721
|
-
|
722
790
|
function readToken_dot() {
|
723
791
|
var next = input.charCodeAt(tokPos + 1);
|
724
792
|
if (next >= 48 && next <= 57) return readNumber(true);
|
@@ -734,7 +802,7 @@
|
|
734
802
|
|
735
803
|
function readToken_slash() { // '/'
|
736
804
|
var next = input.charCodeAt(tokPos + 1);
|
737
|
-
if (
|
805
|
+
if (tokExprAllowed) {++tokPos; return readRegexp();}
|
738
806
|
if (next === 61) return finishOp(_assign, 2);
|
739
807
|
return finishOp(_slash, 1);
|
740
808
|
}
|
@@ -818,23 +886,17 @@
|
|
818
886
|
case 44: ++tokPos; return finishToken(_comma);
|
819
887
|
case 91: ++tokPos; return finishToken(_bracketL);
|
820
888
|
case 93: ++tokPos; return finishToken(_bracketR);
|
821
|
-
case 123:
|
822
|
-
|
823
|
-
if (templates.length) ++templates[templates.length - 1];
|
824
|
-
return finishToken(_braceL);
|
825
|
-
case 125:
|
826
|
-
++tokPos;
|
827
|
-
if (templates.length && --templates[templates.length - 1] === 0)
|
828
|
-
return readTemplateString(_templateContinued);
|
829
|
-
else
|
830
|
-
return finishToken(_braceR);
|
889
|
+
case 123: ++tokPos; return finishToken(_braceL);
|
890
|
+
case 125: ++tokPos; return finishToken(_braceR);
|
831
891
|
case 58: ++tokPos; return finishToken(_colon);
|
832
892
|
case 63: ++tokPos; return finishToken(_question);
|
833
893
|
|
834
894
|
case 96: // '`'
|
835
895
|
if (options.ecmaVersion >= 6) {
|
836
896
|
++tokPos;
|
837
|
-
return
|
897
|
+
return finishToken(_backQuote);
|
898
|
+
} else {
|
899
|
+
return false;
|
838
900
|
}
|
839
901
|
|
840
902
|
case 48: // '0'
|
@@ -886,13 +948,15 @@
|
|
886
948
|
return false;
|
887
949
|
}
|
888
950
|
|
889
|
-
function readToken(
|
890
|
-
|
891
|
-
else tokPos = tokStart + 1;
|
951
|
+
function readToken() {
|
952
|
+
tokStart = tokPos;
|
892
953
|
if (options.locations) tokStartLoc = curPosition();
|
893
|
-
if (forceRegexp) return readRegexp();
|
894
954
|
if (tokPos >= inputLen) return finishToken(_eof);
|
895
955
|
|
956
|
+
if (curTokContext() === q_tmpl) {
|
957
|
+
return readTmplToken();
|
958
|
+
}
|
959
|
+
|
896
960
|
var code = input.charCodeAt(tokPos);
|
897
961
|
|
898
962
|
// Identifier or keyword. '\uXXXX' sequences are allowed in
|
@@ -1056,55 +1120,64 @@
|
|
1056
1120
|
}
|
1057
1121
|
|
1058
1122
|
function readString(quote) {
|
1059
|
-
++tokPos;
|
1060
|
-
var out = "";
|
1123
|
+
var out = "", chunkStart = ++tokPos;
|
1061
1124
|
for (;;) {
|
1062
1125
|
if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
|
1063
1126
|
var ch = input.charCodeAt(tokPos);
|
1064
|
-
if (ch === quote)
|
1065
|
-
++tokPos;
|
1066
|
-
return finishToken(_string, out);
|
1067
|
-
}
|
1127
|
+
if (ch === quote) break;
|
1068
1128
|
if (ch === 92) { // '\'
|
1129
|
+
out += input.slice(chunkStart, tokPos);
|
1069
1130
|
out += readEscapedChar();
|
1131
|
+
chunkStart = tokPos;
|
1070
1132
|
} else {
|
1133
|
+
if (isNewLine(ch)) raise(tokStart, "Unterminated string constant");
|
1071
1134
|
++tokPos;
|
1072
|
-
if (newline.test(String.fromCharCode(ch))) {
|
1073
|
-
raise(tokStart, "Unterminated string constant");
|
1074
|
-
}
|
1075
|
-
out += String.fromCharCode(ch); // '\'
|
1076
1135
|
}
|
1077
1136
|
}
|
1137
|
+
out += input.slice(chunkStart, tokPos++);
|
1138
|
+
return finishToken(_string, out);
|
1078
1139
|
}
|
1079
1140
|
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1141
|
+
// Reads template string tokens.
|
1142
|
+
|
1143
|
+
function readTmplToken() {
|
1144
|
+
var out = "", chunkStart = tokPos;
|
1083
1145
|
for (;;) {
|
1084
1146
|
if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
|
1085
|
-
var ch = input.
|
1086
|
-
if (ch ===
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1147
|
+
var ch = input.charCodeAt(tokPos);
|
1148
|
+
if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
|
1149
|
+
if (tokPos === tokStart && tokType === _template) {
|
1150
|
+
if (ch === 36) {
|
1151
|
+
tokPos += 2;
|
1152
|
+
return finishToken(_dollarBraceL);
|
1153
|
+
} else {
|
1154
|
+
++tokPos;
|
1155
|
+
return finishToken(_backQuote);
|
1156
|
+
}
|
1157
|
+
}
|
1158
|
+
out += input.slice(chunkStart, tokPos);
|
1159
|
+
return finishToken(_template, out);
|
1091
1160
|
}
|
1092
|
-
|
1093
|
-
|
1161
|
+
if (ch === 92) { // '\'
|
1162
|
+
out += input.slice(chunkStart, tokPos);
|
1094
1163
|
out += readEscapedChar();
|
1095
|
-
|
1164
|
+
chunkStart = tokPos;
|
1165
|
+
} else if (isNewLine(ch)) {
|
1166
|
+
out += input.slice(chunkStart, tokPos);
|
1096
1167
|
++tokPos;
|
1097
|
-
if (
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
if (options.locations) {
|
1103
|
-
++tokCurLine;
|
1104
|
-
tokLineStart = tokPos;
|
1105
|
-
}
|
1168
|
+
if (ch === 13 && input.charCodeAt(tokPos) === 10) {
|
1169
|
+
++tokPos;
|
1170
|
+
out += "\n";
|
1171
|
+
} else {
|
1172
|
+
out += String.fromCharCode(ch);
|
1106
1173
|
}
|
1107
|
-
|
1174
|
+
if (options.locations) {
|
1175
|
+
++tokCurLine;
|
1176
|
+
tokLineStart = tokPos;
|
1177
|
+
}
|
1178
|
+
chunkStart = tokPos;
|
1179
|
+
} else {
|
1180
|
+
++tokPos;
|
1108
1181
|
}
|
1109
1182
|
}
|
1110
1183
|
}
|
@@ -1159,20 +1232,19 @@
|
|
1159
1232
|
// Read an identifier, and return it as a string. Sets `containsEsc`
|
1160
1233
|
// to whether the word contained a '\u' escape.
|
1161
1234
|
//
|
1162
|
-
//
|
1163
|
-
//
|
1235
|
+
// Incrementally adds only escaped chars, adding other chunks as-is
|
1236
|
+
// as a micro-optimization.
|
1164
1237
|
|
1165
1238
|
function readWord1() {
|
1166
1239
|
containsEsc = false;
|
1167
|
-
var word, first = true,
|
1168
|
-
|
1240
|
+
var word = "", first = true, chunkStart = tokPos;
|
1241
|
+
while (tokPos < inputLen) {
|
1169
1242
|
var ch = input.charCodeAt(tokPos);
|
1170
1243
|
if (isIdentifierChar(ch)) {
|
1171
|
-
if (containsEsc) word += input.charAt(tokPos);
|
1172
1244
|
++tokPos;
|
1173
1245
|
} else if (ch === 92) { // "\"
|
1174
|
-
if (!containsEsc) word = input.slice(start, tokPos);
|
1175
1246
|
containsEsc = true;
|
1247
|
+
word += input.slice(chunkStart, tokPos);
|
1176
1248
|
if (input.charCodeAt(++tokPos) != 117) // "u"
|
1177
1249
|
raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
|
1178
1250
|
++tokPos;
|
@@ -1182,12 +1254,13 @@
|
|
1182
1254
|
if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
|
1183
1255
|
raise(tokPos - 4, "Invalid Unicode escape");
|
1184
1256
|
word += escStr;
|
1257
|
+
chunkStart = tokPos;
|
1185
1258
|
} else {
|
1186
1259
|
break;
|
1187
1260
|
}
|
1188
1261
|
first = false;
|
1189
1262
|
}
|
1190
|
-
return
|
1263
|
+
return word + input.slice(chunkStart, tokPos);
|
1191
1264
|
}
|
1192
1265
|
|
1193
1266
|
// Read an identifier or keyword token. Will check for reserved
|
@@ -1226,17 +1299,21 @@
|
|
1226
1299
|
// Continue to the next token.
|
1227
1300
|
|
1228
1301
|
function next() {
|
1302
|
+
if (options.onToken)
|
1303
|
+
options.onToken(new Token());
|
1304
|
+
|
1229
1305
|
lastStart = tokStart;
|
1230
1306
|
lastEnd = tokEnd;
|
1231
1307
|
lastEndLoc = tokEndLoc;
|
1232
1308
|
readToken();
|
1233
1309
|
}
|
1234
1310
|
|
1235
|
-
// Enter strict mode. Re-reads the next
|
1236
|
-
// tests ("use strict"; 010; -- should fail).
|
1311
|
+
// Enter strict mode. Re-reads the next number or string to
|
1312
|
+
// please pedantic tests ("use strict"; 010; -- should fail).
|
1237
1313
|
|
1238
1314
|
function setStrict(strct) {
|
1239
1315
|
strict = strct;
|
1316
|
+
if (tokType !== _num && tokType !== _string) return;
|
1240
1317
|
tokPos = tokStart;
|
1241
1318
|
if (options.locations) {
|
1242
1319
|
while (tokPos < tokLineStart) {
|
@@ -1311,6 +1388,8 @@
|
|
1311
1388
|
return node;
|
1312
1389
|
}
|
1313
1390
|
|
1391
|
+
// Finish node at given position
|
1392
|
+
|
1314
1393
|
function finishNodeAt(node, type, pos) {
|
1315
1394
|
if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; }
|
1316
1395
|
node.type = type;
|
@@ -1339,6 +1418,24 @@
|
|
1339
1418
|
}
|
1340
1419
|
}
|
1341
1420
|
|
1421
|
+
// Tests whether parsed token is a contextual keyword.
|
1422
|
+
|
1423
|
+
function isContextual(name) {
|
1424
|
+
return tokType === _name && tokVal === name;
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
// Consumes contextual keyword if possible.
|
1428
|
+
|
1429
|
+
function eatContextual(name) {
|
1430
|
+
return tokVal === name && eat(_name);
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
// Asserts that following token is given contextual keyword.
|
1434
|
+
|
1435
|
+
function expectContextual(name) {
|
1436
|
+
if (!eatContextual(name)) unexpected();
|
1437
|
+
}
|
1438
|
+
|
1342
1439
|
// Test whether a semicolon can be inserted at the current position.
|
1343
1440
|
|
1344
1441
|
function canInsertSemicolon() {
|
@@ -1371,53 +1468,139 @@
|
|
1371
1468
|
function has(obj, propName) {
|
1372
1469
|
return Object.prototype.hasOwnProperty.call(obj, propName);
|
1373
1470
|
}
|
1471
|
+
|
1374
1472
|
// Convert existing expression atom to assignable pattern
|
1375
1473
|
// if possible.
|
1376
1474
|
|
1377
|
-
function toAssignable(node,
|
1475
|
+
function toAssignable(node, isBinding) {
|
1378
1476
|
if (options.ecmaVersion >= 6 && node) {
|
1379
1477
|
switch (node.type) {
|
1380
1478
|
case "Identifier":
|
1381
|
-
case "
|
1479
|
+
case "ObjectPattern":
|
1480
|
+
case "ArrayPattern":
|
1481
|
+
case "AssignmentPattern":
|
1382
1482
|
break;
|
1383
1483
|
|
1384
1484
|
case "ObjectExpression":
|
1385
1485
|
node.type = "ObjectPattern";
|
1386
1486
|
for (var i = 0; i < node.properties.length; i++) {
|
1387
1487
|
var prop = node.properties[i];
|
1388
|
-
if (prop.kind !== "init")
|
1389
|
-
toAssignable(prop.value,
|
1488
|
+
if (prop.kind !== "init") raise(prop.key.start, "Object pattern can't contain getter or setter");
|
1489
|
+
toAssignable(prop.value, isBinding);
|
1390
1490
|
}
|
1391
1491
|
break;
|
1392
1492
|
|
1393
1493
|
case "ArrayExpression":
|
1394
1494
|
node.type = "ArrayPattern";
|
1395
|
-
|
1396
|
-
toAssignable(node.elements[i], i === lastI, checkType);
|
1397
|
-
}
|
1495
|
+
toAssignableList(node.elements, isBinding);
|
1398
1496
|
break;
|
1399
1497
|
|
1400
|
-
case "
|
1401
|
-
if (
|
1402
|
-
|
1403
|
-
checkSpreadAssign(node.argument);
|
1498
|
+
case "AssignmentExpression":
|
1499
|
+
if (node.operator === "=") {
|
1500
|
+
node.type = "AssignmentPattern";
|
1404
1501
|
} else {
|
1405
|
-
|
1502
|
+
raise(node.left.end, "Only '=' operator can be used for specifying default value.");
|
1406
1503
|
}
|
1407
1504
|
break;
|
1408
1505
|
|
1506
|
+
case "MemberExpression":
|
1507
|
+
if (!isBinding) break;
|
1508
|
+
|
1409
1509
|
default:
|
1410
|
-
|
1510
|
+
raise(node.start, "Assigning to rvalue");
|
1411
1511
|
}
|
1412
1512
|
}
|
1413
1513
|
return node;
|
1414
1514
|
}
|
1415
1515
|
|
1416
|
-
//
|
1516
|
+
// Convert list of expression atoms to binding list.
|
1517
|
+
|
1518
|
+
function toAssignableList(exprList, isBinding) {
|
1519
|
+
if (exprList.length) {
|
1520
|
+
for (var i = 0; i < exprList.length - 1; i++) {
|
1521
|
+
toAssignable(exprList[i], isBinding);
|
1522
|
+
}
|
1523
|
+
var last = exprList[exprList.length - 1];
|
1524
|
+
switch (last.type) {
|
1525
|
+
case "RestElement":
|
1526
|
+
break;
|
1527
|
+
case "SpreadElement":
|
1528
|
+
last.type = "RestElement";
|
1529
|
+
var arg = last.argument;
|
1530
|
+
toAssignable(arg, isBinding);
|
1531
|
+
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
|
1532
|
+
unexpected(arg.start);
|
1533
|
+
break;
|
1534
|
+
default:
|
1535
|
+
toAssignable(last, isBinding);
|
1536
|
+
}
|
1537
|
+
}
|
1538
|
+
return exprList;
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
// Parses spread element.
|
1542
|
+
|
1543
|
+
function parseSpread(refShorthandDefaultPos) {
|
1544
|
+
var node = startNode();
|
1545
|
+
next();
|
1546
|
+
node.argument = parseMaybeAssign(refShorthandDefaultPos);
|
1547
|
+
return finishNode(node, "SpreadElement");
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
function parseRest() {
|
1551
|
+
var node = startNode();
|
1552
|
+
next();
|
1553
|
+
node.argument = tokType === _name || tokType === _bracketL ? parseBindingAtom() : unexpected();
|
1554
|
+
return finishNode(node, "RestElement");
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
// Parses lvalue (assignable) atom.
|
1558
|
+
|
1559
|
+
function parseBindingAtom() {
|
1560
|
+
if (options.ecmaVersion < 6) return parseIdent();
|
1561
|
+
switch (tokType) {
|
1562
|
+
case _name:
|
1563
|
+
return parseIdent();
|
1564
|
+
|
1565
|
+
case _bracketL:
|
1566
|
+
var node = startNode();
|
1567
|
+
next();
|
1568
|
+
node.elements = parseBindingList(_bracketR, true);
|
1569
|
+
return finishNode(node, "ArrayPattern");
|
1570
|
+
|
1571
|
+
case _braceL:
|
1572
|
+
return parseObj(true);
|
1573
|
+
|
1574
|
+
default:
|
1575
|
+
unexpected();
|
1576
|
+
}
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
function parseBindingList(close, allowEmpty) {
|
1580
|
+
var elts = [], first = true;
|
1581
|
+
while (!eat(close)) {
|
1582
|
+
first ? first = false : expect(_comma);
|
1583
|
+
if (tokType === _ellipsis) {
|
1584
|
+
elts.push(parseRest());
|
1585
|
+
expect(close);
|
1586
|
+
break;
|
1587
|
+
}
|
1588
|
+
elts.push(allowEmpty && tokType === _comma ? null : parseMaybeDefault());
|
1589
|
+
}
|
1590
|
+
return elts;
|
1591
|
+
}
|
1417
1592
|
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1593
|
+
// Parses assignment pattern around given atom if possible.
|
1594
|
+
|
1595
|
+
function parseMaybeDefault(startPos, left) {
|
1596
|
+
startPos = startPos || storeCurrentPos();
|
1597
|
+
left = left || parseBindingAtom();
|
1598
|
+
if (!eat(_eq)) return left;
|
1599
|
+
var node = startNodeAt(startPos);
|
1600
|
+
node.operator = "=";
|
1601
|
+
node.left = left;
|
1602
|
+
node.right = parseMaybeAssign();
|
1603
|
+
return finishNode(node, "AssignmentPattern");
|
1421
1604
|
}
|
1422
1605
|
|
1423
1606
|
// Verify that argument names are not repeated, and it does not
|
@@ -1444,6 +1627,9 @@
|
|
1444
1627
|
if (elem) checkFunctionParam(elem, nameHash);
|
1445
1628
|
}
|
1446
1629
|
break;
|
1630
|
+
|
1631
|
+
case "RestElement":
|
1632
|
+
return checkFunctionParam(param.argument, nameHash);
|
1447
1633
|
}
|
1448
1634
|
}
|
1449
1635
|
|
@@ -1483,14 +1669,12 @@
|
|
1483
1669
|
switch (expr.type) {
|
1484
1670
|
case "Identifier":
|
1485
1671
|
if (strict && (isStrictBadIdWord(expr.name) || isStrictReservedWord(expr.name)))
|
1486
|
-
raise(expr.start, isBinding
|
1487
|
-
? "Binding " + expr.name + " in strict mode"
|
1488
|
-
: "Assigning to " + expr.name + " in strict mode"
|
1489
|
-
);
|
1672
|
+
raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
|
1490
1673
|
break;
|
1491
1674
|
|
1492
1675
|
case "MemberExpression":
|
1493
|
-
if (
|
1676
|
+
if (isBinding) raise(expr.start, "Binding to member expression");
|
1677
|
+
break;
|
1494
1678
|
|
1495
1679
|
case "ObjectPattern":
|
1496
1680
|
for (var i = 0; i < expr.properties.length; i++)
|
@@ -1504,7 +1688,12 @@
|
|
1504
1688
|
}
|
1505
1689
|
break;
|
1506
1690
|
|
1507
|
-
case "
|
1691
|
+
case "AssignmentPattern":
|
1692
|
+
checkLVal(expr.left);
|
1693
|
+
break;
|
1694
|
+
|
1695
|
+
case "RestElement":
|
1696
|
+
checkLVal(expr.argument);
|
1508
1697
|
break;
|
1509
1698
|
|
1510
1699
|
default:
|
@@ -1523,15 +1712,13 @@
|
|
1523
1712
|
var first = true;
|
1524
1713
|
if (!node.body) node.body = [];
|
1525
1714
|
while (tokType !== _eof) {
|
1526
|
-
var stmt = parseStatement(true);
|
1715
|
+
var stmt = parseStatement(true, true);
|
1527
1716
|
node.body.push(stmt);
|
1528
1717
|
if (first && isUseStrict(stmt)) setStrict(true);
|
1529
1718
|
first = false;
|
1530
1719
|
}
|
1531
1720
|
|
1532
|
-
|
1533
|
-
lastEnd = tokEnd;
|
1534
|
-
lastEndLoc = tokEndLoc;
|
1721
|
+
next();
|
1535
1722
|
return finishNode(node, "Program");
|
1536
1723
|
}
|
1537
1724
|
|
@@ -1544,10 +1731,7 @@
|
|
1544
1731
|
// `if (foo) /blah/.exec(foo);`, where looking at the previous token
|
1545
1732
|
// does not help.
|
1546
1733
|
|
1547
|
-
function parseStatement(topLevel) {
|
1548
|
-
if (tokType === _slash || tokType === _assign && tokVal == "/=")
|
1549
|
-
readToken(true);
|
1550
|
-
|
1734
|
+
function parseStatement(declaration, topLevel) {
|
1551
1735
|
var starttype = tokType, node = startNode();
|
1552
1736
|
|
1553
1737
|
// Most types of statements are recognized by the keyword they
|
@@ -1559,14 +1743,19 @@
|
|
1559
1743
|
case _debugger: return parseDebuggerStatement(node);
|
1560
1744
|
case _do: return parseDoStatement(node);
|
1561
1745
|
case _for: return parseForStatement(node);
|
1562
|
-
case _function:
|
1563
|
-
|
1746
|
+
case _function:
|
1747
|
+
if (!declaration && options.ecmaVersion >= 6) unexpected();
|
1748
|
+
return parseFunctionStatement(node);
|
1749
|
+
case _class:
|
1750
|
+
if (!declaration) unexpected();
|
1751
|
+
return parseClass(node, true);
|
1564
1752
|
case _if: return parseIfStatement(node);
|
1565
1753
|
case _return: return parseReturnStatement(node);
|
1566
1754
|
case _switch: return parseSwitchStatement(node);
|
1567
1755
|
case _throw: return parseThrowStatement(node);
|
1568
1756
|
case _try: return parseTryStatement(node);
|
1569
|
-
case
|
1757
|
+
case _let: case _const: if (!declaration) unexpected(); // NOTE: falls through to _var
|
1758
|
+
case _var: return parseVarStatement(node, starttype.keyword);
|
1570
1759
|
case _while: return parseWhileStatement(node);
|
1571
1760
|
case _with: return parseWithStatement(node);
|
1572
1761
|
case _braceL: return parseBlock(); // no point creating a function for this
|
@@ -1622,7 +1811,7 @@
|
|
1622
1811
|
function parseDoStatement(node) {
|
1623
1812
|
next();
|
1624
1813
|
labels.push(loopLabel);
|
1625
|
-
node.body = parseStatement();
|
1814
|
+
node.body = parseStatement(false);
|
1626
1815
|
labels.pop();
|
1627
1816
|
expect(_while);
|
1628
1817
|
node.test = parseParenExpression();
|
@@ -1651,15 +1840,19 @@
|
|
1651
1840
|
next();
|
1652
1841
|
parseVar(init, true, varKind);
|
1653
1842
|
finishNode(init, "VariableDeclaration");
|
1654
|
-
if ((tokType === _in || (options.ecmaVersion >= 6 &&
|
1843
|
+
if ((tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) && init.declarations.length === 1 &&
|
1655
1844
|
!(isLet && init.declarations[0].init))
|
1656
1845
|
return parseForIn(node, init);
|
1657
1846
|
return parseFor(node, init);
|
1658
1847
|
}
|
1659
|
-
var
|
1660
|
-
|
1848
|
+
var refShorthandDefaultPos = {start: 0};
|
1849
|
+
var init = parseExpression(true, refShorthandDefaultPos);
|
1850
|
+
if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) {
|
1851
|
+
toAssignable(init);
|
1661
1852
|
checkLVal(init);
|
1662
1853
|
return parseForIn(node, init);
|
1854
|
+
} else if (refShorthandDefaultPos.start) {
|
1855
|
+
unexpected(refShorthandDefaultPos.start);
|
1663
1856
|
}
|
1664
1857
|
return parseFor(node, init);
|
1665
1858
|
}
|
@@ -1672,8 +1865,8 @@
|
|
1672
1865
|
function parseIfStatement(node) {
|
1673
1866
|
next();
|
1674
1867
|
node.test = parseParenExpression();
|
1675
|
-
node.consequent = parseStatement();
|
1676
|
-
node.alternate = eat(_else) ? parseStatement() : null;
|
1868
|
+
node.consequent = parseStatement(false);
|
1869
|
+
node.alternate = eat(_else) ? parseStatement(false) : null;
|
1677
1870
|
return finishNode(node, "IfStatement");
|
1678
1871
|
}
|
1679
1872
|
|
@@ -1717,7 +1910,7 @@
|
|
1717
1910
|
expect(_colon);
|
1718
1911
|
} else {
|
1719
1912
|
if (!cur) unexpected();
|
1720
|
-
cur.consequent.push(parseStatement());
|
1913
|
+
cur.consequent.push(parseStatement(true));
|
1721
1914
|
}
|
1722
1915
|
}
|
1723
1916
|
if (cur) finishNode(cur, "SwitchCase");
|
@@ -1743,9 +1936,8 @@
|
|
1743
1936
|
var clause = startNode();
|
1744
1937
|
next();
|
1745
1938
|
expect(_parenL);
|
1746
|
-
clause.param =
|
1747
|
-
|
1748
|
-
raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
|
1939
|
+
clause.param = parseBindingAtom();
|
1940
|
+
checkLVal(clause.param, true);
|
1749
1941
|
expect(_parenR);
|
1750
1942
|
clause.guard = null;
|
1751
1943
|
clause.body = parseBlock();
|
@@ -1769,7 +1961,7 @@
|
|
1769
1961
|
next();
|
1770
1962
|
node.test = parseParenExpression();
|
1771
1963
|
labels.push(loopLabel);
|
1772
|
-
node.body = parseStatement();
|
1964
|
+
node.body = parseStatement(false);
|
1773
1965
|
labels.pop();
|
1774
1966
|
return finishNode(node, "WhileStatement");
|
1775
1967
|
}
|
@@ -1778,7 +1970,7 @@
|
|
1778
1970
|
if (strict) raise(tokStart, "'with' in strict mode");
|
1779
1971
|
next();
|
1780
1972
|
node.object = parseParenExpression();
|
1781
|
-
node.body = parseStatement();
|
1973
|
+
node.body = parseStatement(false);
|
1782
1974
|
return finishNode(node, "WithStatement");
|
1783
1975
|
}
|
1784
1976
|
|
@@ -1792,7 +1984,7 @@
|
|
1792
1984
|
if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
|
1793
1985
|
var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
|
1794
1986
|
labels.push({name: maybeName, kind: kind});
|
1795
|
-
node.body = parseStatement();
|
1987
|
+
node.body = parseStatement(true);
|
1796
1988
|
labels.pop();
|
1797
1989
|
node.label = expr;
|
1798
1990
|
return finishNode(node, "LabeledStatement");
|
@@ -1823,7 +2015,7 @@
|
|
1823
2015
|
node.body = [];
|
1824
2016
|
expect(_braceL);
|
1825
2017
|
while (!eat(_braceR)) {
|
1826
|
-
var stmt = parseStatement();
|
2018
|
+
var stmt = parseStatement(true);
|
1827
2019
|
node.body.push(stmt);
|
1828
2020
|
if (first && allowStrict && isUseStrict(stmt)) {
|
1829
2021
|
oldStrict = strict;
|
@@ -1846,7 +2038,7 @@
|
|
1846
2038
|
expect(_semi);
|
1847
2039
|
node.update = tokType === _parenR ? null : parseExpression();
|
1848
2040
|
expect(_parenR);
|
1849
|
-
node.body = parseStatement();
|
2041
|
+
node.body = parseStatement(false);
|
1850
2042
|
labels.pop();
|
1851
2043
|
return finishNode(node, "ForStatement");
|
1852
2044
|
}
|
@@ -1860,7 +2052,7 @@
|
|
1860
2052
|
node.left = init;
|
1861
2053
|
node.right = parseExpression();
|
1862
2054
|
expect(_parenR);
|
1863
|
-
node.body = parseStatement();
|
2055
|
+
node.body = parseStatement(false);
|
1864
2056
|
labels.pop();
|
1865
2057
|
return finishNode(node, type);
|
1866
2058
|
}
|
@@ -1872,9 +2064,9 @@
|
|
1872
2064
|
node.kind = kind;
|
1873
2065
|
for (;;) {
|
1874
2066
|
var decl = startNode();
|
1875
|
-
decl.id =
|
2067
|
+
decl.id = parseBindingAtom();
|
1876
2068
|
checkLVal(decl.id, true);
|
1877
|
-
decl.init = eat(_eq) ?
|
2069
|
+
decl.init = eat(_eq) ? parseMaybeAssign(noIn) : (kind === _const.keyword ? unexpected() : null);
|
1878
2070
|
node.declarations.push(finishNode(decl, "VariableDeclarator"));
|
1879
2071
|
if (!eat(_comma)) break;
|
1880
2072
|
}
|
@@ -1889,17 +2081,20 @@
|
|
1889
2081
|
// and, *if* the syntactic construct they handle is present, wrap
|
1890
2082
|
// the AST node that the inner parser gave them in another node.
|
1891
2083
|
|
1892
|
-
// Parse a full expression. The arguments are used to
|
1893
|
-
//
|
1894
|
-
//
|
2084
|
+
// Parse a full expression. The optional arguments are used to
|
2085
|
+
// forbid the `in` operator (in for loops initalization expressions)
|
2086
|
+
// and provide reference for storing '=' operator inside shorthand
|
2087
|
+
// property assignment in contexts where both object expression
|
2088
|
+
// and object pattern might appear (so it's possible to raise
|
2089
|
+
// delayed syntax error at correct position).
|
1895
2090
|
|
1896
|
-
function parseExpression(
|
2091
|
+
function parseExpression(noIn, refShorthandDefaultPos) {
|
1897
2092
|
var start = storeCurrentPos();
|
1898
|
-
var expr = parseMaybeAssign(noIn);
|
1899
|
-
if (
|
2093
|
+
var expr = parseMaybeAssign(noIn, refShorthandDefaultPos);
|
2094
|
+
if (tokType === _comma) {
|
1900
2095
|
var node = startNodeAt(start);
|
1901
2096
|
node.expressions = [expr];
|
1902
|
-
while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
|
2097
|
+
while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn, refShorthandDefaultPos));
|
1903
2098
|
return finishNode(node, "SequenceExpression");
|
1904
2099
|
}
|
1905
2100
|
return expr;
|
@@ -1908,32 +2103,43 @@
|
|
1908
2103
|
// Parse an assignment expression. This includes applications of
|
1909
2104
|
// operators like `+=`.
|
1910
2105
|
|
1911
|
-
function parseMaybeAssign(noIn) {
|
2106
|
+
function parseMaybeAssign(noIn, refShorthandDefaultPos) {
|
2107
|
+
var failOnShorthandAssign;
|
2108
|
+
if (!refShorthandDefaultPos) {
|
2109
|
+
refShorthandDefaultPos = {start: 0};
|
2110
|
+
failOnShorthandAssign = true;
|
2111
|
+
} else {
|
2112
|
+
failOnShorthandAssign = false;
|
2113
|
+
}
|
1912
2114
|
var start = storeCurrentPos();
|
1913
|
-
var left = parseMaybeConditional(noIn);
|
2115
|
+
var left = parseMaybeConditional(noIn, refShorthandDefaultPos);
|
1914
2116
|
if (tokType.isAssign) {
|
1915
2117
|
var node = startNodeAt(start);
|
1916
2118
|
node.operator = tokVal;
|
1917
2119
|
node.left = tokType === _eq ? toAssignable(left) : left;
|
2120
|
+
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
|
1918
2121
|
checkLVal(left);
|
1919
2122
|
next();
|
1920
2123
|
node.right = parseMaybeAssign(noIn);
|
1921
2124
|
return finishNode(node, "AssignmentExpression");
|
2125
|
+
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
|
2126
|
+
unexpected(refShorthandDefaultPos.start);
|
1922
2127
|
}
|
1923
2128
|
return left;
|
1924
2129
|
}
|
1925
2130
|
|
1926
2131
|
// Parse a ternary conditional (`?:`) operator.
|
1927
2132
|
|
1928
|
-
function parseMaybeConditional(noIn) {
|
2133
|
+
function parseMaybeConditional(noIn, refShorthandDefaultPos) {
|
1929
2134
|
var start = storeCurrentPos();
|
1930
|
-
var expr = parseExprOps(noIn);
|
2135
|
+
var expr = parseExprOps(noIn, refShorthandDefaultPos);
|
2136
|
+
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
1931
2137
|
if (eat(_question)) {
|
1932
2138
|
var node = startNodeAt(start);
|
1933
2139
|
node.test = expr;
|
1934
|
-
node.consequent =
|
2140
|
+
node.consequent = parseMaybeAssign();
|
1935
2141
|
expect(_colon);
|
1936
|
-
node.alternate =
|
2142
|
+
node.alternate = parseMaybeAssign(noIn);
|
1937
2143
|
return finishNode(node, "ConditionalExpression");
|
1938
2144
|
}
|
1939
2145
|
return expr;
|
@@ -1941,9 +2147,11 @@
|
|
1941
2147
|
|
1942
2148
|
// Start the precedence parser.
|
1943
2149
|
|
1944
|
-
function parseExprOps(noIn) {
|
2150
|
+
function parseExprOps(noIn, refShorthandDefaultPos) {
|
1945
2151
|
var start = storeCurrentPos();
|
1946
|
-
|
2152
|
+
var expr = parseMaybeUnary(refShorthandDefaultPos);
|
2153
|
+
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
2154
|
+
return parseExprOp(expr, start, -1, noIn);
|
1947
2155
|
}
|
1948
2156
|
|
1949
2157
|
// Parse binary operators with the operator precedence parsing
|
@@ -1972,27 +2180,23 @@
|
|
1972
2180
|
|
1973
2181
|
// Parse unary operators, both prefix and postfix.
|
1974
2182
|
|
1975
|
-
function parseMaybeUnary() {
|
2183
|
+
function parseMaybeUnary(refShorthandDefaultPos) {
|
1976
2184
|
if (tokType.prefix) {
|
1977
|
-
var node = startNode(), update = tokType.isUpdate
|
1978
|
-
|
1979
|
-
|
1980
|
-
} else {
|
1981
|
-
nodeType = update ? "UpdateExpression" : "UnaryExpression";
|
1982
|
-
node.operator = tokVal;
|
1983
|
-
node.prefix = true;
|
1984
|
-
}
|
1985
|
-
tokRegexpAllowed = true;
|
2185
|
+
var node = startNode(), update = tokType.isUpdate;
|
2186
|
+
node.operator = tokVal;
|
2187
|
+
node.prefix = true;
|
1986
2188
|
next();
|
1987
2189
|
node.argument = parseMaybeUnary();
|
2190
|
+
if (refShorthandDefaultPos && refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start);
|
1988
2191
|
if (update) checkLVal(node.argument);
|
1989
2192
|
else if (strict && node.operator === "delete" &&
|
1990
2193
|
node.argument.type === "Identifier")
|
1991
2194
|
raise(node.start, "Deleting local variable in strict mode");
|
1992
|
-
return finishNode(node,
|
2195
|
+
return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
|
1993
2196
|
}
|
1994
2197
|
var start = storeCurrentPos();
|
1995
|
-
var expr = parseExprSubscripts();
|
2198
|
+
var expr = parseExprSubscripts(refShorthandDefaultPos);
|
2199
|
+
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
1996
2200
|
while (tokType.postfix && !canInsertSemicolon()) {
|
1997
2201
|
var node = startNodeAt(start);
|
1998
2202
|
node.operator = tokVal;
|
@@ -2007,9 +2211,11 @@
|
|
2007
2211
|
|
2008
2212
|
// Parse call, dot, and `[]`-subscript expressions.
|
2009
2213
|
|
2010
|
-
function parseExprSubscripts() {
|
2214
|
+
function parseExprSubscripts(refShorthandDefaultPos) {
|
2011
2215
|
var start = storeCurrentPos();
|
2012
|
-
|
2216
|
+
var expr = parseExprAtom(refShorthandDefaultPos);
|
2217
|
+
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
2218
|
+
return parseSubscripts(expr, start);
|
2013
2219
|
}
|
2014
2220
|
|
2015
2221
|
function parseSubscripts(base, start, noCalls) {
|
@@ -2031,7 +2237,7 @@
|
|
2031
2237
|
node.callee = base;
|
2032
2238
|
node.arguments = parseExprList(_parenR, false);
|
2033
2239
|
return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls);
|
2034
|
-
} else if (tokType ===
|
2240
|
+
} else if (tokType === _backQuote) {
|
2035
2241
|
var node = startNodeAt(start);
|
2036
2242
|
node.tag = base;
|
2037
2243
|
node.quasi = parseTemplate();
|
@@ -2044,7 +2250,7 @@
|
|
2044
2250
|
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
|
2045
2251
|
// or `{}`.
|
2046
2252
|
|
2047
|
-
function parseExprAtom() {
|
2253
|
+
function parseExprAtom(refShorthandDefaultPos) {
|
2048
2254
|
switch (tokType) {
|
2049
2255
|
case _this:
|
2050
2256
|
var node = startNode();
|
@@ -2057,7 +2263,7 @@
|
|
2057
2263
|
case _name:
|
2058
2264
|
var start = storeCurrentPos();
|
2059
2265
|
var id = parseIdent(tokType !== _name);
|
2060
|
-
if (eat(_arrow)) {
|
2266
|
+
if (!canInsertSemicolon() && eat(_arrow)) {
|
2061
2267
|
return parseArrowExpression(startNodeAt(start), [id]);
|
2062
2268
|
}
|
2063
2269
|
return id;
|
@@ -2085,42 +2291,7 @@
|
|
2085
2291
|
return finishNode(node, "Literal");
|
2086
2292
|
|
2087
2293
|
case _parenL:
|
2088
|
-
|
2089
|
-
var val, exprList;
|
2090
|
-
next();
|
2091
|
-
// check whether this is generator comprehension or regular expression
|
2092
|
-
if (options.ecmaVersion >= 7 && tokType === _for) {
|
2093
|
-
val = parseComprehension(startNodeAt(start), true);
|
2094
|
-
} else {
|
2095
|
-
var oldParenL = ++metParenL;
|
2096
|
-
if (tokType !== _parenR) {
|
2097
|
-
val = parseExpression();
|
2098
|
-
exprList = val.type === "SequenceExpression" ? val.expressions : [val];
|
2099
|
-
} else {
|
2100
|
-
exprList = [];
|
2101
|
-
}
|
2102
|
-
expect(_parenR);
|
2103
|
-
// if '=>' follows '(...)', convert contents to arguments
|
2104
|
-
if (metParenL === oldParenL && eat(_arrow)) {
|
2105
|
-
val = parseArrowExpression(startNodeAt(start), exprList);
|
2106
|
-
} else {
|
2107
|
-
// forbid '()' before everything but '=>'
|
2108
|
-
if (!val) unexpected(lastStart);
|
2109
|
-
// forbid '...' in sequence expressions
|
2110
|
-
if (options.ecmaVersion >= 6) {
|
2111
|
-
for (var i = 0; i < exprList.length; i++) {
|
2112
|
-
if (exprList[i].type === "SpreadElement") unexpected();
|
2113
|
-
}
|
2114
|
-
}
|
2115
|
-
|
2116
|
-
if (options.preserveParens) {
|
2117
|
-
var par = startNodeAt(start);
|
2118
|
-
par.expression = val;
|
2119
|
-
val = finishNode(par, "ParenthesizedExpression");
|
2120
|
-
}
|
2121
|
-
}
|
2122
|
-
}
|
2123
|
-
return val;
|
2294
|
+
return parseParenAndDistinguishExpression();
|
2124
2295
|
|
2125
2296
|
case _bracketL:
|
2126
2297
|
var node = startNode();
|
@@ -2129,11 +2300,11 @@
|
|
2129
2300
|
if (options.ecmaVersion >= 7 && tokType === _for) {
|
2130
2301
|
return parseComprehension(node, false);
|
2131
2302
|
}
|
2132
|
-
node.elements = parseExprList(_bracketR, true, true);
|
2303
|
+
node.elements = parseExprList(_bracketR, true, true, refShorthandDefaultPos);
|
2133
2304
|
return finishNode(node, "ArrayExpression");
|
2134
2305
|
|
2135
2306
|
case _braceL:
|
2136
|
-
return parseObj();
|
2307
|
+
return parseObj(false, refShorthandDefaultPos);
|
2137
2308
|
|
2138
2309
|
case _function:
|
2139
2310
|
var node = startNode();
|
@@ -2146,7 +2317,7 @@
|
|
2146
2317
|
case _new:
|
2147
2318
|
return parseNew();
|
2148
2319
|
|
2149
|
-
case
|
2320
|
+
case _backQuote:
|
2150
2321
|
return parseTemplate();
|
2151
2322
|
|
2152
2323
|
default:
|
@@ -2154,6 +2325,62 @@
|
|
2154
2325
|
}
|
2155
2326
|
}
|
2156
2327
|
|
2328
|
+
function parseParenAndDistinguishExpression() {
|
2329
|
+
var start = storeCurrentPos(), val;
|
2330
|
+
if (options.ecmaVersion >= 6) {
|
2331
|
+
next();
|
2332
|
+
|
2333
|
+
if (options.ecmaVersion >= 7 && tokType === _for) {
|
2334
|
+
return parseComprehension(startNodeAt(start), true);
|
2335
|
+
}
|
2336
|
+
|
2337
|
+
var innerStart = storeCurrentPos(), exprList = [], first = true;
|
2338
|
+
var refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart;
|
2339
|
+
while (tokType !== _parenR) {
|
2340
|
+
first ? first = false : expect(_comma);
|
2341
|
+
if (tokType === _ellipsis) {
|
2342
|
+
spreadStart = tokStart;
|
2343
|
+
exprList.push(parseRest());
|
2344
|
+
break;
|
2345
|
+
} else {
|
2346
|
+
if (tokType === _parenL && !innerParenStart) {
|
2347
|
+
innerParenStart = tokStart;
|
2348
|
+
}
|
2349
|
+
exprList.push(parseMaybeAssign(false, refShorthandDefaultPos));
|
2350
|
+
}
|
2351
|
+
}
|
2352
|
+
var innerEnd = storeCurrentPos();
|
2353
|
+
expect(_parenR);
|
2354
|
+
|
2355
|
+
if (!canInsertSemicolon() && eat(_arrow)) {
|
2356
|
+
if (innerParenStart) unexpected(innerParenStart);
|
2357
|
+
return parseArrowExpression(startNodeAt(start), exprList);
|
2358
|
+
}
|
2359
|
+
|
2360
|
+
if (!exprList.length) unexpected(lastStart);
|
2361
|
+
if (spreadStart) unexpected(spreadStart);
|
2362
|
+
if (refShorthandDefaultPos.start) unexpected(refShorthandDefaultPos.start);
|
2363
|
+
|
2364
|
+
if (exprList.length > 1) {
|
2365
|
+
val = startNodeAt(innerStart);
|
2366
|
+
val.expressions = exprList;
|
2367
|
+
finishNodeAt(val, "SequenceExpression", innerEnd);
|
2368
|
+
} else {
|
2369
|
+
val = exprList[0];
|
2370
|
+
}
|
2371
|
+
} else {
|
2372
|
+
val = parseParenExpression();
|
2373
|
+
}
|
2374
|
+
|
2375
|
+
if (options.preserveParens) {
|
2376
|
+
var par = startNodeAt(start);
|
2377
|
+
par.expression = val;
|
2378
|
+
return finishNode(par, "ParenthesizedExpression");
|
2379
|
+
} else {
|
2380
|
+
return val;
|
2381
|
+
}
|
2382
|
+
}
|
2383
|
+
|
2157
2384
|
// New's precedence is slightly tricky. It must allow its argument
|
2158
2385
|
// to be a `[]` or dot subscript expression, but not a call — at
|
2159
2386
|
// least, not without wrapping it in parentheses. Thus, it uses the
|
@@ -2171,30 +2398,35 @@
|
|
2171
2398
|
// Parse template expression.
|
2172
2399
|
|
2173
2400
|
function parseTemplateElement() {
|
2174
|
-
var elem =
|
2175
|
-
elem.value =
|
2176
|
-
|
2401
|
+
var elem = startNode();
|
2402
|
+
elem.value = {
|
2403
|
+
raw: input.slice(tokStart, tokEnd),
|
2404
|
+
cooked: tokVal
|
2405
|
+
};
|
2177
2406
|
next();
|
2178
|
-
|
2179
|
-
return
|
2407
|
+
elem.tail = tokType === _backQuote;
|
2408
|
+
return finishNode(elem, "TemplateElement");
|
2180
2409
|
}
|
2181
2410
|
|
2182
2411
|
function parseTemplate() {
|
2183
2412
|
var node = startNode();
|
2413
|
+
next();
|
2184
2414
|
node.expressions = [];
|
2185
2415
|
var curElt = parseTemplateElement();
|
2186
2416
|
node.quasis = [curElt];
|
2187
2417
|
while (!curElt.tail) {
|
2418
|
+
expect(_dollarBraceL);
|
2188
2419
|
node.expressions.push(parseExpression());
|
2189
|
-
|
2420
|
+
expect(_braceR);
|
2190
2421
|
node.quasis.push(curElt = parseTemplateElement());
|
2191
2422
|
}
|
2423
|
+
next();
|
2192
2424
|
return finishNode(node, "TemplateLiteral");
|
2193
2425
|
}
|
2194
2426
|
|
2195
|
-
// Parse an object literal.
|
2427
|
+
// Parse an object literal or binding pattern.
|
2196
2428
|
|
2197
|
-
function parseObj() {
|
2429
|
+
function parseObj(isPattern, refShorthandDefaultPos) {
|
2198
2430
|
var node = startNode(), first = true, propHash = {};
|
2199
2431
|
node.properties = [];
|
2200
2432
|
next();
|
@@ -2204,36 +2436,51 @@
|
|
2204
2436
|
if (options.allowTrailingCommas && eat(_braceR)) break;
|
2205
2437
|
} else first = false;
|
2206
2438
|
|
2207
|
-
var prop = startNode(), isGenerator;
|
2439
|
+
var prop = startNode(), isGenerator, start;
|
2208
2440
|
if (options.ecmaVersion >= 6) {
|
2209
2441
|
prop.method = false;
|
2210
2442
|
prop.shorthand = false;
|
2211
|
-
|
2443
|
+
if (isPattern || refShorthandDefaultPos) {
|
2444
|
+
start = storeCurrentPos();
|
2445
|
+
}
|
2446
|
+
if (!isPattern) {
|
2447
|
+
isGenerator = eat(_star);
|
2448
|
+
}
|
2212
2449
|
}
|
2213
2450
|
parsePropertyName(prop);
|
2214
2451
|
if (eat(_colon)) {
|
2215
|
-
prop.value =
|
2452
|
+
prop.value = isPattern ? parseMaybeDefault() : parseMaybeAssign(false, refShorthandDefaultPos);
|
2216
2453
|
prop.kind = "init";
|
2217
2454
|
} else if (options.ecmaVersion >= 6 && tokType === _parenL) {
|
2455
|
+
if (isPattern) unexpected();
|
2218
2456
|
prop.kind = "init";
|
2219
2457
|
prop.method = true;
|
2220
2458
|
prop.value = parseMethod(isGenerator);
|
2221
2459
|
} else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
|
2222
|
-
(prop.key.name === "get" || prop.key.name === "set")
|
2223
|
-
|
2460
|
+
(prop.key.name === "get" || prop.key.name === "set") &&
|
2461
|
+
(tokType != _comma && tokType != _braceR)) {
|
2462
|
+
if (isGenerator || isPattern) unexpected();
|
2224
2463
|
prop.kind = prop.key.name;
|
2225
2464
|
parsePropertyName(prop);
|
2226
2465
|
prop.value = parseMethod(false);
|
2227
2466
|
} else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
|
2228
2467
|
prop.kind = "init";
|
2229
|
-
|
2468
|
+
if (isPattern) {
|
2469
|
+
prop.value = parseMaybeDefault(start, prop.key);
|
2470
|
+
} else if (tokType === _eq && refShorthandDefaultPos) {
|
2471
|
+
if (!refShorthandDefaultPos.start)
|
2472
|
+
refShorthandDefaultPos.start = tokStart;
|
2473
|
+
prop.value = parseMaybeDefault(start, prop.key);
|
2474
|
+
} else {
|
2475
|
+
prop.value = prop.key;
|
2476
|
+
}
|
2230
2477
|
prop.shorthand = true;
|
2231
2478
|
} else unexpected();
|
2232
2479
|
|
2233
2480
|
checkPropClash(prop, propHash);
|
2234
2481
|
node.properties.push(finishNode(prop, "Property"));
|
2235
2482
|
}
|
2236
|
-
return finishNode(node, "ObjectExpression");
|
2483
|
+
return finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
|
2237
2484
|
}
|
2238
2485
|
|
2239
2486
|
function parsePropertyName(prop) {
|
@@ -2254,11 +2501,9 @@
|
|
2254
2501
|
|
2255
2502
|
function initFunction(node) {
|
2256
2503
|
node.id = null;
|
2257
|
-
node.params = [];
|
2258
2504
|
if (options.ecmaVersion >= 6) {
|
2259
|
-
node.defaults = [];
|
2260
|
-
node.rest = null;
|
2261
2505
|
node.generator = false;
|
2506
|
+
node.expression = false;
|
2262
2507
|
}
|
2263
2508
|
}
|
2264
2509
|
|
@@ -2273,7 +2518,8 @@
|
|
2273
2518
|
if (isStatement || tokType === _name) {
|
2274
2519
|
node.id = parseIdent();
|
2275
2520
|
}
|
2276
|
-
|
2521
|
+
expect(_parenL);
|
2522
|
+
node.params = parseBindingList(_parenR, false);
|
2277
2523
|
parseFunctionBody(node, allowExpressionBody);
|
2278
2524
|
return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
|
2279
2525
|
}
|
@@ -2283,7 +2529,8 @@
|
|
2283
2529
|
function parseMethod(isGenerator) {
|
2284
2530
|
var node = startNode();
|
2285
2531
|
initFunction(node);
|
2286
|
-
|
2532
|
+
expect(_parenL);
|
2533
|
+
node.params = parseBindingList(_parenR, false);
|
2287
2534
|
var allowExpressionBody;
|
2288
2535
|
if (options.ecmaVersion >= 6) {
|
2289
2536
|
node.generator = isGenerator;
|
@@ -2299,76 +2546,18 @@
|
|
2299
2546
|
|
2300
2547
|
function parseArrowExpression(node, params) {
|
2301
2548
|
initFunction(node);
|
2302
|
-
|
2303
|
-
var defaults = node.defaults, hasDefaults = false;
|
2304
|
-
|
2305
|
-
for (var i = 0, lastI = params.length - 1; i <= lastI; i++) {
|
2306
|
-
var param = params[i];
|
2307
|
-
|
2308
|
-
if (param.type === "AssignmentExpression" && param.operator === "=") {
|
2309
|
-
hasDefaults = true;
|
2310
|
-
params[i] = param.left;
|
2311
|
-
defaults.push(param.right);
|
2312
|
-
} else {
|
2313
|
-
toAssignable(param, i === lastI, true);
|
2314
|
-
defaults.push(null);
|
2315
|
-
if (param.type === "SpreadElement") {
|
2316
|
-
params.length--;
|
2317
|
-
node.rest = param.argument;
|
2318
|
-
break;
|
2319
|
-
}
|
2320
|
-
}
|
2321
|
-
}
|
2322
|
-
|
2323
|
-
node.params = params;
|
2324
|
-
if (!hasDefaults) node.defaults = [];
|
2325
|
-
|
2549
|
+
node.params = toAssignableList(params, true);
|
2326
2550
|
parseFunctionBody(node, true);
|
2327
2551
|
return finishNode(node, "ArrowFunctionExpression");
|
2328
2552
|
}
|
2329
2553
|
|
2330
|
-
// Parse function parameters.
|
2331
|
-
|
2332
|
-
function parseFunctionParams(node) {
|
2333
|
-
var defaults = [], hasDefaults = false;
|
2334
|
-
|
2335
|
-
expect(_parenL);
|
2336
|
-
for (;;) {
|
2337
|
-
if (eat(_parenR)) {
|
2338
|
-
break;
|
2339
|
-
} else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
|
2340
|
-
node.rest = toAssignable(parseExprAtom(), false, true);
|
2341
|
-
checkSpreadAssign(node.rest);
|
2342
|
-
expect(_parenR);
|
2343
|
-
defaults.push(null);
|
2344
|
-
break;
|
2345
|
-
} else {
|
2346
|
-
node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
|
2347
|
-
if (options.ecmaVersion >= 6) {
|
2348
|
-
if (eat(_eq)) {
|
2349
|
-
hasDefaults = true;
|
2350
|
-
defaults.push(parseExpression(true));
|
2351
|
-
} else {
|
2352
|
-
defaults.push(null);
|
2353
|
-
}
|
2354
|
-
}
|
2355
|
-
if (!eat(_comma)) {
|
2356
|
-
expect(_parenR);
|
2357
|
-
break;
|
2358
|
-
}
|
2359
|
-
}
|
2360
|
-
}
|
2361
|
-
|
2362
|
-
if (hasDefaults) node.defaults = defaults;
|
2363
|
-
}
|
2364
|
-
|
2365
2554
|
// Parse function body and check parameters.
|
2366
2555
|
|
2367
2556
|
function parseFunctionBody(node, allowExpression) {
|
2368
2557
|
var isExpression = allowExpression && tokType !== _braceL;
|
2369
2558
|
|
2370
2559
|
if (isExpression) {
|
2371
|
-
node.body =
|
2560
|
+
node.body = parseMaybeAssign();
|
2372
2561
|
node.expression = true;
|
2373
2562
|
} else {
|
2374
2563
|
// Start a new scope with regard to labels and the `inFunction`
|
@@ -2389,8 +2578,6 @@
|
|
2389
2578
|
checkFunctionParam(node.id, {});
|
2390
2579
|
for (var i = 0; i < node.params.length; i++)
|
2391
2580
|
checkFunctionParam(node.params[i], nameHash);
|
2392
|
-
if (node.rest)
|
2393
|
-
checkFunctionParam(node.rest, nameHash);
|
2394
2581
|
}
|
2395
2582
|
}
|
2396
2583
|
|
@@ -2400,20 +2587,24 @@
|
|
2400
2587
|
function parseClass(node, isStatement) {
|
2401
2588
|
next();
|
2402
2589
|
node.id = tokType === _name ? parseIdent() : isStatement ? unexpected() : null;
|
2403
|
-
node.superClass = eat(_extends) ?
|
2590
|
+
node.superClass = eat(_extends) ? parseExprSubscripts() : null;
|
2404
2591
|
var classBody = startNode();
|
2405
2592
|
classBody.body = [];
|
2406
2593
|
expect(_braceL);
|
2407
2594
|
while (!eat(_braceR)) {
|
2595
|
+
if (eat(_semi)) continue;
|
2408
2596
|
var method = startNode();
|
2409
|
-
|
2410
|
-
|
2597
|
+
var isGenerator = eat(_star);
|
2598
|
+
parsePropertyName(method);
|
2599
|
+
if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" &&
|
2600
|
+
method.key.name === "static") {
|
2601
|
+
if (isGenerator) unexpected();
|
2411
2602
|
method['static'] = true;
|
2603
|
+
isGenerator = eat(_star);
|
2604
|
+
parsePropertyName(method);
|
2412
2605
|
} else {
|
2413
2606
|
method['static'] = false;
|
2414
2607
|
}
|
2415
|
-
var isGenerator = eat(_star);
|
2416
|
-
parsePropertyName(method);
|
2417
2608
|
if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" &&
|
2418
2609
|
(method.key.name === "get" || method.key.name === "set")) {
|
2419
2610
|
if (isGenerator) unexpected();
|
@@ -2424,7 +2615,6 @@
|
|
2424
2615
|
}
|
2425
2616
|
method.value = parseMethod(isGenerator);
|
2426
2617
|
classBody.body.push(finishNode(method, "MethodDefinition"));
|
2427
|
-
eat(_semi);
|
2428
2618
|
}
|
2429
2619
|
node.body = finishNode(classBody, "ClassBody");
|
2430
2620
|
return finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
|
@@ -2436,7 +2626,7 @@
|
|
2436
2626
|
// nothing in between them to be parsed as `null` (which is needed
|
2437
2627
|
// for array literals).
|
2438
2628
|
|
2439
|
-
function parseExprList(close, allowTrailingComma, allowEmpty) {
|
2629
|
+
function parseExprList(close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
|
2440
2630
|
var elts = [], first = true;
|
2441
2631
|
while (!eat(close)) {
|
2442
2632
|
if (!first) {
|
@@ -2444,8 +2634,14 @@
|
|
2444
2634
|
if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
|
2445
2635
|
} else first = false;
|
2446
2636
|
|
2447
|
-
if (allowEmpty && tokType === _comma)
|
2448
|
-
|
2637
|
+
if (allowEmpty && tokType === _comma) {
|
2638
|
+
elts.push(null);
|
2639
|
+
} else {
|
2640
|
+
if (tokType === _ellipsis)
|
2641
|
+
elts.push(parseSpread(refShorthandDefaultPos));
|
2642
|
+
else
|
2643
|
+
elts.push(parseMaybeAssign(false, refShorthandDefaultPos));
|
2644
|
+
}
|
2449
2645
|
}
|
2450
2646
|
return elts;
|
2451
2647
|
}
|
@@ -2470,7 +2666,6 @@
|
|
2470
2666
|
} else {
|
2471
2667
|
unexpected();
|
2472
2668
|
}
|
2473
|
-
tokRegexpAllowed = false;
|
2474
2669
|
next();
|
2475
2670
|
return finishNode(node, "Identifier");
|
2476
2671
|
}
|
@@ -2481,14 +2676,21 @@
|
|
2481
2676
|
next();
|
2482
2677
|
// export var|const|let|function|class ...;
|
2483
2678
|
if (tokType === _var || tokType === _const || tokType === _let || tokType === _function || tokType === _class) {
|
2484
|
-
node.declaration = parseStatement();
|
2679
|
+
node.declaration = parseStatement(true);
|
2485
2680
|
node['default'] = false;
|
2486
2681
|
node.specifiers = null;
|
2487
2682
|
node.source = null;
|
2488
2683
|
} else
|
2489
2684
|
// export default ...;
|
2490
2685
|
if (eat(_default)) {
|
2491
|
-
|
2686
|
+
var expr = parseMaybeAssign();
|
2687
|
+
if (expr.id) {
|
2688
|
+
switch (expr.type) {
|
2689
|
+
case "FunctionExpression": expr.type = "FunctionDeclaration"; break;
|
2690
|
+
case "ClassExpression": expr.type = "ClassDeclaration"; break;
|
2691
|
+
}
|
2692
|
+
}
|
2693
|
+
node.declaration = expr;
|
2492
2694
|
node['default'] = true;
|
2493
2695
|
node.specifiers = null;
|
2494
2696
|
node.source = null;
|
@@ -2500,8 +2702,7 @@
|
|
2500
2702
|
node.declaration = null;
|
2501
2703
|
node['default'] = false;
|
2502
2704
|
node.specifiers = parseExportSpecifiers();
|
2503
|
-
if (
|
2504
|
-
next();
|
2705
|
+
if (eatContextual("from")) {
|
2505
2706
|
node.source = tokType === _string ? parseExprAtom() : unexpected();
|
2506
2707
|
} else {
|
2507
2708
|
if (isBatch) unexpected();
|
@@ -2532,12 +2733,7 @@
|
|
2532
2733
|
|
2533
2734
|
var node = startNode();
|
2534
2735
|
node.id = parseIdent(tokType === _default);
|
2535
|
-
|
2536
|
-
next();
|
2537
|
-
node.name = parseIdent(true);
|
2538
|
-
} else {
|
2539
|
-
node.name = null;
|
2540
|
-
}
|
2736
|
+
node.name = eatContextual("as") ? parseIdent(true) : null;
|
2541
2737
|
nodes.push(finishNode(node, "ExportSpecifier"));
|
2542
2738
|
}
|
2543
2739
|
}
|
@@ -2555,8 +2751,7 @@
|
|
2555
2751
|
node.kind = "";
|
2556
2752
|
} else {
|
2557
2753
|
node.specifiers = parseImportSpecifiers();
|
2558
|
-
|
2559
|
-
next();
|
2754
|
+
expectContextual("from");
|
2560
2755
|
node.source = tokType === _string ? parseExprAtom() : unexpected();
|
2561
2756
|
}
|
2562
2757
|
semicolon();
|
@@ -2580,8 +2775,7 @@
|
|
2580
2775
|
if (tokType === _star) {
|
2581
2776
|
var node = startNode();
|
2582
2777
|
next();
|
2583
|
-
|
2584
|
-
next();
|
2778
|
+
expectContextual("as");
|
2585
2779
|
node.name = parseIdent();
|
2586
2780
|
checkLVal(node.name, true);
|
2587
2781
|
nodes.push(finishNode(node, "ImportBatchSpecifier"));
|
@@ -2596,12 +2790,7 @@
|
|
2596
2790
|
|
2597
2791
|
var node = startNode();
|
2598
2792
|
node.id = parseIdent(true);
|
2599
|
-
|
2600
|
-
next();
|
2601
|
-
node.name = parseIdent();
|
2602
|
-
} else {
|
2603
|
-
node.name = null;
|
2604
|
-
}
|
2793
|
+
node.name = eatContextual("as") ? parseIdent() : null;
|
2605
2794
|
checkLVal(node.name || node.id, true);
|
2606
2795
|
node['default'] = false;
|
2607
2796
|
nodes.push(finishNode(node, "ImportSpecifier"));
|
@@ -2619,7 +2808,7 @@
|
|
2619
2808
|
node.argument = null;
|
2620
2809
|
} else {
|
2621
2810
|
node.delegate = eat(_star);
|
2622
|
-
node.argument =
|
2811
|
+
node.argument = parseMaybeAssign();
|
2623
2812
|
}
|
2624
2813
|
return finishNode(node, "YieldExpression");
|
2625
2814
|
}
|
@@ -2632,13 +2821,9 @@
|
|
2632
2821
|
var block = startNode();
|
2633
2822
|
next();
|
2634
2823
|
expect(_parenL);
|
2635
|
-
block.left =
|
2824
|
+
block.left = parseBindingAtom();
|
2636
2825
|
checkLVal(block.left, true);
|
2637
|
-
|
2638
|
-
next();
|
2639
|
-
// `of` property is here for compatibility with Esprima's AST
|
2640
|
-
// which also supports deprecated [for (... in ...) expr]
|
2641
|
-
block.of = true;
|
2826
|
+
expectContextual("of");
|
2642
2827
|
block.right = parseExpression();
|
2643
2828
|
expect(_parenR);
|
2644
2829
|
node.blocks.push(finishNode(block, "ComprehensionBlock"));
|
@@ -2649,5 +2834,4 @@
|
|
2649
2834
|
node.generator = isGenerator;
|
2650
2835
|
return finishNode(node, "ComprehensionExpression");
|
2651
2836
|
}
|
2652
|
-
|
2653
2837
|
});
|