diff --git a/acorn.js b/acorn.js index c006844621..0911800bd7 100644 --- a/acorn.js +++ b/acorn.js @@ -481,7 +481,8 @@ name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string, paamayimNekudotayim: _paamayimNekudotayim, exponent: _exponent, hash: _hash, arrow: _arrow, template: _template, star: _star, assign: _assign, - backQuote: _backQuote, dollarBraceL: _dollarBraceL}; + backQuote: _backQuote, dollarBraceL: _dollarBraceL, jsxName: _jsxName, + jsxText: _jsxText, jsxTagStart: _jsxTagStart, jsxTagEnd: _jsxTagEnd}; for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw]; // This is a trick taken from Esprima. It turns out that, on @@ -1274,7 +1275,7 @@ out += readJSXEntity(); chunkStart = tokPos; } else { - if (isNewLine(ch)) raise(tokStart, "Unterminated string constant"); + if (isNewLine(ch) && !isJSX) raise(tokStart, "Unterminated string constant"); ++tokPos; } } @@ -1619,35 +1620,43 @@ // Reads inline JSX contents token. function readJSXToken() { - var out = "", start = tokPos; + var out = "", chunkStart = tokPos; for (;;) { if (tokPos >= inputLen) raise(tokStart, "Unterminated JSX contents"); var ch = input.charCodeAt(tokPos); switch (ch) { case 123: // '{' case 60: // '<' - if (tokPos === start) { + if (tokPos === tokStart) { return getTokenFromCode(ch); } + out += input.slice(chunkStart, tokPos); return finishToken(_jsxText, out); case 38: // '&' + out += input.slice(chunkStart, tokPos); out += readJSXEntity(); + chunkStart = tokPos; break; default: - ++tokPos; if (isNewLine(ch)) { + out += input.slice(chunkStart, tokPos); + ++tokPos; if (ch === 13 && input.charCodeAt(tokPos) === 10) { ++tokPos; - ch = 10; + out += "\n"; + } else { + out += String.fromCharCode(ch); } if (options.locations) { ++tokCurLine; tokLineStart = tokPos; } + chunkStart = tokPos; + } else { + ++tokPos; } - out += String.fromCharCode(ch); } } } diff --git a/test/tests-jsx.js b/test/tests-jsx.js index e5d2999703..c9cfa5af55 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -3587,6 +3587,42 @@ var fbTestFixture = { closingElement: null, children: [] } + }, + '': { + type: "ExpressionStatement", + expression: { + type: "JSXElement", + range: [0, 64], + openingElement: { + type: "JSXOpeningElement", + range: [0, 64], + attributes: [ + { + type: "JSXAttribute", + range: [6, 62], + name: { + type: "JSXIdentifier", + range: [6, 7], + name: "d" + }, + value: { + type: "Literal", + range: [8, 62], + value: "M230 80\n\t\tA 45 45, 0, 1, 0, 275 125 \r\n L 275 80 Z", + raw: "\"M230 80\n\t\tA 45 45, 0, 1, 0, 275 125 \r\n L 275 80 Z\"" + } + } + ], + name: { + type: "JSXIdentifier", + range: [1, 5], + name: "path" + }, + selfClosing: true + }, + closingElement: null, + children: [] + } } } }; @@ -3604,8 +3640,7 @@ for (var ns in fbTestFixture) { }, { ecmaVersion: 6, locations: true, - ranges: true, - loose: false + ranges: true }); } }