diff --git a/README.md b/README.md index 5f790a8592..7714e873a7 100644 --- a/README.md +++ b/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` 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 that end up in the `type` properties of tokens. diff --git a/acorn.js b/acorn.js index 3d952ef184..a5820d6539 100644 --- a/acorn.js +++ b/acorn.js @@ -242,6 +242,7 @@ tokExprAllowed = !!exprAllowed; skipSpace(); }; + getToken.current = function() { return new Token(); }; if (typeof Symbol !== 'undefined') { getToken[Symbol.iterator] = function () { return { @@ -319,13 +320,6 @@ 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() { lastStart = lastEnd = tokPos; if (options.locations) lastEndLoc = curPosition(); @@ -428,10 +422,10 @@ var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"}; var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true}; var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true}; - var _arrow = {type: "=>", beforeExpr: true}; - var _template = {type: "template"}, _templateContinued = {type: "templateContinued"}; - var _xjsText = {type: "xjsText"}; + var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"}; 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 // parser use them properly (the presence of these properties is @@ -476,8 +470,8 @@ parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon, dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string, - arrow: _arrow, template: _template, templateContinued: _templateContinued, star: _star, - assign: _assign}; + arrow: _arrow, template: _template, star: _star, assign: _assign, + backQuote: _backQuote, dollarBraceL: _dollarBraceL}; for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw]; // This is a trick taken from Esprima. It turns out that, on @@ -639,7 +633,6 @@ tokContext = []; tokExprAllowed = true; metParenL = 0; - templates = []; if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') { skipLineComment(2); } @@ -649,8 +642,9 @@ // given point in the program is loosely based on sweet.js' approach. // 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 q_tmpl = {token: "`", isExpr: true}; var j_oTag = {token: "...", isExpr: true}; function curTokContext() { @@ -682,7 +676,7 @@ function finishToken(type, val) { tokEnd = tokPos; if (options.locations) tokEndLoc = curPosition(); - var prevType = tokType; + var prevType = tokType, preserveSpace = false; tokType = type; tokVal = val; @@ -690,9 +684,13 @@ if (type === _parenR || type === _braceR) { var out = tokContext.pop(); tokExprAllowed = !(out && out.isExpr); + preserveSpace = out === b_tmpl; } else if (type === _braceL) { tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr); tokExprAllowed = true; + } else if (type === _dollarBraceL) { + tokContext.push(b_tmpl); + tokExprAllowed = true; } else if (type == _parenL) { var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while; tokContext.push(statementParens ? p_stat : p_expr); @@ -703,6 +701,15 @@ tokExprAllowed = false; } else if (tokExprAllowed && type == _function) { 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) { tokContext.push(j_expr); // treat as beginning of JSX expression tokContext.push(j_oTag); // start opening tag context @@ -725,7 +732,7 @@ tokExprAllowed = type.beforeExpr; } - if (curTokContext() !== j_expr) skipSpace(); + if (!preserveSpace && curTokContext() !== j_expr) skipSpace(); } function skipBlockComment() { @@ -921,23 +928,17 @@ case 44: ++tokPos; return finishToken(_comma); case 91: ++tokPos; return finishToken(_bracketL); case 93: ++tokPos; return finishToken(_bracketR); - case 123: // '{' - ++tokPos; - 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 123: ++tokPos; return finishToken(_braceL); + case 125: ++tokPos; return finishToken(_braceR); case 58: ++tokPos; return finishToken(_colon); case 63: ++tokPos; return finishToken(_question); case 96: // '`' if (options.ecmaVersion >= 6) { ++tokPos; - return readTemplateString(_template); + return finishToken(_backQuote); + } else { + return false; } case 48: // '0' @@ -994,6 +995,10 @@ if (options.locations) tokStartLoc = curPosition(); if (tokPos >= inputLen) return finishToken(_eof); + if (tokContext[tokContext.length - 1] === q_tmpl) { + return readTmplToken(); + } + var code = input.charCodeAt(tokPos); var context = curTokContext(); @@ -1189,34 +1194,40 @@ } } - function readTemplateString(type) { - if (type == _templateContinued) templates.pop(); - var out = "", start = tokPos;; + // Reads template string tokens. + + function readTmplToken() { + var out = "", start = tokPos; for (;;) { if (tokPos >= inputLen) raise(tokStart, "Unterminated template"); - var ch = input.charAt(tokPos); - if (ch === "`" || ch === "$" && input.charCodeAt(tokPos + 1) === 123) { // '`', '${' - var raw = input.slice(start, tokPos); - ++tokPos; - if (ch == "$") { ++tokPos; templates.push(1); } - return finishToken(type, {cooked: out, raw: raw}); + var ch = input.charCodeAt(tokPos); + if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${' + if (tokPos === start && tokType === _template) { + if (ch === 36) { + tokPos += 2; + return finishToken(_dollarBraceL); + } else { + ++tokPos; + return finishToken(_backQuote); + } + } + return finishToken(_template, out); } - - if (ch === "\\") { // '\' + if (ch === 92) { // '\' out += readEscapedChar(); } else { ++tokPos; - if (newline.test(ch)) { - if (ch === "\r" && input.charCodeAt(tokPos) === 10) { + if (isNewLine(ch)) { + if (ch === 13 && input.charCodeAt(tokPos) === 10) { ++tokPos; - ch = "\n"; + ch = 10; } if (options.locations) { ++tokCurLine; tokLineStart = tokPos; } } - out += ch; + out += String.fromCharCode(ch); } } } @@ -1688,11 +1699,12 @@ readToken(); } - // Enter strict mode. Re-reads the next token to please pedantic - // tests ("use strict"; 010; -- should fail). + // Enter strict mode. Re-reads the next number or string to + // please pedantic tests ("use strict"; 010; -- should fail). function setStrict(strct) { strict = strct; + if (tokType !== _num && tokType !== _string) return; tokPos = tokStart; if (options.locations) { while (tokPos < tokLineStart) { @@ -1767,15 +1779,6 @@ 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"`. function isUseStrict(stmt) { @@ -2415,18 +2418,14 @@ function parseMaybeAssign(noIn) { var start = storeCurrentPos(); - var oldParenL = metParenL; var left = parseMaybeConditional(noIn); if (tokType.isAssign) { - if (metParenL !== oldParenL) raise(tokStart, "Assigning to rvalue"); var node = startNodeAt(start); node.operator = tokVal; node.left = tokType === _eq ? toAssignable(left) : left; checkLVal(left); next(); node.right = parseMaybeAssign(noIn); - // restore count of '(' so they are allowed in lvalue's defaults - metParenL = oldParenL; return finishNode(node, "AssignmentExpression"); } return left; @@ -2539,7 +2538,7 @@ node.callee = base; node.arguments = parseExprList(_parenR, false); return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls); - } else if (tokType === _template) { + } else if (tokType === _backQuote) { var node = startNodeAt(start); node.tag = base; node.quasi = parseTemplate(); @@ -2654,7 +2653,7 @@ case _new: return parseNew(); - case _template: + case _backQuote: return parseTemplate(); case _xjsTagStart: @@ -2682,24 +2681,29 @@ // Parse template expression. function parseTemplateElement() { - var elem = startNodeAt(options.locations ? [tokStart + 1, tokStartLoc.offset(1)] : tokStart + 1); - elem.value = tokVal; - elem.tail = input.charCodeAt(tokEnd - 1) !== 123; // '{' + var elem = startNode(); + elem.value = { + raw: input.slice(tokStart, tokEnd), + cooked: tokVal + }; next(); - var endOff = elem.tail ? 1 : 2; - return finishNodeAt(elem, "TemplateElement", options.locations ? [lastEnd - endOff, lastEndLoc.offset(-endOff)] : lastEnd - endOff); + elem.tail = tokType === _backQuote; + return finishNode(elem, "TemplateElement"); } function parseTemplate() { var node = startNode(); + next(); node.expressions = []; var curElt = parseTemplateElement(); node.quasis = [curElt]; while (!curElt.tail) { + expect(_dollarBraceL); node.expressions.push(parseExpression()); - if (tokType !== _templateContinued) unexpected(); + expect(_braceR); node.quasis.push(curElt = parseTemplateElement()); } + next(); return finishNode(node, "TemplateLiteral"); } @@ -2757,10 +2761,7 @@ if (options.ecmaVersion >= 6) { if (eat(_bracketL)) { prop.computed = true; - // save & restore count of '(' so they are allowed in lvalue's computed props - var oldParenL = metParenL; prop.key = parseExpression(); - metParenL = oldParenL; expect(_bracketR); return; } else { @@ -3158,9 +3159,6 @@ checkLVal(block.left, true); if (tokType !== _name || tokVal !== "of") unexpected(); next(); - // `of` property is here for compatibility with Esprima's AST - // which also supports deprecated [for (... in ...) expr] - block.of = true; block.right = parseExpression(); expect(_parenR); node.blocks.push(finishNode(block, "ComprehensionBlock")); diff --git a/acorn_loose.js b/acorn_loose.js index 010a2d7fdf..03d92b7352 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -66,6 +66,8 @@ ahead.length = 0; token = ahead.shift() || readToken(forceRegexp); + if (options.onToken) + options.onToken(token); if (token.start >= nextLineStart) { while (token.start >= nextLineStart) { @@ -101,8 +103,10 @@ replace = {start: e.pos, end: pos, type: tt.regexp, value: re}; } else if (/template/.test(msg)) { replace = {start: e.pos, end: pos, - type: input.charAt(e.pos) == "`" ? tt.template : tt.templateContinued, - value: input.slice(e.pos + 1, pos)}; + type: tt.template, + value: input.slice(e.pos, pos)}; + } else if (/comment/.test(msg)) { + replace = fetchToken.current(); } else { replace = false; } @@ -253,14 +257,6 @@ 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() { var dummy = startNode(); dummy.name = "✖"; @@ -693,7 +689,7 @@ node.callee = base; node.arguments = parseExprList(tt.parenR); base = finishNode(node, "CallExpression"); - } else if (token.type == tt.template) { + } else if (token.type == tt.backQuote) { var node = startNodeAt(start); node.tag = base; node.quasi = parseTemplate(); @@ -786,7 +782,7 @@ } return finishNode(node, "YieldExpression"); - case tt.template: + case tt.backQuote: return parseTemplate(); default: @@ -809,36 +805,35 @@ } function parseTemplateElement() { - var elem = startNodeAt(options.locations ? [token.start + 1, token.startLoc.offset(1)] : token.start + 1); - elem.value = token.value; - elem.tail = input.charCodeAt(token.end - 1) !== 123; // '{' - var endOff = elem.tail ? 1 : 2; - var endPos = options.locations ? [token.end - endOff, token.endLoc.offset(-endOff)] : token.end - endOff; + var elem = startNode(); + elem.value = { + raw: input.slice(token.start, token.end), + cooked: token.value + }; next(); - return finishNodeAt(elem, "TemplateElement", endPos); + elem.tail = token.type === tt.backQuote; + return finishNode(elem, "TemplateElement"); } function parseTemplate() { var node = startNode(); + next(); node.expressions = []; var curElt = parseTemplateElement(); node.quasis = [curElt]; while (!curElt.tail) { - var next = parseExpression(); - if (isDummy(next)) { - node.quasis[node.quasis.length - 1].tail = true; - break; - } - node.expressions.push(next); - if (token.type === tt.templateContinued) { - node.quasis.push(curElt = parseTemplateElement()); + next(); + node.expressions.push(parseExpression()); + if (expect(tt.braceR)) { + curElt = parseTemplateElement(); } else { curElt = startNode(); - curElt.value = {cooked: "", raw: ""}; + curElt.value = {cooked: '', raw: ''}; curElt.tail = true; - node.quasis.push(curElt); } + node.quasis.push(curElt); } + expect(tt.backQuote); return finishNode(node, "TemplateLiteral"); } diff --git a/bin/acorn b/bin/acorn index ca6e32a0c6..b80ad29d51 100755 --- a/bin/acorn +++ b/bin/acorn @@ -20,6 +20,7 @@ for (var i = 2; i < process.argv.length; ++i) { else if (arg == "--ecma3") options.ecmaVersion = 3; else if (arg == "--ecma5") options.ecmaVersion = 5; else if (arg == "--ecma6") options.ecmaVersion = 6; + else if (arg == "--ecma7") options.ecmaVersion = 7; else if (arg == "--strictSemicolons") options.strictSemicolons = true; else if (arg == "--locations") options.locations = true; else if (arg == "--silent") silent = true; diff --git a/test/tests-harmony.js b/test/tests-harmony.js index e38275483e..eb8b8c5812 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -3328,8 +3328,7 @@ test("[for (x of array) x]", { loc: { start: {line: 1, column: 1}, end: {line: 1, column: 17} - }, - of: true + } }], body: { type: "Identifier", @@ -3412,8 +3411,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", { loc: { start: {line: 1, column: 1}, end: {line: 1, column: 17} - }, - of: true + } }, { type: "ComprehensionBlock", @@ -3436,8 +3434,7 @@ test("[for (x of array) for (y of array2) if (x === test) x]", { loc: { start: {line: 1, column: 18}, end: {line: 1, column: 35} - }, - of: true + } } ], body: { @@ -3521,8 +3518,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", { loc: { start: {line: 1, column: 1}, end: {line: 1, column: 17} - }, - of: true + } }, { type: "ComprehensionBlock", @@ -3545,8 +3541,7 @@ test("(for (x of array) for (y of array2) if (x === test) x)", { loc: { start: {line: 1, column: 18}, end: {line: 1, column: 35} - }, - of: true + } } ], body: { @@ -3617,8 +3612,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", { loc: { start: {line: 1, column: 1}, end: {line: 1, column: 20} - }, - of: true + } }, { type: "ComprehensionBlock", @@ -3728,8 +3722,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", { loc: { start: {line: 1, column: 21}, end: {line: 1, column: 65} - }, - of: true + } } ], body: { @@ -3940,7 +3933,7 @@ test("[a, b] = [b, a]", { locations: true }); -test("({ responseText: text } = res)", { +test("({ responseText: text }) = res", { type: "Program", body: [{ type: "ExpressionStatement", @@ -3985,13 +3978,13 @@ test("({ responseText: text } = res)", { type: "Identifier", name: "res", loc: { - start: {line: 1, column: 26}, - end: {line: 1, column: 29} + start: {line: 1, column: 27}, + end: {line: 1, column: 30} } }, loc: { - start: {line: 1, column: 1}, - end: {line: 1, column: 29} + start: {line: 1, column: 0}, + end: {line: 1, column: 30} } }, 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("({ 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}); @@ -13850,9 +13841,9 @@ testFail("let default", "Unexpected token (1:4)", {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}); @@ -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("`test", "Unterminated template (1:0)", {ecmaVersion: 6}); +testFail("`test", "Unterminated template (1:1)", {ecmaVersion: 6}); testFail("switch `test`", "Unexpected token (1:7)", {ecmaVersion: 6}); @@ -14755,3 +14746,97 @@ test("class A { *static() {} }", { ranges: 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 +}); diff --git a/test/tests-jsx.js b/test/tests-jsx.js new file mode 100644 index 0000000000..186a818a9a --- /dev/null +++ b/test/tests-jsx.js @@ -0,0 +1,3466 @@ +// React JSX tests + +var fbTestFixture = { + // Taken and adapted from esprima-fb/fbtest.js. + 'XJS': { + '': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "a", + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + selfClosing: true, + attributes: [], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + closingElement: null, + children: [], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + '': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSNamespacedName', + namespace: { + type: 'XJSIdentifier', + name: 'n', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + name: { + type: 'XJSIdentifier', + name: 'a', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }, + range: [1, 4], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 4 } + } + }, + selfClosing: true, + attributes: [{ + type: 'XJSAttribute', + name: { + type: 'XJSNamespacedName', + namespace: { + type: 'XJSIdentifier', + name: 'n', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + name: { + type: 'XJSIdentifier', + name: 'v', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + value: null, + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }], + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + closingElement: null, + children: [], + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + ' {value} ': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + selfClosing: false, + attributes: [{ + type: 'XJSAttribute', + name: { + type: 'XJSNamespacedName', + namespace: { + type: 'XJSIdentifier', + name: 'n', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }, + name: { + type: 'XJSIdentifier', + name: 'foo', + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + range: [3, 8], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 8 } + } + }, + value: { + type: 'Literal', + value: 'bar', + raw: '"bar"', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + range: [3, 14], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 14 } + } + }], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [38, 39], + loc: { + start: { line: 1, column: 38 }, + end: { line: 1, column: 39 } + } + }, + range: [36, 40], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 40 } + } + }, + children: [{ + type: 'Literal', + value: ' ', + raw: ' ', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, { + type: 'XJSExpressionContainer', + expression: { + type: 'Identifier', + name: 'value', + range: [17, 22], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 22 } + } + }, + range: [16, 23], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 23 } + } + }, { + type: 'Literal', + value: ' ', + raw: ' ', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'b', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + selfClosing: false, + attributes: [], + range: [24, 27], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 27 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'b', + range: [34, 35], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 35 } + } + }, + range: [32, 36], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 36 } + } + }, + children: [{ + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'c', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }, + selfClosing: true, + attributes: [], + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, + closingElement: null, + children: [], + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }], + range: [24, 36], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + } + }, + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + } + }, + '': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "a", + range: [1, 2] + }, + selfClosing: true, + attributes: [ + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "b", + range: [3, 4] + }, + value: { + type: "XJSExpressionContainer", + expression: { + type: "Literal", + value: " ", + raw: "\" \"", + range: [6, 9] + }, + range: [5, 10] + }, + range: [3, 10] + }, + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "c", + range: [11, 12] + }, + value: { + type: "Literal", + value: " ", + raw: "\" \"", + range: [13, 16] + }, + range: [11, 16] + }, + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "d", + range: [17, 18] + }, + value: { + type: "Literal", + value: "&", + raw: "\"&\"", + range: [19, 26] + }, + range: [17, 26] + }, + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "e", + range: [27, 28] + }, + value: { + type: "Literal", + value: "&r;", + raw: "\"&r;\"", + range: [29, 37] + }, + range: [27, 37] + } + ], + range: [0, 40] + }, + closingElement: null, + children: [], + range: [0, 40] + }, + range: [0, 40] + }, + '': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "a", + range: [ + 1, + 2 + ], + loc: { + start: { + line: 1, + column: 1 + }, + end: { + line: 1, + column: 2 + } + } + }, + selfClosing: true, + attributes: [], + range: [ + 0, + 5 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 2, + column: 2 + } + } + }, + closingElement: null, + children: [], + range: [ + 0, + 5 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 2, + column: 2 + } + } + }, + range: [ + 0, + 5 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 2, + column: 2 + } + } + }, + '<日本語>': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "日本語", + range: [ + 1, + 4 + ], + loc: { + start: { + line: 1, + column: 1 + }, + end: { + line: 1, + column: 4 + } + } + }, + selfClosing: false, + attributes: [], + range: [ + 0, + 5 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 5 + } + } + }, + closingElement: { + type: "XJSClosingElement", + name: { + type: "XJSIdentifier", + name: "日本語", + range: [ + 7, + 10 + ], + loc: { + start: { + line: 1, + column: 7 + }, + end: { + line: 1, + column: 10 + } + } + }, + range: [ + 5, + 11 + ], + loc: { + start: { + line: 1, + column: 5 + }, + end: { + line: 1, + column: 11 + } + } + }, + children: [], + range: [ + 0, + 11 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 11 + } + } + }, + range: [ + 0, + 11 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 11 + } + } + }, + + '\nbar\nbaz\n': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "AbC-def", + range: [ + 1, + 8 + ], + loc: { + start: { + line: 1, + column: 1 + }, + end: { + line: 1, + column: 8 + } + } + }, + selfClosing: false, + attributes: [ + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "test", + range: [ + 11, + 15 + ], + loc: { + start: { + line: 2, + column: 2 + }, + end: { + line: 2, + column: 6 + } + } + }, + value: { + type: "Literal", + value: "&&", + raw: "\"&&\"", + range: [ + 16, + 31 + ], + loc: { + start: { + line: 2, + column: 7 + }, + end: { + line: 2, + column: 22 + } + } + }, + range: [ + 11, + 31 + ], + loc: { + start: { + line: 2, + column: 2 + }, + end: { + line: 2, + column: 22 + } + } + } + ], + range: [ + 0, + 32 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 2, + column: 23 + } + } + }, + closingElement: { + type: "XJSClosingElement", + name: { + type: "XJSIdentifier", + name: "AbC-def", + range: [ + 43, + 50 + ], + loc: { + start: { + line: 5, + column: 2 + }, + end: { + line: 5, + column: 9 + } + } + }, + range: [ + 41, + 51 + ], + loc: { + start: { + line: 5, + column: 0 + }, + end: { + line: 5, + column: 10 + } + } + }, + children: [ + { + type: "Literal", + value: "\nbar\nbaz\n", + raw: "\nbar\nbaz\n", + range: [ + 32, + 41 + ], + loc: { + start: { + line: 2, + column: 23 + }, + end: { + line: 5, + column: 0 + } + } + } + ], + range: [ + 0, + 51 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 5, + column: 10 + } + } + }, + range: [ + 0, + 51 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 5, + column: 10 + } + } + }, + + ' : } />': { + type: "ExpressionStatement", + expression: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "a", + range: [ + 1, + 2 + ], + loc: { + start: { + line: 1, + column: 1 + }, + end: { + line: 1, + column: 2 + } + } + }, + selfClosing: true, + attributes: [ + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "b", + range: [ + 3, + 4 + ], + loc: { + start: { + line: 1, + column: 3 + }, + end: { + line: 1, + column: 4 + } + } + }, + value: { + type: "XJSExpressionContainer", + expression: { + type: "ConditionalExpression", + test: { + type: "Identifier", + name: "x", + range: [ + 6, + 7 + ], + loc: { + start: { + line: 1, + column: 6 + }, + end: { + line: 1, + column: 7 + } + } + }, + consequent: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "c", + range: [ + 11, + 12 + ], + loc: { + start: { + line: 1, + column: 11 + }, + end: { + line: 1, + column: 12 + } + } + }, + selfClosing: true, + attributes: [], + range: [ + 10, + 15 + ], + loc: { + start: { + line: 1, + column: 10 + }, + end: { + line: 1, + column: 15 + } + } + }, + closingElement: null, + children: [], + range: [ + 10, + 15 + ], + loc: { + start: { + line: 1, + column: 10 + }, + end: { + line: 1, + column: 15 + } + } + }, + alternate: { + type: "XJSElement", + openingElement: { + type: "XJSOpeningElement", + name: { + type: "XJSIdentifier", + name: "d", + range: [ + 19, + 20 + ], + loc: { + start: { + line: 1, + column: 19 + }, + end: { + line: 1, + column: 20 + } + } + }, + selfClosing: true, + attributes: [], + range: [ + 18, + 23 + ], + loc: { + start: { + line: 1, + column: 18 + }, + end: { + line: 1, + column: 23 + } + } + }, + closingElement: null, + children: [], + range: [ + 18, + 23 + ], + loc: { + start: { + line: 1, + column: 18 + }, + end: { + line: 1, + column: 23 + } + } + }, + range: [ + 6, + 23 + ], + loc: { + start: { + line: 1, + column: 6 + }, + end: { + line: 1, + column: 23 + } + } + }, + range: [ + 5, + 24 + ], + loc: { + start: { + line: 1, + column: 5 + }, + end: { + line: 1, + column: 24 + } + } + }, + range: [ + 3, + 24 + ], + loc: { + start: { + line: 1, + column: 3 + }, + end: { + line: 1, + column: 24 + } + } + } + ], + range: [ + 0, + 27 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 27 + } + } + }, + closingElement: null, + children: [], + range: [ + 0, + 27 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 27 + } + } + }, + range: [ + 0, + 27 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 27 + } + } + }, + + '{}': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + selfClosing: false, + attributes: [], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [5, 9], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 9 } + } + }, + children: [{ + type: 'XJSExpressionContainer', + expression: { + type: 'XJSEmptyExpression', + range: [4, 4], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 4 } + } + }, + range: [3, 5], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 5 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + '{/* this is a comment */}': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + selfClosing: false, + attributes: [], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'a', + range: [30, 31], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 31 } + } + }, + range: [28, 32], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 32 } + } + }, + children: [{ + type: 'XJSExpressionContainer', + expression: { + type: 'XJSEmptyExpression', + range: [4, 27], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 27 } + } + }, + range: [3, 28], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 28 } + } + }], + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + + '
@test content
': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'div', + range: [1, 4], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 4 } + } + }, + selfClosing: false, + attributes: [], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'div', + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }, + range: [18, 24], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 24 } + } + }, + children: [{ + type: 'Literal', + value: '@test content', + raw: '@test content', + range: [5, 18], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + '

7x invalid-js-identifier
': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'div', + range: [ + 1, + 4 + ], + loc: { + start: { + line: 1, + column: 1 + }, + end: { + line: 1, + column: 4 + } + } + }, + selfClosing: false, + attributes: [], + range: [ + 0, + 5 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 5 + } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSIdentifier', + name: 'div', + range: [ + 37, + 40 + ], + loc: { + start: { + line: 1, + column: 37 + }, + end: { + line: 1, + column: 40 + } + } + }, + range: [ + 35, + 41 + ], + loc: { + start: { + line: 1, + column: 35 + }, + end: { + line: 1, + column: 41 + } + } + }, + children: [{ + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'br', + range: [ + 6, + 8 + ], + loc: { + start: { + line: 1, + column: 6 + }, + end: { + line: 1, + column: 8 + } + } + }, + selfClosing: true, + attributes: [], + range: [ + 5, + 11 + ], + loc: { + start: { + line: 1, + column: 5 + }, + end: { + line: 1, + column: 11 + } + } + }, + closingElement: null, + children: [], + range: [ + 5, + 11 + ], + loc: { + start: { + line: 1, + column: 5 + }, + end: { + line: 1, + column: 11 + } + } + }, { + type: 'Literal', + value: '7x invalid-js-identifier', + raw: '7x invalid-js-identifier', + range: [ + 11, + 35 + ], + loc: { + start: { + line: 1, + column: 11 + }, + end: { + line: 1, + column: 35 + } + } + }], + range: [ + 0, + 41 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 41 + } + } + }, + range: [ + 0, + 41 + ], + loc: { + start: { + line: 1, + column: 0 + }, + end: { + line: 1, + column: 41 + } + } + }, + + ' right=monkeys /> gorillas />': { + "type": "ExpressionStatement", + "expression": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "LeftRight", + "range": [ + 1, + 10 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 10 + } + } + }, + "selfClosing": true, + "attributes": [ + { + "type": "XJSAttribute", + "name": { + "type": "XJSIdentifier", + "name": "left", + "range": [ + 11, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + "value": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "a", + "range": [ + 17, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + "selfClosing": true, + "attributes": [], + "range": [ + 16, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 21 + } + } + }, + closingElement: null, + "children": [], + "range": [ + 16, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 21 + } + } + }, + "range": [ + 11, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 21 + } + } + }, + { + "type": "XJSAttribute", + "name": { + "type": "XJSIdentifier", + "name": "right", + "range": [ + 22, + 27 + ], + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 27 + } + } + }, + "value": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "b", + "range": [ + 29, + 30 + ], + "loc": { + "start": { + "line": 1, + "column": 29 + }, + "end": { + "line": 1, + "column": 30 + } + } + }, + "selfClosing": false, + "attributes": [], + "range": [ + 28, + 31 + ], + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 31 + } + } + }, + "closingElement": { + "type": "XJSClosingElement", + "name": { + "type": "XJSIdentifier", + "name": "b", + "range": [ + 52, + 53 + ], + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 53 + } + } + }, + "range": [ + 50, + 54 + ], + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 54 + } + } + }, + "children": [ + { + "type": "Literal", + "value": "monkeys /> gorillas", + "raw": "monkeys /> gorillas", + "range": [ + 31, + 50 + ], + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 50 + } + } + } + ], + "range": [ + 28, + 54 + ], + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 54 + } + } + }, + "range": [ + 22, + 54 + ], + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 54 + } + } + } + ], + "range": [ + 0, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + } + }, + closingElement: null, + "children": [], + "range": [ + 0, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + } + }, + "range": [ + 0, + 57 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 57 + } + } + }, + + '': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSMemberExpression', + object: { + type: 'XJSIdentifier', + name: 'a', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'b', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }, + range: [1, 4], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 4 } + } + }, + selfClosing: false, + attributes: [], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSMemberExpression', + object: { + type: 'XJSIdentifier', + name: 'a', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'b', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + range: [7, 10], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 10 } + } + }, + range: [5, 11], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 11 } + } + }, + children: [], + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + '': { + type: 'ExpressionStatement', + expression: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSMemberExpression', + object: { + type: 'XJSMemberExpression', + object: { + type: 'XJSIdentifier', + name: 'a', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'b', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }, + range: [1, 4], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 4 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'c', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [1, 6], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 6 } + } + }, + selfClosing: false, + attributes: [], + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + closingElement: { + type: 'XJSClosingElement', + name: { + type: 'XJSMemberExpression', + object: { + type: 'XJSMemberExpression', + object: { + type: 'XJSIdentifier', + name: 'a', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'b', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'XJSIdentifier', + name: 'c', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + range: [7, 15], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 15 } + } + }, + children: [], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + // In order to more useful parse errors, we disallow following an + // XJSElement by a less-than symbol. In the rare case that the binary + // operator was intended, the tag can be wrapped in parentheses: + '(
) < x;': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'XJSElement', + openingElement: { + type: 'XJSOpeningElement', + name: { + type: 'XJSIdentifier', + name: 'div', + range: [2, 5], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 5 } + } + }, + selfClosing: true, + attributes: [], + range: [1, 8], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 8 } + } + }, + closingElement: null, + children: [], + range: [1, 8], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 8 } + } + }, + right: { + type: 'Identifier', + name: 'x', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '
': { + "type": "ExpressionStatement", + "expression": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "div", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + } + }, + "selfClosing": true, + "attributes": [ + { + "type": "XJSSpreadAttribute", + "argument": { + "type": "Identifier", + "name": "props", + "range": [ + 9, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 14 + } + } + }, + "range": [ + 5, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 15 + } + } + } + ], + "range": [ + 0, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + closingElement: null, + "children": [], + "range": [ + 0, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + "range": [ + 0, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + + '
': { + "type": "ExpressionStatement", + "expression": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "div", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + } + }, + "selfClosing": true, + "attributes": [ + { + "type": "XJSSpreadAttribute", + "argument": { + "type": "Identifier", + "name": "props", + "range": [ + 9, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 14 + } + } + }, + "range": [ + 5, + 15 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 15 + } + } + }, + { + "type": "XJSAttribute", + "name": { + "type": "XJSIdentifier", + "name": "post", + "range": [ + 16, + 20 + ], + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 20 + } + } + }, + "value": { + "type": "Literal", + "value": "attribute", + "raw": "\"attribute\"", + "range": [ + 21, + 32 + ], + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 32 + } + } + }, + "range": [ + 16, + 32 + ], + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 32 + } + } + } + ], + "range": [ + 0, + 35 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 35 + } + } + }, + closingElement: null, + "children": [], + "range": [ + 0, + 35 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 35 + } + } + }, + "range": [ + 0, + 35 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 35 + } + } + }, + + '
': { + "type": "ExpressionStatement", + "expression": { + "type": "XJSElement", + "openingElement": { + "type": "XJSOpeningElement", + "name": { + "type": "XJSIdentifier", + "name": "div", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + } + }, + "selfClosing": false, + "attributes": [ + { + "type": "XJSAttribute", + "name": { + "type": "XJSIdentifier", + "name": "pre", + "range": [ + 5, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + "value": { + "type": "Literal", + "value": "leading", + "raw": "\"leading\"", + "range": [ + 9, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + "range": [ + 5, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + { + "type": "XJSAttribute", + "name": { + "type": "XJSIdentifier", + "name": "pre2", + "range": [ + 19, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "value": { + "type": "Literal", + "value": "attribute", + "raw": "\"attribute\"", + "range": [ + 24, + 35 + ], + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 35 + } + } + }, + "range": [ + 19, + 35 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 35 + } + } + }, + { + "type": "XJSSpreadAttribute", + "argument": { + "type": "Identifier", + "name": "props", + "range": [ + 40, + 45 + ], + "loc": { + "start": { + "line": 1, + "column": 40 + }, + "end": { + "line": 1, + "column": 45 + } + } + }, + "range": [ + 36, + 46 + ], + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 46 + } + } + } + ], + "range": [ + 0, + 47 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 47 + } + } + }, + "closingElement": { + "type": "XJSClosingElement", + "name": { + "type": "XJSIdentifier", + "name": "div", + "range": [ + 49, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 52 + } + } + }, + "range": [ + 47, + 53 + ], + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 53 + } + } + }, + "children": [], + "range": [ + 0, + 53 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + } + }, + "range": [ + 0, + 53 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + } + }, + '
{aa.b}
': { + "type": "ExpressionStatement", + "start": 0, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "range": [ + 0, + 52 + ], + "expression": { + "type": "XJSElement", + "start": 0, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "range": [ + 0, + 52 + ], + "openingElement": { + "type": "XJSOpeningElement", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "range": [ + 0, + 31 + ], + "attributes": [ + { + "type": "XJSAttribute", + "start": 3, + "end": 16, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 16 + } + }, + "range": [ + 3, + 16 + ], + "name": { + "type": "XJSIdentifier", + "start": 3, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "range": [ + 3, + 5 + ], + "name": "aa" + }, + "value": { + "type": "XJSExpressionContainer", + "start": 6, + "end": 16, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 16 + } + }, + "range": [ + 6, + 16 + ], + "expression": { + "type": "MemberExpression", + "start": 7, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "range": [ + 7, + 15 + ], + "object": { + "type": "MemberExpression", + "start": 7, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "range": [ + 7, + 12 + ], + "object": { + "type": "Identifier", + "start": 7, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "range": [ + 7, + 9 + ], + "name": "aa" + }, + "property": { + "type": "Identifier", + "start": 10, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "range": [ + 10, + 12 + ], + "name": "bb" + }, + "computed": false + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "range": [ + 13, + 15 + ], + "name": "cc" + }, + "computed": false + } + } + }, + { + "type": "XJSAttribute", + "start": 17, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 30 + } + }, + "range": [ + 17, + 30 + ], + "name": { + "type": "XJSIdentifier", + "start": 17, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "range": [ + 17, + 19 + ], + "name": "bb" + }, + "value": { + "type": "XJSExpressionContainer", + "start": 20, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 30 + } + }, + "range": [ + 20, + 30 + ], + "expression": { + "type": "MemberExpression", + "start": 21, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "range": [ + 21, + 29 + ], + "object": { + "type": "MemberExpression", + "start": 21, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "range": [ + 21, + 26 + ], + "object": { + "type": "Identifier", + "start": 21, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "range": [ + 21, + 23 + ], + "name": "bb" + }, + "property": { + "type": "Identifier", + "start": 24, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "range": [ + 24, + 26 + ], + "name": "cc" + }, + "computed": false + }, + "property": { + "type": "Identifier", + "start": 27, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 27 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "range": [ + 27, + 29 + ], + "name": "dd" + }, + "computed": false + } + } + } + ], + "name": { + "type": "XJSIdentifier", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "range": [ + 1, + 2 + ], + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "XJSClosingElement", + "start": 48, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "range": [ + 48, + 52 + ], + "name": { + "type": "XJSIdentifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "range": [ + 50, + 51 + ], + "name": "A" + } + }, + "children": [ + { + "type": "XJSElement", + "start": 31, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 48 + } + }, + "range": [ + 31, + 48 + ], + "openingElement": { + "type": "XJSOpeningElement", + "start": 31, + "end": 36, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 36 + } + }, + "range": [ + 31, + 36 + ], + "attributes": [], + "name": { + "type": "XJSIdentifier", + "start": 32, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "range": [ + 32, + 35 + ], + "name": "div" + }, + "selfClosing": false + }, + "closingElement": { + "type": "XJSClosingElement", + "start": 42, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 48 + } + }, + "range": [ + 42, + 48 + ], + "name": { + "type": "XJSIdentifier", + "start": 44, + "end": 47, + "loc": { + "start": { + "line": 1, + "column": 44 + }, + "end": { + "line": 1, + "column": 47 + } + }, + "range": [ + 44, + 47 + ], + "name": "div" + } + }, + "children": [ + { + "type": "XJSExpressionContainer", + "start": 36, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "range": [ + 36, + 42 + ], + "expression": { + "type": "MemberExpression", + "start": 37, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "range": [ + 37, + 41 + ], + "object": { + "type": "Identifier", + "start": 37, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 39 + } + }, + "range": [ + 37, + 39 + ], + "name": "aa" + }, + "property": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 40 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "range": [ + 40, + 41 + ], + "name": "b" + }, + "computed": false + } + } + ] + } + ] + } + } + }, + 'Regression': { + '

foo bar baz

;': { + type: "ExpressionStatement", + start: 0, + end: 40, + expression: { + type: "XJSElement", + start: 0, + end: 38, + openingElement: { + type: "XJSOpeningElement", + start: 0, + end: 3, + attributes: [], + name: { + type: "XJSIdentifier", + start: 1, + end: 2, + name: "p" + }, + selfClosing: false + }, + closingElement: { + type: "XJSClosingElement", + start: 34, + end: 38, + name: { + type: "XJSIdentifier", + start: 36, + end: 37, + name: "p" + } + }, + children: [ + { + type: "Literal", + start: 3, + end: 7, + value: "foo ", + raw: "foo " + }, + { + type: "XJSElement", + start: 7, + end: 30, + openingElement: { + type: "XJSOpeningElement", + start: 7, + end: 22, + attributes: [{ + type: "XJSAttribute", + start: 10, + end: 21, + name: { + type: "XJSIdentifier", + start: 10, + end: 14, + name: "href" + }, + value: { + type: "Literal", + start: 15, + end: 21, + value: "test", + raw: "\"test\"" + } + }], + name: { + type: "XJSIdentifier", + start: 8, + end: 9, + name: "a" + }, + selfClosing: false + }, + closingElement: { + type: "XJSClosingElement", + start: 26, + end: 30, + name: { + type: "XJSIdentifier", + start: 28, + end: 29, + name: "a" + } + }, + children: [{ + type: "Literal", + start: 22, + end: 26, + value: " bar", + raw: " bar" + }] + }, + { + type: "Literal", + start: 30, + end: 34, + value: " baz", + raw: " baz" + } + ] + } + }, + + '
{
}
': { + type: 'ExpressionStatement', + start: 0, + end: 30, + expression: { + type: 'XJSElement', + start: 0, + end: 30, + openingElement: { + type: 'XJSOpeningElement', + start: 0, + end: 5, + attributes: [], + name: { + type: 'XJSIdentifier', + start: 1, + end: 4, + name: 'div' + }, + selfClosing: false + }, + closingElement: { + type: 'XJSClosingElement', + start: 24, + end: 30, + name: { + type: 'XJSIdentifier', + start: 26, + end: 29, + name: 'div' + } + }, + children: [{ + type: 'XJSExpressionContainer', + start: 5, + end: 24, + expression: { + type: 'XJSElement', + start: 6, + end: 23, + openingElement: { + type: 'XJSOpeningElement', + start: 6, + end: 23, + attributes: [ + { + type: 'XJSSpreadAttribute', + start: 11, + end: 20, + argument: { + type: 'Identifier', + start: 15, + end: 19, + name: 'test' + } + } + ], + name: { + type: 'XJSIdentifier', + start: 7, + end: 10, + name: 'div' + }, + selfClosing: true + }, + closingElement: null, + children: [] + } + }] + } + }, + + '
{ {a} }
': { + type: "ExpressionStatement", + start: 0, + end: 18, + expression: { + type: "XJSElement", + start: 0, + end: 18, + openingElement: { + type: "XJSOpeningElement", + start: 0, + end: 5, + attributes: [], + name: { + type: "XJSIdentifier", + start: 1, + end: 4, + name: "div" + }, + selfClosing: false + }, + closingElement: { + type: "XJSClosingElement", + start: 12, + end: 18, + name: { + type: "XJSIdentifier", + start: 14, + end: 17, + name: "div" + } + }, + children: [{ + type: "XJSExpressionContainer", + start: 5, + end: 12, + expression: { + type: "ObjectExpression", + start: 7, + end: 10, + properties: [{ + type: "Property", + start: 8, + end: 9, + method: false, + shorthand: true, + computed: false, + key: { + type: "Identifier", + start: 8, + end: 9, + name: "a" + }, + kind: "init", + value: { + type: "Identifier", + start: 8, + end: 9, + name: "a" + } + }] + } + }] + } + }, + + '
/text
': { + type: "ExpressionStatement", + start: 0, + end: 16, + expression: { + type: "XJSElement", + start: 0, + end: 16, + openingElement: { + type: "XJSOpeningElement", + start: 0, + end: 5, + attributes: [], + name: { + type: "XJSIdentifier", + start: 1, + end: 4, + name: "div" + }, + selfClosing: false + }, + closingElement: { + type: "XJSClosingElement", + start: 10, + end: 16, + name: { + type: "XJSIdentifier", + start: 12, + end: 15, + name: "div" + } + }, + children: [{ + type: "Literal", + start: 5, + end: 10, + value: "/text", + raw: "/text" + }] + } + } + } +}; + +if (typeof exports !== "undefined") { + var test = require("./driver.js").test; +} + +for (var ns in fbTestFixture) { + ns = fbTestFixture[ns]; + for (var code in ns) { + test(code, { + type: 'Program', + body: [ns[code]] + }, { + ecmaVersion: 6, + locations: true, + ranges: true, + loose: false + }); + } +} diff --git a/test/tests.js b/test/tests.js index 1037330068..172eb1fb87 100644 --- a/test/tests.js +++ b/test/tests.js @@ -403,7 +403,7 @@ test("(1 + 2 ) * 3", { preserveParens: true }); -testFail("(x) = 23", "Assigning to rvalue (1:4)"); +testFail("(x) = 23", "Assigning to rvalue (1:0)", { preserveParens: true }); test("x = []", { type: "Program", @@ -26883,7 +26883,7 @@ testFail("func() = 4", "Assigning to rvalue (1:0)"); testFail("(1 + 1) = 10", - "Assigning to rvalue (1:8)"); + "Assigning to rvalue (1:1)"); testFail("1++", "Assigning to rvalue (1:0)");