You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by er...@apache.org on 2013/01/08 16:05:32 UTC
svn commit: r1430315 - in /flex/whiteboard/mschmalle/falconjx:
compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/
compiler.jx/src/org/apache/flex/compiler/as/codegen/
compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ c...
Author: erikdebruin
Date: Tue Jan 8 15:05:32 2013
New Revision: 1430315
URL: http://svn.apache.org/viewvc?rev=1430315&view=rev
Log:
- refactored a bit to give control over 'binary operator' handling to the emitter instead of the walker
- moved 'emitVarDeclaration' and 'emitFunctionObject' overrides to JSEmitter
- created 'emitBinaryOperator' on JSGoogEmitter to handle the various 'goog' specific workarounds
- created TestGoogExpressions and made overrides for JS (and/or 'goog') specific implementations
Added:
flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java (with props)
Modified:
flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java
flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java
flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/JSEmitter.java
flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
Added: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java?rev=1430315&view=auto
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java (added)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java Tue Jan 8 15:05:32 2013
@@ -0,0 +1,163 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.js.codegen.goog;
+
+import org.apache.flex.compiler.clients.IBackend;
+import org.apache.flex.compiler.internal.as.codegen.TestExpressions;
+import org.apache.flex.compiler.internal.js.driver.goog.GoogBackend;
+import org.apache.flex.compiler.internal.tree.as.NamespaceAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class TestGoogExpressions extends TestExpressions
+{
+
+ //----------------------------------
+ // Primary expression keywords
+ //----------------------------------
+
+ //----------------------------------
+ // Logical
+ //----------------------------------
+
+ @Override
+ @Test
+ public void testVisitBinaryOperatorNode_LogicalAndAssignment()
+ {
+ IBinaryOperatorNode node = getBinaryNode("a &&= b");
+ visitor.visitBinaryOperator(node);
+ assertOut("a = a && b");
+ }
+
+ @Override
+ @Test
+ public void testVisitBinaryOperatorNode_LogicalOrAssignment()
+ {
+ IBinaryOperatorNode node = getBinaryNode("a ||= b");
+ visitor.visitBinaryOperator(node);
+ assertOut("a = a || b");
+ }
+
+ //----------------------------------
+ // Other
+ //----------------------------------
+
+ @Override
+ @Test
+ public void testAnonymousFunction()
+ {
+ IVariableNode node = (IVariableNode) getNode("var a = function(){};",
+ IVariableNode.class);
+ visitor.visitVariable(node);
+ assertOut("var a = function() {\n}");
+ }
+
+ @Override
+ @Test
+ public void testAnonymousFunctionWithParamsReturn()
+ {
+ IVariableNode node = (IVariableNode) getNode(
+ "var a:Object = function(foo:int, bar:String = 'goo'):int{return -1;};",
+ IVariableNode.class);
+ visitor.visitVariable(node);
+ assertOutDebug("var a = function(foo, bar) {\n\tbar = typeof bar !== 'undefined' ? bar : 'goo';\n\treturn -1;\n}");
+ }
+
+ @Override
+ @Test
+ public void testAnonymousFunctionAsArgument()
+ {
+ // TODO (mschmalle) using IIfNode in expressions test, any other way to do this without statement?
+ IIfNode node = (IIfNode) getNode(
+ "if (a) {addListener('foo', function(event:Object):void{doit();});}",
+ IIfNode.class);
+ visitor.visitIf(node);
+ assertOut("if (a) {\n\taddListener('foo', function(event) {\n\t\tdoit();\n\t});\n}");
+ }
+
+ @Override
+ @Test
+ public void testVisitAs()
+ {
+ // TODO (erikdebruin) the assert is a placeholder for the eventual workaround
+ IBinaryOperatorNode node = getBinaryNode("a as b");
+ visitor.visitBinaryOperator(node);
+ assertOut("as(a, b)");
+ }
+
+ @Override
+ @Test
+ public void testVisitBinaryOperator_Instancof()
+ {
+ // TODO (erikdebruin) check if the AS and JS implementations match
+ IBinaryOperatorNode node = getBinaryNode("a instanceof b");
+ visitor.visitBinaryOperator(node);
+ assertOut("a instanceof b");
+ }
+
+ @Override
+ @Test
+ public void testVisitBinaryOperator_Is()
+ {
+ // TODO (erikdebruin) the assert is a placeholder for the eventual workaround
+ IBinaryOperatorNode node = getBinaryNode("a is b");
+ visitor.visitBinaryOperator(node);
+ assertOut("is(a, b)");
+ }
+
+ @Ignore
+ @Override
+ @Test
+ public void testVisitBinaryOperator_NamespaceAccess_1()
+ {
+ // TODO (mschmalle) this needs INamespaceAccessExpressionNode interface
+ // TODO (erikdebruin) JS implementation?
+ NamespaceAccessExpressionNode node = (NamespaceAccessExpressionNode) getExpressionNode(
+ "a::b", NamespaceAccessExpressionNode.class);
+ visitor.visitNamespaceAccessExpression(node);
+ assertOut("a::b");
+ }
+
+ @Ignore
+ @Override
+ @Test
+ public void testVisitBinaryOperator_NamespaceAccess_2()
+ {
+ // TODO (mschmalle) this needs INamespaceAccessExpressionNode interface
+ // TODO (erikdebruin) JS implementation?
+ NamespaceAccessExpressionNode node = (NamespaceAccessExpressionNode) getExpressionNode(
+ "a::b::c", NamespaceAccessExpressionNode.class);
+ visitor.visitNamespaceAccessExpression(node);
+ assertOut("a::b::c");
+ }
+
+ protected IBackend createBackend()
+ {
+ return new GoogBackend();
+ }
+
+}
Propchange: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java?rev=1430315&r1=1430314&r2=1430315&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java Tue Jan 8 15:05:32 2013
@@ -22,6 +22,7 @@ package org.apache.flex.compiler.as.code
import java.io.Writer;
import org.apache.flex.compiler.internal.tree.as.FunctionObjectNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IFunctionNode;
import org.apache.flex.compiler.tree.as.IGetterNode;
@@ -161,4 +162,15 @@ public interface IASEmitter
void emitFunctionBlockHeader(IFunctionNode node);
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ /**
+ * Emit an operator statement.
+ *
+ * @param node The {@link IBinaryOperatorNode} or chain of variable nodes.
+ */
+ void emitBinaryOperator(IBinaryOperatorNode node);
+
}
Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java?rev=1430315&r1=1430314&r2=1430315&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java Tue Jan 8 15:05:32 2013
@@ -1008,12 +1008,8 @@ public class ASBlockWalker implements IA
{
debug("visitBinaryOperator(" + node.getOperator().getOperatorText()
+ ")");
- walk(node.getLeftOperandNode());
- if (node.getNodeID() != ASTNodeID.Op_CommaID)
- emitter.write(" ");
- emitter.write(node.getOperator().getOperatorText());
- emitter.write(" ");
- walk(node.getRightOperandNode());
+
+ emitter.emitBinaryOperator(node);
}
@Override
Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java?rev=1430315&r1=1430314&r2=1430315&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java Tue Jan 8 15:05:32 2013
@@ -38,6 +38,7 @@ import org.apache.flex.compiler.problems
import org.apache.flex.compiler.tree.ASTNodeID;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IAccessorNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
import org.apache.flex.compiler.tree.as.IDefinitionNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IFunctionNode;
@@ -542,7 +543,7 @@ public class ASEmitter implements IASEmi
// TODO (mschmalle) FunctionObjectNode; does this need specific treatment?
emitMethodScope(node);
}
-
+
protected ITypeNode findTypeNode(IPackageNode node)
{
IScopedNode scope = node.getScopedNode();
@@ -569,4 +570,18 @@ public class ASEmitter implements IASEmi
return null;
}
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void emitBinaryOperator(IBinaryOperatorNode node)
+ {
+ getWalker().walk(node.getLeftOperandNode());
+ if (node.getNodeID() != ASTNodeID.Op_CommaID)
+ write(" ");
+ write(node.getOperator().getOperatorText());
+ write(" ");
+ getWalker().walk(node.getRightOperandNode());
+ }
}
Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/JSEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/JSEmitter.java?rev=1430315&r1=1430314&r2=1430315&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/JSEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/JSEmitter.java Tue Jan 8 15:05:32 2013
@@ -23,8 +23,13 @@ import java.io.FilterWriter;
import org.apache.flex.compiler.definitions.ITypeDefinition;
import org.apache.flex.compiler.internal.as.codegen.ASEmitter;
+import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionObjectNode;
import org.apache.flex.compiler.js.codegen.IJSEmitter;
import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IFunctionNode;
import org.apache.flex.compiler.tree.as.IVariableNode;
@@ -62,6 +67,20 @@ public class JSEmitter extends ASEmitter
}
@Override
+ public void emitFunctionObject(IExpressionNode node)
+ {
+ FunctionObjectNode f = (FunctionObjectNode) node;
+
+ FunctionNode fnode = f.getFunctionNode();
+
+ write("function");
+
+ emitParamters(fnode.getParameterNodes());
+
+ emitFunctionScope(fnode.getScopedNode());
+ }
+
+ @Override
public void emitField(IVariableNode node)
{
super.emitField(node);
@@ -80,41 +99,29 @@ public class JSEmitter extends ASEmitter
@Override
public void emitVarDeclaration(IVariableNode node)
{
- super.emitVarDeclaration(node);
- // getWalker().walk(node.getChild(0)); // VariableExpressionNode
- // write(" ");
- // getWalker().walk(node.getNameExpressionNode());
- // // add :Type
- // {
- // IExpressionNode tnode = node.getVariableTypeNode();
- // if (tnode instanceof ILanguageIdentifierNode)
- // {
- // ILanguageIdentifierNode lnode = (ILanguageIdentifierNode) tnode;
- // if (lnode.getKind() != ILanguageIdentifierNode.LanguageIdentifierKind.ANY_TYPE)
- // write(":");
- // }
- // else
- // {
- // write(":");
- // }
- //
- // getWalker().walk(node.getVariableTypeNode());
- // }
- // IExpressionNode vnode = node.getAssignedValueNode();
- // if (vnode != null)
- // {
- // write(" = ");
- // if (vnode instanceof FunctionObjectNode)
- // {
- // //getWalker().pushContext(TraverseContext.FUNCTION);
- // getWalker().walk(vnode.getChild(0)); // IFunctionNode
- // //getWalker().popContext(TraverseContext.FUNCTION);
- // }
- // else
- // {
- // getWalker().walk(vnode);
- // }
- // }
+ if (!(node instanceof ChainedVariableNode))
+ {
+ emitMemberKeyword(node);
+ }
+
+ emitDeclarationName(node);
+ emitAssignedValue(node.getAssignedValueNode());
+
+ if (!(node instanceof ChainedVariableNode))
+ {
+ // check for chained variables
+ int len = node.getChildCount();
+ for (int i = 0; i < len; i++)
+ {
+ IASNode child = node.getChild(i);
+ if (child instanceof ChainedVariableNode)
+ {
+ write(",");
+ write(" ");
+ emitVarDeclaration((IVariableNode) child);
+ }
+ }
+ }
}
@Override
Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java?rev=1430315&r1=1430314&r2=1430315&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java Tue Jan 8 15:05:32 2013
@@ -41,11 +41,13 @@ import org.apache.flex.compiler.projects
import org.apache.flex.compiler.tree.ASTNodeID;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IAccessorNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
import org.apache.flex.compiler.tree.as.IClassNode;
import org.apache.flex.compiler.tree.as.IDefinitionNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IFunctionNode;
import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
import org.apache.flex.compiler.tree.as.IPackageNode;
import org.apache.flex.compiler.tree.as.IParameterNode;
import org.apache.flex.compiler.tree.as.IScopedNode;
@@ -576,4 +578,52 @@ public class JSGoogEmitter extends JSEmi
// tail, no colon; parent container will add it
write(")");
}
+
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ @Override
+ public void emitBinaryOperator(IBinaryOperatorNode node)
+ {
+ ASTNodeID id = node.getNodeID();
+
+ if (id == ASTNodeID.Op_AsID || id == ASTNodeID.Op_IsID)
+ {
+ // TODO (erikdebruin) replace: this is a placeholder for the
+ // eventual implementation
+ write((id == ASTNodeID.Op_AsID) ? "as(" : "is(");
+ getWalker().walk(node.getLeftOperandNode());
+ write(", ");
+ getWalker().walk(node.getRightOperandNode());
+ write(")");
+ }
+ else
+ {
+ getWalker().walk(node.getLeftOperandNode());
+
+ if (id != ASTNodeID.Op_CommaID)
+ write(" ");
+
+ // (erikdebruin) rewrite 'a &&= b' to 'a = a && b'
+ if (id == ASTNodeID.Op_LogicalAndAssignID || id == ASTNodeID.Op_LogicalOrAssignID)
+ {
+ IIdentifierNode lnode = (IIdentifierNode) node.getLeftOperandNode();
+
+ write("=");
+ write(" ");
+ write(lnode.getName());
+ write(" ");
+ write((id == ASTNodeID.Op_LogicalAndAssignID) ? ASTNodeID.Op_LogicalAndID.getParaphrase() : ASTNodeID.Op_LogicalOrID.getParaphrase());
+ }
+ else
+ {
+ write(node.getOperator().getOperatorText());
+ }
+
+ write(" ");
+
+ getWalker().walk(node.getRightOperandNode());
+ }
+ }
}