Merge branch 'upstream' into jsx2
Conflicts: acorn.js
This commit is contained in:
commit
d64efe1be4
11
README.md
11
README.md
@ -162,6 +162,17 @@ token, and returns a `{start, end, type, value}` object (with added
|
|||||||
`loc` property when the `locations` option is enabled and `range`
|
`loc` property when the `locations` option is enabled and `range`
|
||||||
property when the `ranges` option is enabled).
|
property when the `ranges` option is enabled).
|
||||||
|
|
||||||
|
In ES6 environment, returned result can be used as any other protocol-compliant iterable:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
for (let token of acorn.tokenize(str)) {
|
||||||
|
// iterate over the tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform code to array of tokens:
|
||||||
|
var tokens = [...acorn.tokenize(str)];
|
||||||
|
```
|
||||||
|
|
||||||
**tokTypes** holds an object mapping names to the token type objects
|
**tokTypes** holds an object mapping names to the token type objects
|
||||||
that end up in the `type` properties of tokens.
|
that end up in the `type` properties of tokens.
|
||||||
|
|
||||||
|
|||||||
138
acorn.js
138
acorn.js
@ -242,6 +242,7 @@
|
|||||||
tokExprAllowed = !!exprAllowed;
|
tokExprAllowed = !!exprAllowed;
|
||||||
skipSpace();
|
skipSpace();
|
||||||
};
|
};
|
||||||
|
getToken.current = function() { return new Token(); };
|
||||||
if (typeof Symbol !== 'undefined') {
|
if (typeof Symbol !== 'undefined') {
|
||||||
getToken[Symbol.iterator] = function () {
|
getToken[Symbol.iterator] = function () {
|
||||||
return {
|
return {
|
||||||
@ -319,13 +320,6 @@
|
|||||||
|
|
||||||
var metParenL;
|
var metParenL;
|
||||||
|
|
||||||
// This is used by the tokenizer to track the template strings it is
|
|
||||||
// inside, and count the amount of open braces seen inside them, to
|
|
||||||
// be able to switch back to a template token when the } to match ${
|
|
||||||
// is encountered. It will hold an array of integers.
|
|
||||||
|
|
||||||
var templates;
|
|
||||||
|
|
||||||
function initParserState() {
|
function initParserState() {
|
||||||
lastStart = lastEnd = tokPos;
|
lastStart = lastEnd = tokPos;
|
||||||
if (options.locations) lastEndLoc = curPosition();
|
if (options.locations) lastEndLoc = curPosition();
|
||||||
@ -428,10 +422,10 @@
|
|||||||
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
|
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
|
||||||
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
|
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
|
||||||
var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
|
var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
|
||||||
var _arrow = {type: "=>", beforeExpr: true};
|
var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"};
|
||||||
var _template = {type: "template"}, _templateContinued = {type: "templateContinued"};
|
|
||||||
var _xjsText = {type: "xjsText"};
|
|
||||||
var _ellipsis = {type: "...", prefix: true, beforeExpr: true};
|
var _ellipsis = {type: "...", prefix: true, beforeExpr: true};
|
||||||
|
var _backQuote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
|
||||||
|
var _xjsText = {type: "xjsText"};
|
||||||
|
|
||||||
// Operators. These carry several kinds of properties to help the
|
// Operators. These carry several kinds of properties to help the
|
||||||
// parser use them properly (the presence of these properties is
|
// parser use them properly (the presence of these properties is
|
||||||
@ -476,8 +470,8 @@
|
|||||||
parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
|
parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
|
||||||
dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
|
dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
|
||||||
name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
|
name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
|
||||||
arrow: _arrow, template: _template, templateContinued: _templateContinued, star: _star,
|
arrow: _arrow, template: _template, star: _star, assign: _assign,
|
||||||
assign: _assign};
|
backQuote: _backQuote, dollarBraceL: _dollarBraceL};
|
||||||
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
|
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
|
||||||
|
|
||||||
// This is a trick taken from Esprima. It turns out that, on
|
// This is a trick taken from Esprima. It turns out that, on
|
||||||
@ -639,7 +633,6 @@
|
|||||||
tokContext = [];
|
tokContext = [];
|
||||||
tokExprAllowed = true;
|
tokExprAllowed = true;
|
||||||
metParenL = 0;
|
metParenL = 0;
|
||||||
templates = [];
|
|
||||||
if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') {
|
if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') {
|
||||||
skipLineComment(2);
|
skipLineComment(2);
|
||||||
}
|
}
|
||||||
@ -649,8 +642,9 @@
|
|||||||
// given point in the program is loosely based on sweet.js' approach.
|
// given point in the program is loosely based on sweet.js' approach.
|
||||||
// See https://github.com/mozilla/sweet.js/wiki/design
|
// See https://github.com/mozilla/sweet.js/wiki/design
|
||||||
|
|
||||||
var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true};
|
var b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true};
|
||||||
var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true};
|
var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true};
|
||||||
|
var q_tmpl = {token: "`", isExpr: true};
|
||||||
var j_oTag = {token: "<tag", isExpr: false}, j_cTag = {token: "</tag", isExpr: false}, j_expr = {token: "<tag>...</tag>", isExpr: true};
|
var j_oTag = {token: "<tag", isExpr: false}, j_cTag = {token: "</tag", isExpr: false}, j_expr = {token: "<tag>...</tag>", isExpr: true};
|
||||||
|
|
||||||
function curTokContext() {
|
function curTokContext() {
|
||||||
@ -682,7 +676,7 @@
|
|||||||
function finishToken(type, val) {
|
function finishToken(type, val) {
|
||||||
tokEnd = tokPos;
|
tokEnd = tokPos;
|
||||||
if (options.locations) tokEndLoc = curPosition();
|
if (options.locations) tokEndLoc = curPosition();
|
||||||
var prevType = tokType;
|
var prevType = tokType, preserveSpace = false;
|
||||||
tokType = type;
|
tokType = type;
|
||||||
tokVal = val;
|
tokVal = val;
|
||||||
|
|
||||||
@ -690,9 +684,13 @@
|
|||||||
if (type === _parenR || type === _braceR) {
|
if (type === _parenR || type === _braceR) {
|
||||||
var out = tokContext.pop();
|
var out = tokContext.pop();
|
||||||
tokExprAllowed = !(out && out.isExpr);
|
tokExprAllowed = !(out && out.isExpr);
|
||||||
|
preserveSpace = out === b_tmpl;
|
||||||
} else if (type === _braceL) {
|
} else if (type === _braceL) {
|
||||||
tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr);
|
tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr);
|
||||||
tokExprAllowed = true;
|
tokExprAllowed = true;
|
||||||
|
} else if (type === _dollarBraceL) {
|
||||||
|
tokContext.push(b_tmpl);
|
||||||
|
tokExprAllowed = true;
|
||||||
} else if (type == _parenL) {
|
} else if (type == _parenL) {
|
||||||
var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while;
|
var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while;
|
||||||
tokContext.push(statementParens ? p_stat : p_expr);
|
tokContext.push(statementParens ? p_stat : p_expr);
|
||||||
@ -703,6 +701,15 @@
|
|||||||
tokExprAllowed = false;
|
tokExprAllowed = false;
|
||||||
} else if (tokExprAllowed && type == _function) {
|
} else if (tokExprAllowed && type == _function) {
|
||||||
tokExprAllowed = false;
|
tokExprAllowed = false;
|
||||||
|
} else if (type === _backQuote) {
|
||||||
|
if (tokContext[tokContext.length - 1] === q_tmpl) {
|
||||||
|
tokContext.pop();
|
||||||
|
} else {
|
||||||
|
tokContext.push(q_tmpl);
|
||||||
|
preserveSpace = true;
|
||||||
|
}
|
||||||
|
tokExprAllowed = false;
|
||||||
|
tokExprAllowed = false;
|
||||||
} else if (type === _xjsTagStart) {
|
} else if (type === _xjsTagStart) {
|
||||||
tokContext.push(j_expr); // treat as beginning of JSX expression
|
tokContext.push(j_expr); // treat as beginning of JSX expression
|
||||||
tokContext.push(j_oTag); // start opening tag context
|
tokContext.push(j_oTag); // start opening tag context
|
||||||
@ -725,7 +732,7 @@
|
|||||||
tokExprAllowed = type.beforeExpr;
|
tokExprAllowed = type.beforeExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curTokContext() !== j_expr) skipSpace();
|
if (!preserveSpace && curTokContext() !== j_expr) skipSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
function skipBlockComment() {
|
function skipBlockComment() {
|
||||||
@ -921,23 +928,17 @@
|
|||||||
case 44: ++tokPos; return finishToken(_comma);
|
case 44: ++tokPos; return finishToken(_comma);
|
||||||
case 91: ++tokPos; return finishToken(_bracketL);
|
case 91: ++tokPos; return finishToken(_bracketL);
|
||||||
case 93: ++tokPos; return finishToken(_bracketR);
|
case 93: ++tokPos; return finishToken(_bracketR);
|
||||||
case 123: // '{'
|
case 123: ++tokPos; return finishToken(_braceL);
|
||||||
++tokPos;
|
case 125: ++tokPos; return finishToken(_braceR);
|
||||||
if (templates.length) ++templates[templates.length - 1];
|
|
||||||
return finishToken(_braceL);
|
|
||||||
case 125: // '}'
|
|
||||||
++tokPos;
|
|
||||||
if (templates.length && --templates[templates.length - 1] === 0)
|
|
||||||
return readTemplateString(_templateContinued);
|
|
||||||
else
|
|
||||||
return finishToken(_braceR);
|
|
||||||
case 58: ++tokPos; return finishToken(_colon);
|
case 58: ++tokPos; return finishToken(_colon);
|
||||||
case 63: ++tokPos; return finishToken(_question);
|
case 63: ++tokPos; return finishToken(_question);
|
||||||
|
|
||||||
case 96: // '`'
|
case 96: // '`'
|
||||||
if (options.ecmaVersion >= 6) {
|
if (options.ecmaVersion >= 6) {
|
||||||
++tokPos;
|
++tokPos;
|
||||||
return readTemplateString(_template);
|
return finishToken(_backQuote);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 48: // '0'
|
case 48: // '0'
|
||||||
@ -994,6 +995,10 @@
|
|||||||
if (options.locations) tokStartLoc = curPosition();
|
if (options.locations) tokStartLoc = curPosition();
|
||||||
if (tokPos >= inputLen) return finishToken(_eof);
|
if (tokPos >= inputLen) return finishToken(_eof);
|
||||||
|
|
||||||
|
if (tokContext[tokContext.length - 1] === q_tmpl) {
|
||||||
|
return readTmplToken();
|
||||||
|
}
|
||||||
|
|
||||||
var code = input.charCodeAt(tokPos);
|
var code = input.charCodeAt(tokPos);
|
||||||
var context = curTokContext();
|
var context = curTokContext();
|
||||||
|
|
||||||
@ -1189,34 +1194,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readTemplateString(type) {
|
// Reads template string tokens.
|
||||||
if (type == _templateContinued) templates.pop();
|
|
||||||
var out = "", start = tokPos;;
|
function readTmplToken() {
|
||||||
|
var out = "", start = tokPos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
|
if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
|
||||||
var ch = input.charAt(tokPos);
|
var ch = input.charCodeAt(tokPos);
|
||||||
if (ch === "`" || ch === "$" && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
|
if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
|
||||||
var raw = input.slice(start, tokPos);
|
if (tokPos === start && tokType === _template) {
|
||||||
|
if (ch === 36) {
|
||||||
|
tokPos += 2;
|
||||||
|
return finishToken(_dollarBraceL);
|
||||||
|
} else {
|
||||||
++tokPos;
|
++tokPos;
|
||||||
if (ch == "$") { ++tokPos; templates.push(1); }
|
return finishToken(_backQuote);
|
||||||
return finishToken(type, {cooked: out, raw: raw});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (ch === "\\") { // '\'
|
return finishToken(_template, out);
|
||||||
|
}
|
||||||
|
if (ch === 92) { // '\'
|
||||||
out += readEscapedChar();
|
out += readEscapedChar();
|
||||||
} else {
|
} else {
|
||||||
++tokPos;
|
++tokPos;
|
||||||
if (newline.test(ch)) {
|
if (isNewLine(ch)) {
|
||||||
if (ch === "\r" && input.charCodeAt(tokPos) === 10) {
|
if (ch === 13 && input.charCodeAt(tokPos) === 10) {
|
||||||
++tokPos;
|
++tokPos;
|
||||||
ch = "\n";
|
ch = 10;
|
||||||
}
|
}
|
||||||
if (options.locations) {
|
if (options.locations) {
|
||||||
++tokCurLine;
|
++tokCurLine;
|
||||||
tokLineStart = tokPos;
|
tokLineStart = tokPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out += ch;
|
out += String.fromCharCode(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1688,11 +1699,12 @@
|
|||||||
readToken();
|
readToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter strict mode. Re-reads the next token to please pedantic
|
// Enter strict mode. Re-reads the next number or string to
|
||||||
// tests ("use strict"; 010; -- should fail).
|
// please pedantic tests ("use strict"; 010; -- should fail).
|
||||||
|
|
||||||
function setStrict(strct) {
|
function setStrict(strct) {
|
||||||
strict = strct;
|
strict = strct;
|
||||||
|
if (tokType !== _num && tokType !== _string) return;
|
||||||
tokPos = tokStart;
|
tokPos = tokStart;
|
||||||
if (options.locations) {
|
if (options.locations) {
|
||||||
while (tokPos < tokLineStart) {
|
while (tokPos < tokLineStart) {
|
||||||
@ -1767,15 +1779,6 @@
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishNodeAt(node, type, pos) {
|
|
||||||
if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; }
|
|
||||||
node.type = type;
|
|
||||||
node.end = pos;
|
|
||||||
if (options.ranges)
|
|
||||||
node.range[1] = pos;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test whether a statement node is the string literal `"use strict"`.
|
// Test whether a statement node is the string literal `"use strict"`.
|
||||||
|
|
||||||
function isUseStrict(stmt) {
|
function isUseStrict(stmt) {
|
||||||
@ -2415,18 +2418,14 @@
|
|||||||
|
|
||||||
function parseMaybeAssign(noIn) {
|
function parseMaybeAssign(noIn) {
|
||||||
var start = storeCurrentPos();
|
var start = storeCurrentPos();
|
||||||
var oldParenL = metParenL;
|
|
||||||
var left = parseMaybeConditional(noIn);
|
var left = parseMaybeConditional(noIn);
|
||||||
if (tokType.isAssign) {
|
if (tokType.isAssign) {
|
||||||
if (metParenL !== oldParenL) raise(tokStart, "Assigning to rvalue");
|
|
||||||
var node = startNodeAt(start);
|
var node = startNodeAt(start);
|
||||||
node.operator = tokVal;
|
node.operator = tokVal;
|
||||||
node.left = tokType === _eq ? toAssignable(left) : left;
|
node.left = tokType === _eq ? toAssignable(left) : left;
|
||||||
checkLVal(left);
|
checkLVal(left);
|
||||||
next();
|
next();
|
||||||
node.right = parseMaybeAssign(noIn);
|
node.right = parseMaybeAssign(noIn);
|
||||||
// restore count of '(' so they are allowed in lvalue's defaults
|
|
||||||
metParenL = oldParenL;
|
|
||||||
return finishNode(node, "AssignmentExpression");
|
return finishNode(node, "AssignmentExpression");
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
@ -2539,7 +2538,7 @@
|
|||||||
node.callee = base;
|
node.callee = base;
|
||||||
node.arguments = parseExprList(_parenR, false);
|
node.arguments = parseExprList(_parenR, false);
|
||||||
return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls);
|
return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls);
|
||||||
} else if (tokType === _template) {
|
} else if (tokType === _backQuote) {
|
||||||
var node = startNodeAt(start);
|
var node = startNodeAt(start);
|
||||||
node.tag = base;
|
node.tag = base;
|
||||||
node.quasi = parseTemplate();
|
node.quasi = parseTemplate();
|
||||||
@ -2654,7 +2653,7 @@
|
|||||||
case _new:
|
case _new:
|
||||||
return parseNew();
|
return parseNew();
|
||||||
|
|
||||||
case _template:
|
case _backQuote:
|
||||||
return parseTemplate();
|
return parseTemplate();
|
||||||
|
|
||||||
case _xjsTagStart:
|
case _xjsTagStart:
|
||||||
@ -2682,24 +2681,29 @@
|
|||||||
// Parse template expression.
|
// Parse template expression.
|
||||||
|
|
||||||
function parseTemplateElement() {
|
function parseTemplateElement() {
|
||||||
var elem = startNodeAt(options.locations ? [tokStart + 1, tokStartLoc.offset(1)] : tokStart + 1);
|
var elem = startNode();
|
||||||
elem.value = tokVal;
|
elem.value = {
|
||||||
elem.tail = input.charCodeAt(tokEnd - 1) !== 123; // '{'
|
raw: input.slice(tokStart, tokEnd),
|
||||||
|
cooked: tokVal
|
||||||
|
};
|
||||||
next();
|
next();
|
||||||
var endOff = elem.tail ? 1 : 2;
|
elem.tail = tokType === _backQuote;
|
||||||
return finishNodeAt(elem, "TemplateElement", options.locations ? [lastEnd - endOff, lastEndLoc.offset(-endOff)] : lastEnd - endOff);
|
return finishNode(elem, "TemplateElement");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTemplate() {
|
function parseTemplate() {
|
||||||
var node = startNode();
|
var node = startNode();
|
||||||
|
next();
|
||||||
node.expressions = [];
|
node.expressions = [];
|
||||||
var curElt = parseTemplateElement();
|
var curElt = parseTemplateElement();
|
||||||
node.quasis = [curElt];
|
node.quasis = [curElt];
|
||||||
while (!curElt.tail) {
|
while (!curElt.tail) {
|
||||||
|
expect(_dollarBraceL);
|
||||||
node.expressions.push(parseExpression());
|
node.expressions.push(parseExpression());
|
||||||
if (tokType !== _templateContinued) unexpected();
|
expect(_braceR);
|
||||||
node.quasis.push(curElt = parseTemplateElement());
|
node.quasis.push(curElt = parseTemplateElement());
|
||||||
}
|
}
|
||||||
|
next();
|
||||||
return finishNode(node, "TemplateLiteral");
|
return finishNode(node, "TemplateLiteral");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2757,10 +2761,7 @@
|
|||||||
if (options.ecmaVersion >= 6) {
|
if (options.ecmaVersion >= 6) {
|
||||||
if (eat(_bracketL)) {
|
if (eat(_bracketL)) {
|
||||||
prop.computed = true;
|
prop.computed = true;
|
||||||
// save & restore count of '(' so they are allowed in lvalue's computed props
|
|
||||||
var oldParenL = metParenL;
|
|
||||||
prop.key = parseExpression();
|
prop.key = parseExpression();
|
||||||
metParenL = oldParenL;
|
|
||||||
expect(_bracketR);
|
expect(_bracketR);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -3158,9 +3159,6 @@
|
|||||||
checkLVal(block.left, true);
|
checkLVal(block.left, true);
|
||||||
if (tokType !== _name || tokVal !== "of") unexpected();
|
if (tokType !== _name || tokVal !== "of") unexpected();
|
||||||
next();
|
next();
|
||||||
// `of` property is here for compatibility with Esprima's AST
|
|
||||||
// which also supports deprecated [for (... in ...) expr]
|
|
||||||
block.of = true;
|
|
||||||
block.right = parseExpression();
|
block.right = parseExpression();
|
||||||
expect(_parenR);
|
expect(_parenR);
|
||||||
node.blocks.push(finishNode(block, "ComprehensionBlock"));
|
node.blocks.push(finishNode(block, "ComprehensionBlock"));
|
||||||
|
|||||||
@ -66,6 +66,8 @@
|
|||||||
ahead.length = 0;
|
ahead.length = 0;
|
||||||
|
|
||||||
token = ahead.shift() || readToken(forceRegexp);
|
token = ahead.shift() || readToken(forceRegexp);
|
||||||
|
if (options.onToken)
|
||||||
|
options.onToken(token);
|
||||||
|
|
||||||
if (token.start >= nextLineStart) {
|
if (token.start >= nextLineStart) {
|
||||||
while (token.start >= nextLineStart) {
|
while (token.start >= nextLineStart) {
|
||||||
@ -101,8 +103,10 @@
|
|||||||
replace = {start: e.pos, end: pos, type: tt.regexp, value: re};
|
replace = {start: e.pos, end: pos, type: tt.regexp, value: re};
|
||||||
} else if (/template/.test(msg)) {
|
} else if (/template/.test(msg)) {
|
||||||
replace = {start: e.pos, end: pos,
|
replace = {start: e.pos, end: pos,
|
||||||
type: input.charAt(e.pos) == "`" ? tt.template : tt.templateContinued,
|
type: tt.template,
|
||||||
value: input.slice(e.pos + 1, pos)};
|
value: input.slice(e.pos, pos)};
|
||||||
|
} else if (/comment/.test(msg)) {
|
||||||
|
replace = fetchToken.current();
|
||||||
} else {
|
} else {
|
||||||
replace = false;
|
replace = false;
|
||||||
}
|
}
|
||||||
@ -253,14 +257,6 @@
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishNodeAt(node, type, pos) {
|
|
||||||
if (options.locations) { node.loc.end = pos[1]; pos = pos[0]; }
|
|
||||||
node.type = type;
|
|
||||||
node.end = pos;
|
|
||||||
if (options.ranges) node.range[1] = pos;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
function dummyIdent() {
|
function dummyIdent() {
|
||||||
var dummy = startNode();
|
var dummy = startNode();
|
||||||
dummy.name = "✖";
|
dummy.name = "✖";
|
||||||
@ -693,7 +689,7 @@
|
|||||||
node.callee = base;
|
node.callee = base;
|
||||||
node.arguments = parseExprList(tt.parenR);
|
node.arguments = parseExprList(tt.parenR);
|
||||||
base = finishNode(node, "CallExpression");
|
base = finishNode(node, "CallExpression");
|
||||||
} else if (token.type == tt.template) {
|
} else if (token.type == tt.backQuote) {
|
||||||
var node = startNodeAt(start);
|
var node = startNodeAt(start);
|
||||||
node.tag = base;
|
node.tag = base;
|
||||||
node.quasi = parseTemplate();
|
node.quasi = parseTemplate();
|
||||||
@ -786,7 +782,7 @@
|
|||||||
}
|
}
|
||||||
return finishNode(node, "YieldExpression");
|
return finishNode(node, "YieldExpression");
|
||||||
|
|
||||||
case tt.template:
|
case tt.backQuote:
|
||||||
return parseTemplate();
|
return parseTemplate();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -809,36 +805,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseTemplateElement() {
|
function parseTemplateElement() {
|
||||||
var elem = startNodeAt(options.locations ? [token.start + 1, token.startLoc.offset(1)] : token.start + 1);
|
var elem = startNode();
|
||||||
elem.value = token.value;
|
elem.value = {
|
||||||
elem.tail = input.charCodeAt(token.end - 1) !== 123; // '{'
|
raw: input.slice(token.start, token.end),
|
||||||
var endOff = elem.tail ? 1 : 2;
|
cooked: token.value
|
||||||
var endPos = options.locations ? [token.end - endOff, token.endLoc.offset(-endOff)] : token.end - endOff;
|
};
|
||||||
next();
|
next();
|
||||||
return finishNodeAt(elem, "TemplateElement", endPos);
|
elem.tail = token.type === tt.backQuote;
|
||||||
|
return finishNode(elem, "TemplateElement");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTemplate() {
|
function parseTemplate() {
|
||||||
var node = startNode();
|
var node = startNode();
|
||||||
|
next();
|
||||||
node.expressions = [];
|
node.expressions = [];
|
||||||
var curElt = parseTemplateElement();
|
var curElt = parseTemplateElement();
|
||||||
node.quasis = [curElt];
|
node.quasis = [curElt];
|
||||||
while (!curElt.tail) {
|
while (!curElt.tail) {
|
||||||
var next = parseExpression();
|
next();
|
||||||
if (isDummy(next)) {
|
node.expressions.push(parseExpression());
|
||||||
node.quasis[node.quasis.length - 1].tail = true;
|
if (expect(tt.braceR)) {
|
||||||
break;
|
curElt = parseTemplateElement();
|
||||||
}
|
|
||||||
node.expressions.push(next);
|
|
||||||
if (token.type === tt.templateContinued) {
|
|
||||||
node.quasis.push(curElt = parseTemplateElement());
|
|
||||||
} else {
|
} else {
|
||||||
curElt = startNode();
|
curElt = startNode();
|
||||||
curElt.value = {cooked: "", raw: ""};
|
curElt.value = {cooked: '', raw: ''};
|
||||||
curElt.tail = true;
|
curElt.tail = true;
|
||||||
|
}
|
||||||
node.quasis.push(curElt);
|
node.quasis.push(curElt);
|
||||||
}
|
}
|
||||||
}
|
expect(tt.backQuote);
|
||||||
return finishNode(node, "TemplateLiteral");
|
return finishNode(node, "TemplateLiteral");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ for (var i = 2; i < process.argv.length; ++i) {
|
|||||||
else if (arg == "--ecma3") options.ecmaVersion = 3;
|
else if (arg == "--ecma3") options.ecmaVersion = 3;
|
||||||
else if (arg == "--ecma5") options.ecmaVersion = 5;
|
else if (arg == "--ecma5") options.ecmaVersion = 5;
|
||||||
else if (arg == "--ecma6") options.ecmaVersion = 6;
|
else if (arg == "--ecma6") options.ecmaVersion = 6;
|
||||||
|
else if (arg == "--ecma7") options.ecmaVersion = 7;
|
||||||
else if (arg == "--strictSemicolons") options.strictSemicolons = true;
|
else if (arg == "--strictSemicolons") options.strictSemicolons = true;
|
||||||
else if (arg == "--locations") options.locations = true;
|
else if (arg == "--locations") options.locations = true;
|
||||||
else if (arg == "--silent") silent = true;
|
else if (arg == "--silent") silent = true;
|
||||||
|
|||||||
@ -3328,8 +3328,7 @@ test("[for (x of array) x]", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 1},
|
start: {line: 1, column: 1},
|
||||||
end: {line: 1, column: 17}
|
end: {line: 1, column: 17}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
}],
|
}],
|
||||||
body: {
|
body: {
|
||||||
type: "Identifier",
|
type: "Identifier",
|
||||||
@ -3412,8 +3411,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 1},
|
start: {line: 1, column: 1},
|
||||||
end: {line: 1, column: 17}
|
end: {line: 1, column: 17}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "ComprehensionBlock",
|
type: "ComprehensionBlock",
|
||||||
@ -3436,8 +3434,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 18},
|
start: {line: 1, column: 18},
|
||||||
end: {line: 1, column: 35}
|
end: {line: 1, column: 35}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: {
|
body: {
|
||||||
@ -3521,8 +3518,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 1},
|
start: {line: 1, column: 1},
|
||||||
end: {line: 1, column: 17}
|
end: {line: 1, column: 17}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "ComprehensionBlock",
|
type: "ComprehensionBlock",
|
||||||
@ -3545,8 +3541,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 18},
|
start: {line: 1, column: 18},
|
||||||
end: {line: 1, column: 35}
|
end: {line: 1, column: 35}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: {
|
body: {
|
||||||
@ -3617,8 +3612,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 1},
|
start: {line: 1, column: 1},
|
||||||
end: {line: 1, column: 20}
|
end: {line: 1, column: 20}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "ComprehensionBlock",
|
type: "ComprehensionBlock",
|
||||||
@ -3728,8 +3722,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", {
|
|||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 21},
|
start: {line: 1, column: 21},
|
||||||
end: {line: 1, column: 65}
|
end: {line: 1, column: 65}
|
||||||
},
|
}
|
||||||
of: true
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: {
|
body: {
|
||||||
@ -3940,7 +3933,7 @@ test("[a, b] = [b, a]", {
|
|||||||
locations: true
|
locations: true
|
||||||
});
|
});
|
||||||
|
|
||||||
test("({ responseText: text } = res)", {
|
test("({ responseText: text }) = res", {
|
||||||
type: "Program",
|
type: "Program",
|
||||||
body: [{
|
body: [{
|
||||||
type: "ExpressionStatement",
|
type: "ExpressionStatement",
|
||||||
@ -3985,13 +3978,13 @@ test("({ responseText: text } = res)", {
|
|||||||
type: "Identifier",
|
type: "Identifier",
|
||||||
name: "res",
|
name: "res",
|
||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 26},
|
start: {line: 1, column: 27},
|
||||||
end: {line: 1, column: 29}
|
end: {line: 1, column: 30}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loc: {
|
loc: {
|
||||||
start: {line: 1, column: 1},
|
start: {line: 1, column: 0},
|
||||||
end: {line: 1, column: 29}
|
end: {line: 1, column: 30}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loc: {
|
loc: {
|
||||||
@ -13826,11 +13819,9 @@ testFail("[v] += ary", "Assigning to rvalue (1:0)", {ecmaVersion: 6});
|
|||||||
|
|
||||||
testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
|
testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("({ obj:20 }) = 42", "Assigning to rvalue (1:13)", {ecmaVersion: 6});
|
testFail("({ obj:20 }) = 42", "Assigning to rvalue (1:7)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("({ obj:20 } = 42)", "Assigning to rvalue (1:7)", {ecmaVersion: 6});
|
testFail("( { get x() {} } ) = 0", "Unexpected token (1:8)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("( { get x() {} } = 0 )", "Unexpected token (1:8)", {ecmaVersion: 6});
|
|
||||||
|
|
||||||
testFail("x \n is y", "Unexpected token (2:4)", {ecmaVersion: 6});
|
testFail("x \n is y", "Unexpected token (2:4)", {ecmaVersion: 6});
|
||||||
|
|
||||||
@ -13850,9 +13841,9 @@ testFail("let default", "Unexpected token (1:4)", {ecmaVersion: 6});
|
|||||||
|
|
||||||
testFail("const default", "Unexpected token (1:6)", {ecmaVersion: 6});
|
testFail("const default", "Unexpected token (1:6)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; ({ v: eval } = obj)", "Assigning to eval in strict mode (1:20)", {ecmaVersion: 6});
|
testFail("\"use strict\"; ({ v: eval }) = obj", "Assigning to eval in strict mode (1:20)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("\"use strict\"; ({ v: arguments } = obj)", "Assigning to arguments in strict mode (1:20)", {ecmaVersion: 6});
|
testFail("\"use strict\"; ({ v: arguments }) = obj", "Assigning to arguments in strict mode (1:20)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("for (let x = 42 in list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6});
|
testFail("for (let x = 42 in list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6});
|
||||||
|
|
||||||
@ -14086,7 +14077,7 @@ testFail("class A extends yield B { }", "Unexpected token (1:22)", {ecmaVersion:
|
|||||||
|
|
||||||
testFail("class default", "Unexpected token (1:6)", {ecmaVersion: 6});
|
testFail("class default", "Unexpected token (1:6)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("`test", "Unterminated template (1:0)", {ecmaVersion: 6});
|
testFail("`test", "Unterminated template (1:1)", {ecmaVersion: 6});
|
||||||
|
|
||||||
testFail("switch `test`", "Unexpected token (1:7)", {ecmaVersion: 6});
|
testFail("switch `test`", "Unexpected token (1:7)", {ecmaVersion: 6});
|
||||||
|
|
||||||
@ -14755,3 +14746,97 @@ test("class A { *static() {} }", {
|
|||||||
ranges: true,
|
ranges: true,
|
||||||
locations: true
|
locations: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("`${/\d/.exec('1')[0]}`", {
|
||||||
|
"type": "Program",
|
||||||
|
"start": 0,
|
||||||
|
"end": 21,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "ExpressionStatement",
|
||||||
|
"start": 0,
|
||||||
|
"end": 21,
|
||||||
|
"expression": {
|
||||||
|
"type": "TemplateLiteral",
|
||||||
|
"start": 0,
|
||||||
|
"end": 21,
|
||||||
|
"expressions": [
|
||||||
|
{
|
||||||
|
"type": "MemberExpression",
|
||||||
|
"start": 3,
|
||||||
|
"end": 19,
|
||||||
|
"object": {
|
||||||
|
"type": "CallExpression",
|
||||||
|
"start": 3,
|
||||||
|
"end": 16,
|
||||||
|
"callee": {
|
||||||
|
"type": "MemberExpression",
|
||||||
|
"start": 3,
|
||||||
|
"end": 11,
|
||||||
|
"object": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 3,
|
||||||
|
"end": 6,
|
||||||
|
"regex": {
|
||||||
|
"pattern": "d",
|
||||||
|
"flags": ""
|
||||||
|
},
|
||||||
|
"value": {},
|
||||||
|
"raw": "/d/"
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 7,
|
||||||
|
"end": 11,
|
||||||
|
"name": "exec"
|
||||||
|
},
|
||||||
|
"computed": false
|
||||||
|
},
|
||||||
|
"arguments": [
|
||||||
|
{
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 12,
|
||||||
|
"end": 15,
|
||||||
|
"value": "1",
|
||||||
|
"raw": "'1'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"property": {
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 17,
|
||||||
|
"end": 18,
|
||||||
|
"value": 0,
|
||||||
|
"raw": "0"
|
||||||
|
},
|
||||||
|
"computed": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quasis": [
|
||||||
|
{
|
||||||
|
"type": "TemplateElement",
|
||||||
|
"start": 1,
|
||||||
|
"end": 1,
|
||||||
|
"value": {
|
||||||
|
"raw": "",
|
||||||
|
"cooked": ""
|
||||||
|
},
|
||||||
|
"tail": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TemplateElement",
|
||||||
|
"start": 20,
|
||||||
|
"end": 20,
|
||||||
|
"value": {
|
||||||
|
"raw": "",
|
||||||
|
"cooked": ""
|
||||||
|
},
|
||||||
|
"tail": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
ecmaVersion: 6
|
||||||
|
});
|
||||||
|
|||||||
3466
test/tests-jsx.js
Normal file
3466
test/tests-jsx.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -403,7 +403,7 @@ test("(1 + 2 ) * 3", {
|
|||||||
preserveParens: true
|
preserveParens: true
|
||||||
});
|
});
|
||||||
|
|
||||||
testFail("(x) = 23", "Assigning to rvalue (1:4)");
|
testFail("(x) = 23", "Assigning to rvalue (1:0)", { preserveParens: true });
|
||||||
|
|
||||||
test("x = []", {
|
test("x = []", {
|
||||||
type: "Program",
|
type: "Program",
|
||||||
@ -26883,7 +26883,7 @@ testFail("func() = 4",
|
|||||||
"Assigning to rvalue (1:0)");
|
"Assigning to rvalue (1:0)");
|
||||||
|
|
||||||
testFail("(1 + 1) = 10",
|
testFail("(1 + 1) = 10",
|
||||||
"Assigning to rvalue (1:8)");
|
"Assigning to rvalue (1:1)");
|
||||||
|
|
||||||
testFail("1++",
|
testFail("1++",
|
||||||
"Assigning to rvalue (1:0)");
|
"Assigning to rvalue (1:0)");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user