Repository: flex-falcon Updated Branches: refs/heads/develop 80eb23610 -> 13b29e17d
LiteralEmitter: fixed incorrectly trimmed whitespace and missing commas with JSX and brace syntax Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/13b29e17 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/13b29e17 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/13b29e17 Branch: refs/heads/develop Commit: 13b29e17dbda3f4ac20c050d1c0b957012e93261 Parents: 80eb236 Author: Josh Tynjala <joshtynj...@gmail.com> Authored: Sat Oct 15 11:41:14 2016 -0700 Committer: Josh Tynjala <joshtynj...@gmail.com> Committed: Sat Oct 15 11:41:14 2016 -0700 ---------------------------------------------------------------------- .../internal/codegen/js/jx/LiteralEmitter.java | 37 +++++++++++++---- .../codegen/js/flexjs/TestFlexJSJSX.java | 42 +++++++++++++++++++- 2 files changed, 70 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/13b29e17/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java index 47f0c8d..176eb35 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java @@ -115,9 +115,9 @@ public class LiteralEmitter extends JSSubEmitter implements if (inAttribute) { sb.append("'\"' + "); - + sb.append(s); - + sb.append(" + '\"'"); } else @@ -187,6 +187,7 @@ public class LiteralEmitter extends JSSubEmitter implements Stack<String> elementStack = new Stack<String>(); String elementName = null; boolean endsWithAttribute = false; + boolean afterOpenTag = false; for (int i = 0; i < childCount; i++) { IASNode child = node.getContentsNode().getChild(i); @@ -196,12 +197,21 @@ public class LiteralEmitter extends JSSubEmitter implements if (literalChild.getLiteralType() != LiteralType.XML) { //inside {} syntax. emit normally. + if (afterOpenTag) + { + writeToken(ASEmitterTokens.COMMA); + } getEmitter().getWalker().walk(literalChild); continue; } String value = literalChild.getValue(true); value = value.replaceAll(ASEmitterTokens.NEW_LINE.getToken(), ""); - value = value.trim(); + if (!afterOpenTag) + { + //trim the starting whitespace, unless we're inside an open + //and close tag where we want to preserve whitespace + value = value.replaceAll("^\\s+", ""); + } while (value.length() > 0) { int nextTagStartIndex = value.indexOf("<"); @@ -254,7 +264,7 @@ public class LiteralEmitter extends JSSubEmitter implements String topOfStack = elementStack.pop(); assert topOfStack.equals(elementName); value = value.substring(nextTagEndIndex + 1); - value = value.trim(); + value = value.replaceAll("^\\s+", ""); continue; } else @@ -271,14 +281,20 @@ public class LiteralEmitter extends JSSubEmitter implements write(ASEmitterTokens.PAREN_OPEN); write(elementName); value = value.substring(endNameIndex); - value = value.trim(); + value = value.replaceAll("^\\s+", ""); //we changed the string, so find it again nextTagEndIndex = value.indexOf(">"); + afterOpenTag = false; } } else { //we're inside an element's open and closing tags + if (nextTagStartIndex == -1) + { + //literal ends with an attribute that uses {} syntax + nextTagStartIndex = value.length(); + } String elementText = value.substring(0, nextTagStartIndex); writeToken(ASEmitterTokens.COMMA); emitJSXText(elementText); @@ -307,12 +323,17 @@ public class LiteralEmitter extends JSSubEmitter implements assert topOfStack.equals(elementName); } value = value.substring(nextTagEndIndex + 1); - value = value.trim(); + if (!endsWithAttribute) + { + //don't trim here because we want to preserve whitespace + //inside the open and close tags + afterOpenTag = true; + } } } else { - if (!endsWithAttribute) + if (!endsWithAttribute || afterOpenTag) { writeToken(ASEmitterTokens.COMMA); } @@ -374,7 +395,7 @@ public class LiteralEmitter extends JSSubEmitter implements String attributeValue = value.substring(startAttributeValueIndex, endAttributeValueIndex); emitJSXText(attributeValue); value = value.substring(endAttributeValueIndex + 1); - value = value.trim(); + value = value.replaceAll("^\\s+", ""); } } if (!endsWithAttribute) http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/13b29e17/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSJSX.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSJSX.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSJSX.java index a3c1c07..00933ae 100644 --- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSJSX.java +++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSJSX.java @@ -109,7 +109,7 @@ public class TestFlexJSJSX extends ASTestBase } @Test - public void testSelfClosingHTMLTagWithCurlyAttribute() + public void testSelfClosingHTMLTagWithAttributeContainingLiteral() { IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id={2}/>}"); asBlockWalker.visitFunction(node); @@ -117,6 +117,14 @@ public class TestFlexJSJSX extends ASTestBase } @Test + public void testSelfClosingHTMLTagWithAttributeContainingExpression() + { + IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id={2 + 2}/>}"); + asBlockWalker.visitFunction(node); + assertOut("FalconTest_A.prototype.foo = function() {\n return React.createElement('div', { id: 2 + 2 });\n}"); + } + + @Test public void testSimpleOpenAndCloseHTMLTag() { IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div></div>}"); @@ -133,6 +141,38 @@ public class TestFlexJSJSX extends ASTestBase } @Test + public void testOpenAndCloseHTMLTagWithChildBracesContainingLiteral() + { + IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2}</div>}"); + asBlockWalker.visitFunction(node); + assertOut("FalconTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2);\n}"); + } + + @Test + public void testOpenAndCloseHTMLTagWithChildBracesContainingExpression() + { + IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2 + 2}</div>}"); + asBlockWalker.visitFunction(node); + assertOut("FalconTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2 + 2);\n}"); + } + + @Test + public void testOpenAndCloseHTMLTagWithChildTextAndBraces() + { + IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>Foo {2}</div>}"); + asBlockWalker.visitFunction(node); + assertOut("FalconTest_A.prototype.foo = function() {\n return React.createElement('div', null, 'Foo ', 2);\n}"); + } + + @Test + public void testOpenAndCloseHTMLTagWithChildBracesAndText() + { + IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div>{2} Foo</div>}"); + asBlockWalker.visitFunction(node); + assertOut("FalconTest_A.prototype.foo = function() {\n return React.createElement('div', null, 2, ' Foo');\n}"); + } + + @Test public void testOpenAndCloseHTMLTagWithAttribute() { IFunctionNode node = getMethod("[JSX]\nfunction foo() {return <div id=\"foo\"></div>}");