diff --git a/vendor/fbtransform/transforms/__tests__/react-test.js b/vendor/fbtransform/transforms/__tests__/react-test.js
index 44b7b3b76a5..d35a47d63bd 100644
--- a/vendor/fbtransform/transforms/__tests__/react-test.js
+++ b/vendor/fbtransform/transforms/__tests__/react-test.js
@@ -324,6 +324,19 @@ describe('react jsx', function() {
expect(transform(code).code).toBe(result);
});
+ it('handles overparenthesized JS', function() {
+ var code =
+ 'Foo {(e+f //A line comment\n' +
+ '/* A multiline comment */)\n' +
+ '} bar\n' +
+ '';
+ var result = 'React.createElement("foo", {a: (b), c: (d)}, "Foo ", (e+f //A line comment\n' +
+ '/* A multiline comment */), \n' +
+ '" bar"\n' +
+ ')';
+ expect(transform(code).code).toBe(result);
+ });
+
it('should transform known hyphenated tags', function() {
var code = ';';
var result = 'React.createElement("font-face", null);';
diff --git a/vendor/fbtransform/transforms/jsx.js b/vendor/fbtransform/transforms/jsx.js
index 428d80a37ba..b1a1037bbd6 100644
--- a/vendor/fbtransform/transforms/jsx.js
+++ b/vendor/fbtransform/transforms/jsx.js
@@ -11,6 +11,33 @@
var Syntax = require('jstransform').Syntax;
var utils = require('jstransform/src/utils');
+function commaAfterLastParen(value) {
+ var state = 'normal';
+ var commaPos = 0;
+ for (var i = 0; i < value.length; ++i) {
+ if (state === 'normal') {
+ if (value.substr(i, 2) === '//') {
+ state = 'singleline';
+ i += 1;
+ } else if (value.substr(i, 2) === '/*') {
+ state = 'multiline';
+ i += 1;
+ } else if (value.charAt(i).trim() !== '') {
+ commaPos = i + 1;
+ }
+ } else if (state === 'singleline' && value.charAt(i) === '\n') {
+ state = 'normal';
+ } else if (state === 'multiline' &&
+ value.charAt(i) === '*' &&
+ i + 1 < value.length &&
+ value.charAt(i + 1) === '/') {
+ i += 1;
+ state = 'normal';
+ }
+ }
+ return value.substring(0, commaPos) + ', ' + trimLeft(value.substring(commaPos));
+}
+
function renderJSXLiteral(object, isLast, state, start, end) {
var lines = object.value.split(/\r\n|\n|\r/);
@@ -84,11 +111,11 @@ function renderJSXExpressionContainer(traverse, object, isLast, path, state) {
if (!isLast && object.expression.type !== Syntax.JSXEmptyExpression) {
// If we need to append a comma, make sure to do so after the expression.
utils.catchup(object.expression.range[1], state, trimLeft);
- utils.append(', ', state);
+ utils.catchup(object.range[1] - 1, state, commaAfterLastParen);
+ } else {
+ // Minus 1 to skip `}`.
+ utils.catchup(object.range[1] - 1, state, trimLeft);
}
-
- // Minus 1 to skip `}`.
- utils.catchup(object.range[1] - 1, state, trimLeft);
utils.move(object.range[1], state);
return false;
}