[Pkg-javascript-commits] [node-acorn-jsx] 436/484: Add JSX support to loose parser.
Bastien Roucariès
rouca at moszumanska.debian.org
Sat Aug 19 14:21:07 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-acorn-jsx.
commit e0bcfca03f8b044de2f23306c18f431d3d578c9a
Author: Ingvar Stepanyan <me at rreverser.com>
Date: Tue Jan 27 18:25:49 2015 +0200
Add JSX support to loose parser.
---
acorn.js | 10 +---
acorn_loose.js | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
test/tests-jsx.js | 3 +-
3 files changed, 175 insertions(+), 13 deletions(-)
diff --git a/acorn.js b/acorn.js
index 2447814..3cc5fa0 100644
--- a/acorn.js
+++ b/acorn.js
@@ -463,7 +463,8 @@
dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
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
@@ -3321,9 +3322,6 @@
return node;
case _jsxTagStart:
- return parseJSXElement();
-
- case _jsxText:
case _string:
return parseExprAtom();
@@ -3337,10 +3335,6 @@
// at the beginning of the next one (right brace).
function parseJSXEmptyExpression() {
- if (tokType !== _braceR) {
- unexpected();
- }
-
var tmp;
tmp = tokStart;
diff --git a/acorn_loose.js b/acorn_loose.js
index 0f52fcc..fa7631b 100644
--- a/acorn_loose.js
+++ b/acorn_loose.js
@@ -256,11 +256,27 @@
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 emptyNode(type) {
+ var dummy = startNodeAt(options.locations ? [lastEnd, lastEndLoc] : lastEnd);
+ dummy.name = "✖";
+ return finishNodeAt(dummy, type, storeCurrentPos());
+ }
+
function dummyIdent() {
- var dummy = startNode();
+ var dummy = emptyNode("Identifier");
dummy.name = "✖";
- return finishNode(dummy, "Identifier");
+ return dummy;
}
+
function isDummy(node) { return node.name == "✖"; }
function eat(type) {
@@ -724,7 +740,7 @@
next();
return finishNode(node, "Literal");
- case tt.num: case tt.string:
+ case tt.num: case tt.string: case tt.jsxText:
var node = startNode();
node.value = token.value;
node.raw = input.slice(token.start, token.end);
@@ -788,6 +804,9 @@
case tt.backQuote:
return parseTemplate();
+ case tt.jsxTagStart:
+ return parseJSXElement();
+
default:
return dummyIdent();
}
@@ -1161,4 +1180,154 @@
}
return elts;
}
+
+ // Parse next token as JSX identifier
+
+ function parseJSXIdentifier() {
+ var node = startNode();
+ node.name = token.type === tt.jsxName ? token.value : token.type.keyword;
+ next();
+ return finishNode(node, "JSXIdentifier");
+ }
+
+ // Parse namespaced identifier.
+
+ function parseJSXNamespacedName() {
+ var start = storeCurrentPos();
+ var name = parseJSXIdentifier();
+ if (!eat(tt.colon)) return name;
+ var node = startNodeAt(start);
+ node.namespace = name;
+ node.name = parseJSXIdentifier();
+ return finishNode(node, "JSXNamespacedName");
+ }
+
+ // Parses element name in any form - namespaced, member
+ // or single identifier.
+
+ function parseJSXElementName() {
+ var start = storeCurrentPos();
+ var node = parseJSXNamespacedName();
+ while (eat(tt.dot)) {
+ var newNode = startNodeAt(start);
+ newNode.object = node;
+ newNode.property = parseJSXIdentifier();
+ node = finishNode(newNode, "JSXMemberExpression");
+ }
+ return node;
+ }
+
+ // Parses any type of JSX attribute value.
+
+ function parseJSXAttributeValue() {
+ return token.type === tt.braceL ? parseJSXExpressionContainer() : parseExprAtom();
+ }
+
+ // Parses JSX expression enclosed into curly brackets.
+
+ function parseJSXExpressionContainer(allowEmpty) {
+ var node = startNode();
+ pushCx();
+ next();
+ node.expression = allowEmpty && token.type === tt.braceR ? emptyNode("JSXEmptyExpression") : parseExpression();
+ popCx();
+ expect(tt.braceR);
+ return finishNode(node, "JSXExpressionContainer");
+ }
+
+ // Parses following JSX attribute name-value pair.
+
+ function parseJSXAttribute() {
+ var node = startNode();
+ if (token.type === tt.braceL) {
+ if (lookAhead(1).type === tt.ellipsis) {
+ next();
+ next();
+ node.argument = parseMaybeAssign();
+ expect(tt.braceR);
+ return finishNode(node, "JSXSpreadAttribute");
+ } else {
+ node.name = dummyIdent();
+ node.value = parseJSXAttributeValue();
+ }
+ } else {
+ node.name = parseJSXNamespacedName();
+ node.value = eat(tt.eq) ? parseJSXAttributeValue() : null;
+ }
+ return finishNode(node, "JSXAttribute");
+ }
+
+ // Parses JSX opening tag starting after '<'.
+
+ function parseJSXOpeningElementAt(start) {
+ var node = startNodeAt(start);
+ node.attributes = [];
+ node.name = parseJSXElementName();
+ while (token.type !== tt.slash && token.type !== tt.jsxTagEnd && token.type !== tt.eof) {
+ node.attributes.push(parseJSXAttribute());
+ }
+ node.selfClosing = eat(tt.slash);
+ expect(tt.jsxTagEnd);
+ if (token.type === tt.eof) node.selfClosing = true;
+ return finishNode(node, "JSXOpeningElement");
+ }
+
+ // Parses JSX closing tag starting after '</'.
+
+ function parseJSXClosingElementAt(start) {
+ var node = startNodeAt(start);
+ node.name = parseJSXElementName();
+ expect(tt.jsxTagEnd);
+ return finishNode(node, "JSXClosingElement");
+ }
+
+ // Parses entire JSX element, including it's opening tag
+ // (starting after '<'), attributes, contents and closing tag.
+
+ function parseJSXElementAt(start) {
+ var node = startNodeAt(start);
+ var children = [];
+ var openingElement = parseJSXOpeningElementAt(start);
+ var closingElement = null;
+
+ if (!openingElement.selfClosing) {
+ contents:for (;;) {
+ switch (token.type) {
+ case tt.jsxTagStart:
+ start = storeCurrentPos();
+ next();
+ if (eat(tt.slash)) {
+ closingElement = parseJSXClosingElementAt(start);
+ break contents;
+ }
+ children.push(parseJSXElementAt(start));
+ break;
+
+ case tt.braceL:
+ children.push(parseJSXExpressionContainer(true));
+ break;
+
+ case tt.eof:
+ break contents;
+
+ default:
+ children.push(parseExprAtom());
+ break;
+ }
+ }
+ }
+
+ node.openingElement = openingElement;
+ node.closingElement = closingElement;
+ node.children = children;
+ return finishNode(node, "JSXElement");
+ }
+
+ // Parses entire JSX element from current position.
+
+ function parseJSXElement() {
+ var start = storeCurrentPos();
+ next();
+ return parseJSXElementAt(start);
+ }
});
diff --git a/test/tests-jsx.js b/test/tests-jsx.js
index e5d2999..a7dd79e 100644
--- a/test/tests-jsx.js
+++ b/test/tests-jsx.js
@@ -3604,8 +3604,7 @@ for (var ns in fbTestFixture) {
}, {
ecmaVersion: 6,
locations: true,
- ranges: true,
- loose: false
+ ranges: true
});
}
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-acorn-jsx.git
More information about the Pkg-javascript-commits
mailing list