You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2013/06/26 07:42:01 UTC

[1/4] git commit: [flex-falcon] [refs/heads/develop] - changes to get model databinding to work in JS

Updated Branches:
  refs/heads/develop 8611dcb87 -> 4af7ad216


changes to get model databinding to work in JS


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/bd648741
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/bd648741
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/bd648741

Branch: refs/heads/develop
Commit: bd64874191821dccd18f54dba47a57c29a72608a
Parents: 734f9be
Author: Alex Harui <ah...@apache.org>
Authored: Mon Jun 24 22:50:16 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Jun 24 22:53:18 2013 -0700

----------------------------------------------------------------------
 .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java  | 305 ++++++++++++++++++-
 .../codegen/databinding/BindingDatabase.java    |   4 +
 .../databinding/MXMLBindingDirectiveHelper.java |   1 +
 .../codegen/databinding/WatcherInfoBase.java    |   2 +-
 4 files changed, 310 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
index 127df84..09fe26a 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
@@ -19,10 +19,14 @@
 
 package org.apache.flex.compiler.internal.codegen.mxml.flexjs;
 
+
 import java.io.FilterWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
 
+import org.apache.flex.abc.semantics.MethodInfo;
 import org.apache.flex.abc.semantics.Name;
 import org.apache.flex.abc.semantics.Namespace;
 import org.apache.flex.compiler.codegen.as.IASEmitter;
@@ -30,19 +34,31 @@ import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter;
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.databinding.BindingDatabase;
+import org.apache.flex.compiler.internal.codegen.databinding.BindingInfo;
+import org.apache.flex.compiler.internal.codegen.databinding.FunctionWatcherInfo;
+import org.apache.flex.compiler.internal.codegen.databinding.PropertyWatcherInfo;
+import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase;
+import org.apache.flex.compiler.internal.codegen.databinding.XMLWatcherInfo;
+import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
 import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter;
 import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.projects.FlexProject;
 import org.apache.flex.compiler.internal.scopes.ASProjectScope;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.flex.compiler.internal.tree.mxml.MXMLDocumentNode;
 import org.apache.flex.compiler.projects.ICompilerProject;
 import org.apache.flex.compiler.tree.ASTNodeID;
 import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
 import org.apache.flex.compiler.tree.as.IImportNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLArrayNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLDataBindingNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode;
@@ -124,7 +140,7 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
         emitClassDeclStart(cname, node, false);
 
         emitPropertyDecls();
-
+        
         emitClassDeclEnd(cname, node);
 
         emitScripts();
@@ -134,6 +150,9 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
         emitPropertyGetterSetters(cname);
 
         emitMXMLDescriptorFuncs(cname);
+
+        emitBindingData(cname, cdef);
+
     }
 
     //--------------------------------------------------------------------------
@@ -212,6 +231,252 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
         }
     }
 
+    //--------------------------------------------------------------------------
+
+    protected void emitBindingData(String cname, IClassDefinition cdef)
+    {
+        BindingDatabase bd = BindingDatabase.bindingMap.get(cdef);
+        if (bd.getBindingInfo().isEmpty())
+            return;
+
+        outputBindingInfoAsData(cname, bd);
+    }
+
+    private void outputBindingInfoAsData(String cname, BindingDatabase bindingDataBase)
+    {
+        writeNewline("/**");
+        writeNewline(" * @expose");
+        writeNewline(" * @this {" + cname + "}");
+        writeNewline(" */");
+        writeNewline(cname
+                + ".prototype._bindings = [");
+        
+        Set<BindingInfo> bindingInfo = bindingDataBase.getBindingInfo();
+        writeNewline(bindingInfo.size() + ","); // number of bindings
+        
+        for (BindingInfo bi : bindingInfo)
+        {
+            String s;
+            s = bi.getSourceString();
+            if (s == null)
+                s = getSourceStringFromGetter(bi.getExpressionNodesForGetter());
+            if (s.contains("."))
+            {
+                String[] parts = s.split("\\.");
+                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + 
+                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+                int n = parts.length;
+                for (int i = 1; i < n; i++)
+                {
+                    String part = parts[i];
+                    write(", " +  ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+                }
+                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+            }
+            else
+                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s + 
+                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+            
+            s = bi.getDestinationString();
+            if (s.contains("."))
+            {
+                String[] parts = s.split("\\.");
+                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + 
+                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+                int n = parts.length;
+                for (int i = 1; i < n; i++)
+                {
+                    String part = parts[i];
+                    write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+                }
+                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+            }
+            else
+                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
+                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+        }
+        Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();
+        for (Entry<Object, WatcherInfoBase> entry : watcherChains)
+        {
+            WatcherInfoBase watcherInfoBase = entry.getValue();
+            encodeWatcher(watcherInfoBase);
+        }
+        // add a trailing null for now so I don't have to have logic where the watcher figures out not to add
+        // a comma
+        writeNewline("null" + ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.SEMICOLON.getToken());
+    }
+
+    private void encodeWatcher(WatcherInfoBase watcherInfoBase)
+    {
+        writeNewline(watcherInfoBase.getIndex() + ASEmitterTokens.COMMA.getToken());
+        WatcherType type = watcherInfoBase.getType();
+        if (type == WatcherType.FUNCTION)
+        {
+            writeNewline("0" + ASEmitterTokens.COMMA.getToken());
+
+            FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;
+           
+            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + functionWatcherInfo.getFunctionName() + 
+                    ASEmitterTokens.DOUBLE_QUOTE.getToken());
+            outputEventNames(functionWatcherInfo.getEventNames());
+            outputBindings(functionWatcherInfo.getBindings());
+        }
+        else if ((type == WatcherType.STATIC_PROPERTY) || (type == WatcherType.PROPERTY))
+        {
+            writeNewline((type == WatcherType.STATIC_PROPERTY ? "1" : "2") + 
+                    ASEmitterTokens.COMMA.getToken());
+
+            PropertyWatcherInfo propertyWatcherInfo = (PropertyWatcherInfo)watcherInfoBase;
+           
+            boolean makeStaticWatcher = (watcherInfoBase.getType() == WatcherType.STATIC_PROPERTY);
+            
+            // round up the getter function for the watcher, or null if we don't need one
+            MethodInfo propertyGetterFunction = null;
+            if (watcherInfoBase.isRoot && !makeStaticWatcher)
+            {
+                // TODO: figure out what this looks like
+                // propertyGetterFunction = this.propertyGetter;
+                assert propertyGetterFunction != null;
+            }
+            else if (watcherInfoBase.isRoot && makeStaticWatcher)
+            {
+                 // TODO: implement getter func for static watcher.
+            }
+            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + propertyWatcherInfo.getPropertyName() +
+                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+            outputEventNames(propertyWatcherInfo.getEventNames());
+            outputBindings(propertyWatcherInfo.getBindings());
+            if (propertyGetterFunction == null)
+                writeNewline("null" + ASEmitterTokens.COMMA.getToken()); // null is valid
+            // else 
+                // writeNewline(propertyGetterFunction);
+        }
+        else if (type == WatcherType.XML)
+        {
+            writeNewline("3" + ASEmitterTokens.COMMA.getToken());
+
+            XMLWatcherInfo xmlWatcherInfo = (XMLWatcherInfo)watcherInfoBase;
+            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + xmlWatcherInfo.getPropertyName() +
+                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+            outputBindings(xmlWatcherInfo.getBindings());
+        }
+        else assert false;     
+
+        // then recurse into children
+        Set<Entry<Object, WatcherInfoBase>> children = watcherInfoBase.getChildren();
+        if (children != null)
+        {
+            writeNewline(ASEmitterTokens.SQUARE_OPEN.getToken());
+            for ( Entry<Object, WatcherInfoBase> ent : children)
+            {
+                encodeWatcher(ent.getValue());
+            }
+            writeNewline("null" + ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+        }
+        else
+        {
+            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
+        }
+    }
+    
+    private String getSourceStringFromMemberAccessExpressionNode(MemberAccessExpressionNode node)
+    {
+        String s = "";
+        
+        IExpressionNode left = node.getLeftOperandNode();
+        if (left instanceof FunctionCallNode) //  probably a cast
+        {
+            IASNode child = ((FunctionCallNode)left).getArgumentsNode().getChild(0);
+            if (child instanceof IdentifierNode)
+                s = getSourceStringFromIdentifierNode((IdentifierNode)child);
+            else if (child instanceof MemberAccessExpressionNode)
+                s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
+        }
+        else if (left instanceof MemberAccessExpressionNode)
+            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)left);
+        else if (left instanceof IdentifierNode)
+            s = getSourceStringFromIdentifierNode((IdentifierNode)left);
+        else
+            System.out.println("expected binding member access left node" + node.toString());
+        s += ".";
+        
+        IExpressionNode right = node.getRightOperandNode();
+        if (right instanceof FunctionCallNode) //  probably a cast
+        {
+            IASNode child = ((FunctionCallNode)right).getArgumentsNode().getChild(0);
+            if (child instanceof IdentifierNode)
+                s += getSourceStringFromIdentifierNode((IdentifierNode)child);
+            else if (child instanceof MemberAccessExpressionNode)
+                s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
+        }
+        else if (right instanceof MemberAccessExpressionNode)
+            s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)right);
+        else if (right instanceof IdentifierNode)
+            s += getSourceStringFromIdentifierNode((IdentifierNode)right);
+        else
+            System.out.println("expected binding member access right node" + node.toString());
+        
+        return s;
+    }
+    
+    private String getSourceStringFromIdentifierNode(IdentifierNode node)
+    {
+        return node.getName();
+    }
+    
+    private String getSourceStringFromGetter(List<IExpressionNode> nodes)
+    {
+        String s = "";
+        IExpressionNode node = nodes.get(0);
+        if (node instanceof MemberAccessExpressionNode)
+        {
+            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)node);
+        }
+        return s;
+    }
+    
+    private void outputEventNames(List<String> events)
+    {
+        if (events.size() > 1)
+        {
+            int n = events.size();
+            write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
+                    events.get(0) + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+            for (int i = 1; i < n; i++)
+            {
+                String event = events.get(i);
+                write(ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + 
+                        event + ASEmitterTokens.DOUBLE_QUOTE.getToken());
+            }
+            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+        }
+        else if (events.size() == 1)
+            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + events.get(0) +
+                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
+        else
+            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
+    }
+    
+    private void outputBindings(List<BindingInfo> bindings)
+    {
+        if (bindings.size() > 1)
+        {
+            int n = bindings.size();
+            write(ASEmitterTokens.SQUARE_OPEN.getToken() + bindings.get(0).getIndex());
+            for (int i = 1; i < n; i++)
+            {
+                BindingInfo binding = bindings.get(i);
+                write(ASEmitterTokens.COMMA.getToken() + binding.getIndex());
+            }
+            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
+        }
+        else if (bindings.size() == 1)
+            writeNewline(bindings.get(0).getIndex() + ASEmitterTokens.COMMA.getToken());
+        else
+            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
+        
+    }
+
     //--------------------------------------------------------------------------    
 
     protected void emitScripts()
@@ -834,10 +1099,36 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
         return false;
     }
     
+    /**
+     * Is a give node a "databinding node"?
+     */
+    public static boolean isDataBindingNode(IASNode node)
+    {
+        return node instanceof IMXMLDataBindingNode;
+    }
+    
+    protected static boolean isDataboundProp(IMXMLPropertySpecifierNode propertyNode)
+    {
+        boolean ret = propertyNode.getChildCount() > 0 && isDataBindingNode(propertyNode.getInstanceNode());
+        
+        // Sanity check that we based our conclusion about databinding on the correct node.
+        // (code assumes only one child if databinding)
+        int n = propertyNode.getChildCount();
+        for (int i = 0; i < n; i++)
+        {
+            boolean db = isDataBindingNode(propertyNode.getChild(i));
+            assert db == ret;
+        }
+        
+        return ret;
+    }
 
     @Override
     public void emitPropertySpecifier(IMXMLPropertySpecifierNode node)
     {
+        if (isDataboundProp(node))
+            return;
+        
         IDefinition cdef = node.getDefinition();
 
         IASNode cnode = node.getChild(0);
@@ -1010,6 +1301,18 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
                 if (imp.equals(cname))
                     continue;
     
+                if (imp.equals("mx.binding.Binding"))
+                    continue;
+                if (imp.equals("mx.binding.BindingManager"))
+                    continue;
+                if (imp.equals("mx.binding.FunctionReturnWatcher"))
+                    continue;
+                if (imp.equals("mx.binding.PropertyWatcher"))
+                    continue;
+                if (imp.equals("mx.binding.StaticPropertyWatcher"))
+                    continue;
+                if (imp.equals("mx.binding.XMLWatcher"))
+                    continue;
                 if (imp.equals("mx.events.PropertyChangeEvent"))
                     continue;
                 if (imp.equals("mx.events.PropertyChangeEventKind"))

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
index e799950..f55aba1 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
@@ -21,6 +21,7 @@ package org.apache.flex.compiler.internal.codegen.databinding;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -28,6 +29,7 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
 
+import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.internal.as.codegen.MXMLClassDirectiveProcessor;
 import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
 import org.apache.flex.compiler.internal.scopes.ASScope;
@@ -89,6 +91,8 @@ public class BindingDatabase
    
    private static List<BindingDatabase> _diagnosticLogger;
    
+   public static Map<IClassDefinition, BindingDatabase> bindingMap = new HashMap<IClassDefinition, BindingDatabase>();
+   
    /**
     * test only field. Total number of watcher info's of all types
     */

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
index daee6d5..825324f 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
@@ -83,6 +83,7 @@ public class MXMLBindingDirectiveHelper
     public MXMLBindingDirectiveHelper(MXMLClassDirectiveProcessor ddp, IABCVisitor emitter)
     {
         host = ddp;
+        BindingDatabase.bindingMap.put(ddp.getClassDefinition(), bindingDataBase);
         this.emitter = emitter;
     }
     

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
index b9dd180..ba52f7f 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
@@ -98,7 +98,7 @@ public class WatcherInfoBase
      */
     public boolean isRoot = false;
 
-    WatcherType getType()
+    public WatcherType getType()
     {
         return type;
     }


[4/4] git commit: [flex-falcon] [refs/heads/develop] - more fixes for databinding

Posted by ah...@apache.org.
more fixes for databinding


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/4af7ad21
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/4af7ad21
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/4af7ad21

Branch: refs/heads/develop
Commit: 4af7ad216d344d76fc8dc18d77f426c5e03b9215
Parents: a50776c
Author: Alex Harui <ah...@apache.org>
Authored: Tue Jun 25 22:40:11 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Tue Jun 25 22:40:11 2013 -0700

----------------------------------------------------------------------
 compiler.jx/build.xml                                     |  2 +-
 .../internal/projects/FlexProjectConfigurator.java        | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4af7ad21/compiler.jx/build.xml
----------------------------------------------------------------------
diff --git a/compiler.jx/build.xml b/compiler.jx/build.xml
index af29c60..7d53854 100644
--- a/compiler.jx/build.xml
+++ b/compiler.jx/build.xml
@@ -80,7 +80,7 @@
 	
 	<target name="main" depends="prebuild,copyFiles,compile">
         
-        <property name="jar.classpath" value="commons-io.jar google/closure-compiler/compiler.jar ../../compiler/generated/dist/sdk/lib/compiler.jar ../../lib/compiler.jar" />
+        <property name="jar.classpath" value="commons-io.jar ../../lib/external/guava.jar google/closure-compiler/compiler.jar ../../compiler/generated/dist/sdk/lib/compiler.jar ../../lib/compiler.jar" />
 
 		<echo message="Building ${jsc.jar}" />
 		<jar file="${jsc.jar}" basedir="${classes.dir}"

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4af7ad21/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
index 1c247f2..00987d8 100644
--- a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
+++ b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
@@ -183,32 +183,32 @@ public class FlexProjectConfigurator
             String configValue = configuration.getBindingEventHandlerEvent();
             int dotIndex;
             dotIndex = configValue.lastIndexOf(".");
-            String packageName = configValue.substring(0, dotIndex - 1);
+            String packageName = configValue.substring(0, dotIndex);
             String className = configValue.substring(dotIndex + 1);
             BindableHelper.NAME_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
             
             configValue = configuration.getBindingEventHandlerClass();
             dotIndex = configValue.lastIndexOf(".");
-            packageName = configValue.substring(0, dotIndex - 1);
+            packageName = configValue.substring(0, dotIndex);
             className = configValue.substring(dotIndex + 1);
             BindableHelper.NAME_EVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
     
             configValue = configuration.getBindingEventHandlerInterface();
             dotIndex = configValue.lastIndexOf(".");
-            packageName = configValue.substring(0, dotIndex - 1);
+            packageName = configValue.substring(0, dotIndex);
             className = configValue.substring(dotIndex + 1);
             BindableHelper.NAME_IEVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
     
             configValue = configuration.getBindingValueChangeEvent();
             dotIndex = configValue.lastIndexOf(".");
-            packageName = configValue.substring(0, dotIndex - 1);
+            packageName = configValue.substring(0, dotIndex);
             className = configValue.substring(dotIndex + 1);
             BindableHelper.NAME_PROPERTY_CHANGE_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
             BindableHelper.NAMESPACE_MX_EVENTS = new Namespace(CONSTANT_PackageNs, packageName);
             
             configValue = configuration.getBindingValueChangeEventKind();
             dotIndex = configValue.lastIndexOf(".");
-            packageName = configValue.substring(0, dotIndex - 1);
+            packageName = configValue.substring(0, dotIndex);
             className = configValue.substring(dotIndex + 1);
             BindableHelper.NAME_PROPERTY_CHANGE_EVENT_KIND = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
         


[3/4] git commit: [flex-falcon] [refs/heads/develop] - fix tests broken by previous changes

Posted by ah...@apache.org.
fix tests broken by previous changes


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/a50776c3
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/a50776c3
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/a50776c3

Branch: refs/heads/develop
Commit: a50776c331b835d1c3974cc9ec6ce184cca9cdd2
Parents: bd64874
Author: Alex Harui <ah...@apache.org>
Authored: Mon Jun 24 23:58:17 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Jun 24 23:58:17 2013 -0700

----------------------------------------------------------------------
 .../compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java | 2 ++
 .../compiler/internal/codegen/databinding/BindingDatabase.java   | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a50776c3/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
index 09fe26a..eb94f27 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
@@ -236,6 +236,8 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
     protected void emitBindingData(String cname, IClassDefinition cdef)
     {
         BindingDatabase bd = BindingDatabase.bindingMap.get(cdef);
+        if (bd == null)
+            return;
         if (bd.getBindingInfo().isEmpty())
             return;
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a50776c3/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
index f55aba1..ff66319 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
@@ -21,13 +21,13 @@ package org.apache.flex.compiler.internal.codegen.databinding;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.WeakHashMap;
 
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.internal.as.codegen.MXMLClassDirectiveProcessor;
@@ -91,7 +91,7 @@ public class BindingDatabase
    
    private static List<BindingDatabase> _diagnosticLogger;
    
-   public static Map<IClassDefinition, BindingDatabase> bindingMap = new HashMap<IClassDefinition, BindingDatabase>();
+   public static WeakHashMap<IClassDefinition, BindingDatabase> bindingMap = new WeakHashMap<IClassDefinition, BindingDatabase>();
    
    /**
     * test only field. Total number of watcher info's of all types


Re: [1/4] git commit: [flex-falcon] [refs/heads/develop] - changes to get model databinding to work in JS

Posted by Erik de Bruin <er...@ixsoftware.nl>.
Awesome!!!

EdB



On Wed, Jun 26, 2013 at 7:42 AM,  <ah...@apache.org> wrote:
> Updated Branches:
>   refs/heads/develop 8611dcb87 -> 4af7ad216
>
>
> changes to get model databinding to work in JS
>
>
> Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
> Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/bd648741
> Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/bd648741
> Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/bd648741
>
> Branch: refs/heads/develop
> Commit: bd64874191821dccd18f54dba47a57c29a72608a
> Parents: 734f9be
> Author: Alex Harui <ah...@apache.org>
> Authored: Mon Jun 24 22:50:16 2013 -0700
> Committer: Alex Harui <ah...@apache.org>
> Committed: Mon Jun 24 22:53:18 2013 -0700
>
> ----------------------------------------------------------------------
>  .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java  | 305 ++++++++++++++++++-
>  .../codegen/databinding/BindingDatabase.java    |   4 +
>  .../databinding/MXMLBindingDirectiveHelper.java |   1 +
>  .../codegen/databinding/WatcherInfoBase.java    |   2 +-
>  4 files changed, 310 insertions(+), 2 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
> ----------------------------------------------------------------------
> diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
> index 127df84..09fe26a 100644
> --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
> +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
> @@ -19,10 +19,14 @@
>
>  package org.apache.flex.compiler.internal.codegen.mxml.flexjs;
>
> +
>  import java.io.FilterWriter;
>  import java.util.ArrayList;
>  import java.util.List;
> +import java.util.Set;
> +import java.util.Map.Entry;
>
> +import org.apache.flex.abc.semantics.MethodInfo;
>  import org.apache.flex.abc.semantics.Name;
>  import org.apache.flex.abc.semantics.Namespace;
>  import org.apache.flex.compiler.codegen.as.IASEmitter;
> @@ -30,19 +34,31 @@ import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter;
>  import org.apache.flex.compiler.definitions.IClassDefinition;
>  import org.apache.flex.compiler.definitions.IDefinition;
>  import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
> +import org.apache.flex.compiler.internal.codegen.databinding.BindingDatabase;
> +import org.apache.flex.compiler.internal.codegen.databinding.BindingInfo;
> +import org.apache.flex.compiler.internal.codegen.databinding.FunctionWatcherInfo;
> +import org.apache.flex.compiler.internal.codegen.databinding.PropertyWatcherInfo;
> +import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase;
> +import org.apache.flex.compiler.internal.codegen.databinding.XMLWatcherInfo;
> +import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
>  import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
>  import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
>  import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter;
>  import org.apache.flex.compiler.internal.projects.FlexJSProject;
>  import org.apache.flex.compiler.internal.projects.FlexProject;
>  import org.apache.flex.compiler.internal.scopes.ASProjectScope;
> +import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
> +import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
> +import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
>  import org.apache.flex.compiler.internal.tree.mxml.MXMLDocumentNode;
>  import org.apache.flex.compiler.projects.ICompilerProject;
>  import org.apache.flex.compiler.tree.ASTNodeID;
>  import org.apache.flex.compiler.tree.as.IASNode;
> +import org.apache.flex.compiler.tree.as.IExpressionNode;
>  import org.apache.flex.compiler.tree.as.IImportNode;
>  import org.apache.flex.compiler.tree.mxml.IMXMLArrayNode;
>  import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode;
> +import org.apache.flex.compiler.tree.mxml.IMXMLDataBindingNode;
>  import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
>  import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
>  import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode;
> @@ -124,7 +140,7 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
>          emitClassDeclStart(cname, node, false);
>
>          emitPropertyDecls();
> -
> +
>          emitClassDeclEnd(cname, node);
>
>          emitScripts();
> @@ -134,6 +150,9 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
>          emitPropertyGetterSetters(cname);
>
>          emitMXMLDescriptorFuncs(cname);
> +
> +        emitBindingData(cname, cdef);
> +
>      }
>
>      //--------------------------------------------------------------------------
> @@ -212,6 +231,252 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
>          }
>      }
>
> +    //--------------------------------------------------------------------------
> +
> +    protected void emitBindingData(String cname, IClassDefinition cdef)
> +    {
> +        BindingDatabase bd = BindingDatabase.bindingMap.get(cdef);
> +        if (bd.getBindingInfo().isEmpty())
> +            return;
> +
> +        outputBindingInfoAsData(cname, bd);
> +    }
> +
> +    private void outputBindingInfoAsData(String cname, BindingDatabase bindingDataBase)
> +    {
> +        writeNewline("/**");
> +        writeNewline(" * @expose");
> +        writeNewline(" * @this {" + cname + "}");
> +        writeNewline(" */");
> +        writeNewline(cname
> +                + ".prototype._bindings = [");
> +
> +        Set<BindingInfo> bindingInfo = bindingDataBase.getBindingInfo();
> +        writeNewline(bindingInfo.size() + ","); // number of bindings
> +
> +        for (BindingInfo bi : bindingInfo)
> +        {
> +            String s;
> +            s = bi.getSourceString();
> +            if (s == null)
> +                s = getSourceStringFromGetter(bi.getExpressionNodesForGetter());
> +            if (s.contains("."))
> +            {
> +                String[] parts = s.split("\\.");
> +                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
> +                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +                int n = parts.length;
> +                for (int i = 1; i < n; i++)
> +                {
> +                    String part = parts[i];
> +                    write(", " +  ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +                }
> +                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
> +            }
> +            else
> +                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
> +                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
> +
> +            s = bi.getDestinationString();
> +            if (s.contains("."))
> +            {
> +                String[] parts = s.split("\\.");
> +                write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
> +                        parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +                int n = parts.length;
> +                for (int i = 1; i < n; i++)
> +                {
> +                    String part = parts[i];
> +                    write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +                }
> +                writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
> +            }
> +            else
> +                writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s +
> +                        ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
> +        }
> +        Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();
> +        for (Entry<Object, WatcherInfoBase> entry : watcherChains)
> +        {
> +            WatcherInfoBase watcherInfoBase = entry.getValue();
> +            encodeWatcher(watcherInfoBase);
> +        }
> +        // add a trailing null for now so I don't have to have logic where the watcher figures out not to add
> +        // a comma
> +        writeNewline("null" + ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.SEMICOLON.getToken());
> +    }
> +
> +    private void encodeWatcher(WatcherInfoBase watcherInfoBase)
> +    {
> +        writeNewline(watcherInfoBase.getIndex() + ASEmitterTokens.COMMA.getToken());
> +        WatcherType type = watcherInfoBase.getType();
> +        if (type == WatcherType.FUNCTION)
> +        {
> +            writeNewline("0" + ASEmitterTokens.COMMA.getToken());
> +
> +            FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;
> +
> +            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + functionWatcherInfo.getFunctionName() +
> +                    ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +            outputEventNames(functionWatcherInfo.getEventNames());
> +            outputBindings(functionWatcherInfo.getBindings());
> +        }
> +        else if ((type == WatcherType.STATIC_PROPERTY) || (type == WatcherType.PROPERTY))
> +        {
> +            writeNewline((type == WatcherType.STATIC_PROPERTY ? "1" : "2") +
> +                    ASEmitterTokens.COMMA.getToken());
> +
> +            PropertyWatcherInfo propertyWatcherInfo = (PropertyWatcherInfo)watcherInfoBase;
> +
> +            boolean makeStaticWatcher = (watcherInfoBase.getType() == WatcherType.STATIC_PROPERTY);
> +
> +            // round up the getter function for the watcher, or null if we don't need one
> +            MethodInfo propertyGetterFunction = null;
> +            if (watcherInfoBase.isRoot && !makeStaticWatcher)
> +            {
> +                // TODO: figure out what this looks like
> +                // propertyGetterFunction = this.propertyGetter;
> +                assert propertyGetterFunction != null;
> +            }
> +            else if (watcherInfoBase.isRoot && makeStaticWatcher)
> +            {
> +                 // TODO: implement getter func for static watcher.
> +            }
> +            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + propertyWatcherInfo.getPropertyName() +
> +                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
> +            outputEventNames(propertyWatcherInfo.getEventNames());
> +            outputBindings(propertyWatcherInfo.getBindings());
> +            if (propertyGetterFunction == null)
> +                writeNewline("null" + ASEmitterTokens.COMMA.getToken()); // null is valid
> +            // else
> +                // writeNewline(propertyGetterFunction);
> +        }
> +        else if (type == WatcherType.XML)
> +        {
> +            writeNewline("3" + ASEmitterTokens.COMMA.getToken());
> +
> +            XMLWatcherInfo xmlWatcherInfo = (XMLWatcherInfo)watcherInfoBase;
> +            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + xmlWatcherInfo.getPropertyName() +
> +                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
> +            outputBindings(xmlWatcherInfo.getBindings());
> +        }
> +        else assert false;
> +
> +        // then recurse into children
> +        Set<Entry<Object, WatcherInfoBase>> children = watcherInfoBase.getChildren();
> +        if (children != null)
> +        {
> +            writeNewline(ASEmitterTokens.SQUARE_OPEN.getToken());
> +            for ( Entry<Object, WatcherInfoBase> ent : children)
> +            {
> +                encodeWatcher(ent.getValue());
> +            }
> +            writeNewline("null" + ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
> +        }
> +        else
> +        {
> +            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
> +        }
> +    }
> +
> +    private String getSourceStringFromMemberAccessExpressionNode(MemberAccessExpressionNode node)
> +    {
> +        String s = "";
> +
> +        IExpressionNode left = node.getLeftOperandNode();
> +        if (left instanceof FunctionCallNode) //  probably a cast
> +        {
> +            IASNode child = ((FunctionCallNode)left).getArgumentsNode().getChild(0);
> +            if (child instanceof IdentifierNode)
> +                s = getSourceStringFromIdentifierNode((IdentifierNode)child);
> +            else if (child instanceof MemberAccessExpressionNode)
> +                s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
> +        }
> +        else if (left instanceof MemberAccessExpressionNode)
> +            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)left);
> +        else if (left instanceof IdentifierNode)
> +            s = getSourceStringFromIdentifierNode((IdentifierNode)left);
> +        else
> +            System.out.println("expected binding member access left node" + node.toString());
> +        s += ".";
> +
> +        IExpressionNode right = node.getRightOperandNode();
> +        if (right instanceof FunctionCallNode) //  probably a cast
> +        {
> +            IASNode child = ((FunctionCallNode)right).getArgumentsNode().getChild(0);
> +            if (child instanceof IdentifierNode)
> +                s += getSourceStringFromIdentifierNode((IdentifierNode)child);
> +            else if (child instanceof MemberAccessExpressionNode)
> +                s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
> +        }
> +        else if (right instanceof MemberAccessExpressionNode)
> +            s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)right);
> +        else if (right instanceof IdentifierNode)
> +            s += getSourceStringFromIdentifierNode((IdentifierNode)right);
> +        else
> +            System.out.println("expected binding member access right node" + node.toString());
> +
> +        return s;
> +    }
> +
> +    private String getSourceStringFromIdentifierNode(IdentifierNode node)
> +    {
> +        return node.getName();
> +    }
> +
> +    private String getSourceStringFromGetter(List<IExpressionNode> nodes)
> +    {
> +        String s = "";
> +        IExpressionNode node = nodes.get(0);
> +        if (node instanceof MemberAccessExpressionNode)
> +        {
> +            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)node);
> +        }
> +        return s;
> +    }
> +
> +    private void outputEventNames(List<String> events)
> +    {
> +        if (events.size() > 1)
> +        {
> +            int n = events.size();
> +            write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
> +                    events.get(0) + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +            for (int i = 1; i < n; i++)
> +            {
> +                String event = events.get(i);
> +                write(ASEmitterTokens.COMMA.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() +
> +                        event + ASEmitterTokens.DOUBLE_QUOTE.getToken());
> +            }
> +            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
> +        }
> +        else if (events.size() == 1)
> +            writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + events.get(0) +
> +                    ASEmitterTokens.DOUBLE_QUOTE.getToken() + ASEmitterTokens.COMMA.getToken());
> +        else
> +            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
> +    }
> +
> +    private void outputBindings(List<BindingInfo> bindings)
> +    {
> +        if (bindings.size() > 1)
> +        {
> +            int n = bindings.size();
> +            write(ASEmitterTokens.SQUARE_OPEN.getToken() + bindings.get(0).getIndex());
> +            for (int i = 1; i < n; i++)
> +            {
> +                BindingInfo binding = bindings.get(i);
> +                write(ASEmitterTokens.COMMA.getToken() + binding.getIndex());
> +            }
> +            writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken());
> +        }
> +        else if (bindings.size() == 1)
> +            writeNewline(bindings.get(0).getIndex() + ASEmitterTokens.COMMA.getToken());
> +        else
> +            writeNewline("null" + ASEmitterTokens.COMMA.getToken());
> +
> +    }
> +
>      //--------------------------------------------------------------------------
>
>      protected void emitScripts()
> @@ -834,10 +1099,36 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
>          return false;
>      }
>
> +    /**
> +     * Is a give node a "databinding node"?
> +     */
> +    public static boolean isDataBindingNode(IASNode node)
> +    {
> +        return node instanceof IMXMLDataBindingNode;
> +    }
> +
> +    protected static boolean isDataboundProp(IMXMLPropertySpecifierNode propertyNode)
> +    {
> +        boolean ret = propertyNode.getChildCount() > 0 && isDataBindingNode(propertyNode.getInstanceNode());
> +
> +        // Sanity check that we based our conclusion about databinding on the correct node.
> +        // (code assumes only one child if databinding)
> +        int n = propertyNode.getChildCount();
> +        for (int i = 0; i < n; i++)
> +        {
> +            boolean db = isDataBindingNode(propertyNode.getChild(i));
> +            assert db == ret;
> +        }
> +
> +        return ret;
> +    }
>
>      @Override
>      public void emitPropertySpecifier(IMXMLPropertySpecifierNode node)
>      {
> +        if (isDataboundProp(node))
> +            return;
> +
>          IDefinition cdef = node.getDefinition();
>
>          IASNode cnode = node.getChild(0);
> @@ -1010,6 +1301,18 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
>                  if (imp.equals(cname))
>                      continue;
>
> +                if (imp.equals("mx.binding.Binding"))
> +                    continue;
> +                if (imp.equals("mx.binding.BindingManager"))
> +                    continue;
> +                if (imp.equals("mx.binding.FunctionReturnWatcher"))
> +                    continue;
> +                if (imp.equals("mx.binding.PropertyWatcher"))
> +                    continue;
> +                if (imp.equals("mx.binding.StaticPropertyWatcher"))
> +                    continue;
> +                if (imp.equals("mx.binding.XMLWatcher"))
> +                    continue;
>                  if (imp.equals("mx.events.PropertyChangeEvent"))
>                      continue;
>                  if (imp.equals("mx.events.PropertyChangeEventKind"))
>
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
> ----------------------------------------------------------------------
> diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
> index e799950..f55aba1 100644
> --- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
> +++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingDatabase.java
> @@ -21,6 +21,7 @@ package org.apache.flex.compiler.internal.codegen.databinding;
>
>  import java.util.ArrayList;
>  import java.util.Collection;
> +import java.util.HashMap;
>  import java.util.LinkedHashMap;
>  import java.util.List;
>  import java.util.Map;
> @@ -28,6 +29,7 @@ import java.util.Map.Entry;
>  import java.util.Set;
>  import java.util.TreeSet;
>
> +import org.apache.flex.compiler.definitions.IClassDefinition;
>  import org.apache.flex.compiler.internal.as.codegen.MXMLClassDirectiveProcessor;
>  import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
>  import org.apache.flex.compiler.internal.scopes.ASScope;
> @@ -89,6 +91,8 @@ public class BindingDatabase
>
>     private static List<BindingDatabase> _diagnosticLogger;
>
> +   public static Map<IClassDefinition, BindingDatabase> bindingMap = new HashMap<IClassDefinition, BindingDatabase>();
> +
>     /**
>      * test only field. Total number of watcher info's of all types
>      */
>
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
> ----------------------------------------------------------------------
> diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
> index daee6d5..825324f 100644
> --- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
> +++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
> @@ -83,6 +83,7 @@ public class MXMLBindingDirectiveHelper
>      public MXMLBindingDirectiveHelper(MXMLClassDirectiveProcessor ddp, IABCVisitor emitter)
>      {
>          host = ddp;
> +        BindingDatabase.bindingMap.put(ddp.getClassDefinition(), bindingDataBase);
>          this.emitter = emitter;
>      }
>
>
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/bd648741/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
> ----------------------------------------------------------------------
> diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
> index b9dd180..ba52f7f 100644
> --- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
> +++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/WatcherInfoBase.java
> @@ -98,7 +98,7 @@ public class WatcherInfoBase
>       */
>      public boolean isRoot = false;
>
> -    WatcherType getType()
> +    public WatcherType getType()
>      {
>          return type;
>      }
>



-- 
Ix Multimedia Software

Jan Luykenstraat 27
3521 VB Utrecht

T. 06-51952295
I. www.ixsoftware.nl

[2/4] git commit: [flex-falcon] [refs/heads/develop] - changes to support databinding in FlexJS

Posted by ah...@apache.org.
changes to support databinding in FlexJS


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/734f9bec
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/734f9bec
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/734f9bec

Branch: refs/heads/develop
Commit: 734f9bec02c81034eb39d85bff4595bc3870e0b5
Parents: 8611dcb
Author: Alex Harui <ah...@apache.org>
Authored: Sat Jun 22 07:21:08 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Mon Jun 24 22:53:18 2013 -0700

----------------------------------------------------------------------
 .../flex/compiler/config/Configuration.java     | 122 +++++++++-
 .../internal/as/codegen/BindableHelper.java     |  14 +-
 .../as/codegen/MXMLClassDirectiveProcessor.java |  34 ++-
 .../databinding/MXMLBindingDirectiveHelper.java | 226 +++++++++++++++++++
 .../projects/FlexProjectConfigurator.java       |  45 ++++
 5 files changed, 424 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/734f9bec/compiler/src/org/apache/flex/compiler/config/Configuration.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/config/Configuration.java b/compiler/src/org/apache/flex/compiler/config/Configuration.java
index 6cbb8a7..b8afa21 100644
--- a/compiler/src/org/apache/flex/compiler/config/Configuration.java
+++ b/compiler/src/org/apache/flex/compiler/config/Configuration.java
@@ -1551,7 +1551,127 @@ public class Configuration
         allowSourcePathOverlap = b;
     }
 
-/**
+    //
+    // 'compiler.binding-value-change-event' option
+    //
+
+    private String bindingValueChangeEvent = "mx.events.PropertyChangeEvent";
+
+    public String getBindingValueChangeEvent()
+    {
+        return bindingValueChangeEvent;
+    }
+
+    /**
+     * The change event class for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEvent(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEvent = b;
+    }
+
+    //
+    // 'compiler.binding-value-change-event-kind' option
+    //
+
+    private String bindingValueChangeEventKind = "mx.events.PropertyChangeEventKind";
+
+    public String getBindingValueChangeEventKind()
+    {
+        return bindingValueChangeEventKind;
+    }
+
+    /**
+     * The change event kind for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEventKind(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEventKind = b;
+    }
+
+    //
+    // 'compiler.binding-value-change-event-type' option
+    //
+
+    private String bindingValueChangeEventType = "propertyChange";
+
+    public String getBindingValueChangeEventType()
+    {
+        return bindingValueChangeEventType;
+    }
+
+    /**
+     * The change event type for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingValueChangeEventType(ConfigurationValue cv, String b)
+    {
+        bindingValueChangeEventType = b;
+    }
+
+    //
+    // 'compiler.binding-event-handler-event' option
+    //
+
+    private String bindingEventHandlerEvent = "flash.events.Event";
+
+    public String getBindingEventHandlerEvent()
+    {
+        return bindingEventHandlerEvent;
+    }
+
+    /**
+     * The event handler event for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerEvent(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerEvent = b;
+    }
+
+    //
+    // 'compiler.binding-event-handler-class' option
+    //
+
+    private String bindingEventHandlerClass = "flash.events.EventDispatcher";
+
+    public String getBindingEventHandlerClass()
+    {
+        return bindingEventHandlerClass;
+    }
+
+    /**
+     * The event handler class for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerClass(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerClass = b;
+    }
+    
+    //
+    // 'compiler.binding-event-handler-interface' option
+    //
+
+    private String bindingEventHandlerInterface = "flash.events.IEventDispatcher";
+
+    public String getBindingEventHandlerInterface()
+    {
+        return bindingEventHandlerInterface;
+    }
+
+    /**
+     * The event handler interface for generated binding code
+     */
+    @Config(advanced = true)
+    public void setCompilerBindingEventHandlerInterface(ConfigurationValue cv, String b)
+    {
+        bindingEventHandlerInterface = b;
+    }
+    
+    /**
      * Syntax:<br/>
      * <code>-define=&lt;name&gt;,&lt;value&gt;</code>
      * where name is <code>NAMESPACE::name</code> and value is a legal definition value

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/734f9bec/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java b/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java
index 67a33b4..21f5bda 100644
--- a/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java
+++ b/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java
@@ -528,13 +528,13 @@ public class BindableHelper
     /**
      * The mx.events package namespace
      */
-    private static final Namespace NAMESPACE_MX_EVENTS = new Namespace(CONSTANT_PackageNs, "mx.events");
+    public static Namespace NAMESPACE_MX_EVENTS = new Namespace(CONSTANT_PackageNs, "mx.events");
 
     //
     // Following Names are constants to use for various types & properties used in the code generated for Bindable
     //
-    private static final Name NAME_PROPERTY_CHANGE_EVENT = new Name(CONSTANT_Qname, new Nsset(NAMESPACE_MX_EVENTS), "PropertyChangeEvent");
-    private static final Name NAME_PROPERTY_CHANGE_EVENT_KIND = new Name(CONSTANT_Qname, new Nsset(NAMESPACE_MX_EVENTS), "PropertyChangeEventKind");
+    public static Name NAME_PROPERTY_CHANGE_EVENT = new Name(CONSTANT_Qname, new Nsset(NAMESPACE_MX_EVENTS), "PropertyChangeEvent");
+    public static Name NAME_PROPERTY_CHANGE_EVENT_KIND = new Name(CONSTANT_Qname, new Nsset(NAMESPACE_MX_EVENTS), "PropertyChangeEventKind");
     private static final Name NAME_CREATE_UPDATE_EVENT = new Name("createUpdateEvent");
 
     private static final Name NAME_STRING = new Name(IASLanguageConstants.String);
@@ -544,17 +544,17 @@ public class BindableHelper
     private static final Name NAME_VOID = new Name(IASLanguageConstants.void_);
 
 
-    private static final Name NAME_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "Event");
+    public static Name NAME_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "Event");
     private static final Name NAME_ADDEVENT_LISTENER = new Name("addEventListener");
     private static final Name NAME_DISPATCH_EVENT = new Name("dispatchEvent");
     private static final Name NAME_HAS_EVENT_LISTENER = new Name("hasEventListener");
     private static final Name NAME_REMOVE_EVENT_LISTENER = new Name("removeEventListener");
     private static final Name NAME_WILL_TRIGGER = new Name("willTrigger");
-    private static final Name NAME_EVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "EventDispatcher");
-    private static final Name NAME_IEVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "IEventDispatcher");
+    public static Name NAME_EVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "EventDispatcher");
+    public static Name NAME_IEVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, "flash.events")), "IEventDispatcher");
     private static final Name NAME_BINDING_EVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(bindablePrivateNamespace), "_bindingEventDispatcher");
     private static final Name NAME_STATIC_EVENT_DISPATCHER = new Name("staticEventDispatcher");
 
-    private static final String PROPERTY_CHANGE = "propertyChange";
+    public static String PROPERTY_CHANGE = "propertyChange";
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/734f9bec/compiler/src/org/apache/flex/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java b/compiler/src/org/apache/flex/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
index 88773a5..708376a 100644
--- a/compiler/src/org/apache/flex/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
+++ b/compiler/src/org/apache/flex/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
@@ -3245,6 +3245,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
                                 
                 context.stopUsing(IL.PROPERTIES, 1);
                                 
+                context.isStateDescriptor = false;
             }
             else if (propertyName.equals("model"))
             {
@@ -3274,15 +3275,26 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
             }
             else
             {
-                context.startUsing(IL.PROPERTIES);
-                
-                context.addInstruction(OP_pushstring, propertyName);
-                
-                context.isContentFactory = false;
-                
-                traverse(propertyNode, context);
-                
-                context.stopUsing(IL.PROPERTIES, 1);
+                if (!isDataboundProp(propertyNode))
+                {
+                    context.startUsing(IL.PROPERTIES);
+                    
+                    context.addInstruction(OP_pushstring, propertyName);
+                    
+                    context.isContentFactory = false;
+                    
+                    traverse(propertyNode, context);
+                    
+                    context.stopUsing(IL.PROPERTIES, 1);
+                }
+                else
+                {
+                    IMXMLInstanceNode instanceNode = propertyNode.getInstanceNode();
+                    if (instanceNode instanceof IMXMLSingleDataBindingNode)
+                        processMXMLDataBinding((IMXMLSingleDataBindingNode)instanceNode, context);
+                    else if (instanceNode instanceof IMXMLConcatenatedDataBindingNode)
+                        processMXMLConcatenatedDataBinding((IMXMLConcatenatedDataBindingNode)instanceNode, context);
+                }
             }
             return;
         }
@@ -3889,6 +3901,10 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
                 context.parentContext.incrementCounter(IL.MXML_STATES_ARRAY, numElements);
             }
         }
+        if (getProject().getTargetSettings().getMxmlChildrenAsData())
+        {
+            context.isStateDescriptor = false;
+        }
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/734f9bec/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
index 488f475..daee6d5 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java
@@ -21,6 +21,7 @@ package org.apache.flex.compiler.internal.codegen.databinding;
 
 import static org.apache.flex.abc.ABCConstants.*;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -39,7 +40,12 @@ import org.apache.flex.compiler.internal.as.codegen.MXMLClassDirectiveProcessor;
 import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
 import org.apache.flex.compiler.internal.projects.FlexProject;
 import org.apache.flex.compiler.internal.scopes.ASScope;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.flex.compiler.mxml.IMXMLTypeConstants;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLBindingNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDataBindingNode;
 import org.apache.flex.compiler.workspaces.IWorkspace;
@@ -140,6 +146,9 @@ public class MXMLBindingDirectiveHelper
         // Just comment it out before checking
         //System.out.println("db: " + bindingDataBase);
         
+        if (host.getProject().getTargetSettings().getMxmlChildrenAsData())
+            return outputBindingInfoAsData();
+        
         InstructionList ret = new InstructionList();
         
         makeSpecialMemberVariablesForBinding();
@@ -155,6 +164,223 @@ public class MXMLBindingDirectiveHelper
         return ret;
     }
     
+    private InstructionList outputBindingInfoAsData()
+    {
+        host.addVariableTrait(IMXMLTypeConstants.NAME_BINDINGS, NAME_ARRAYTYPE);
+
+        InstructionList ret = new InstructionList();
+        int propertyCount = 0;
+        
+        Set<BindingInfo> bindingInfo = bindingDataBase.getBindingInfo();
+        ret.pushNumericConstant(bindingInfo.size()); // number of bindings
+        propertyCount++;
+        
+        for (BindingInfo bi : bindingInfo)
+        {
+            String s;
+            s = bi.getSourceString();
+            if (s == null)
+                s = getSourceStringFromGetter(bi.getExpressionNodesForGetter());
+            if (s.contains("."))
+            {
+                String[] parts = s.split("\\.");
+                for (String part : parts)
+                    ret.addInstruction(OP_pushstring, part);
+                ret.addInstruction(OP_newarray, parts.length);
+            }
+            else
+                ret.addInstruction(OP_pushstring, s);
+            
+            s = bi.getDestinationString();
+            if (s.contains("."))
+            {
+                String[] parts = s.split("\\.");
+                for (String part : parts)
+                    ret.addInstruction(OP_pushstring, part);
+                ret.addInstruction(OP_newarray, parts.length);
+            }
+            else
+                ret.addInstruction(OP_pushstring, s);
+            propertyCount += 2;
+        }
+        Set<Entry<Object, WatcherInfoBase>> watcherChains = bindingDataBase.getWatcherChains();
+        for (Entry<Object, WatcherInfoBase> entry : watcherChains)
+        {
+            WatcherInfoBase watcherInfoBase = entry.getValue();
+            propertyCount += encodeWatcher(ret, watcherInfoBase);
+        }
+        ret.addInstruction(OP_newarray,  propertyCount); 
+        // now save array to _bindings property
+        ret.addInstruction(OP_getlocal0);
+        // stack : this, bindings
+        ret.addInstruction(OP_swap);
+        // stack : bindings, this
+        ret.addInstruction(OP_setproperty, IMXMLTypeConstants.NAME_BINDINGS);
+
+        return ret;
+    }
+
+    private int encodeWatcher(InstructionList ret, WatcherInfoBase watcherInfoBase)
+    {
+        ret.pushNumericConstant(watcherInfoBase.getIndex());
+        WatcherType type = watcherInfoBase.getType();
+        int propertyCount = 1;            
+        if (type == WatcherType.FUNCTION)
+        {
+            ret.pushNumericConstant(0);
+
+            FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;
+           
+            ret.addInstruction(OP_pushstring, functionWatcherInfo.getFunctionName());
+            outputEventNames(ret, functionWatcherInfo.getEventNames());
+            outputBindings(ret, functionWatcherInfo.getBindings());
+            propertyCount += 4;
+        }
+        else if ((type == WatcherType.STATIC_PROPERTY) || (type == WatcherType.PROPERTY))
+        {
+            ret.pushNumericConstant(type == WatcherType.STATIC_PROPERTY ? 1 : 2);
+
+            PropertyWatcherInfo propertyWatcherInfo = (PropertyWatcherInfo)watcherInfoBase;
+           
+            boolean makeStaticWatcher = (watcherInfoBase.getType() == WatcherType.STATIC_PROPERTY);
+            
+            // round up the getter function for the watcher, or null if we don't need one
+            MethodInfo propertyGetterFunction = null;
+            if (watcherInfoBase.isRoot && !makeStaticWatcher)
+            {
+                propertyGetterFunction = this.propertyGetter;
+                assert propertyGetterFunction != null;
+            }
+            else if (watcherInfoBase.isRoot && makeStaticWatcher)
+            {
+                 // TOTO: implement getter func for static watcher.
+            }
+            ret.addInstruction(OP_pushstring, propertyWatcherInfo.getPropertyName());
+            outputEventNames(ret, propertyWatcherInfo.getEventNames());
+            outputBindings(ret, propertyWatcherInfo.getBindings());
+            if (propertyGetterFunction == null)
+                ret.addInstruction(OP_pushnull);            // null is valid
+            else 
+                ret.addInstruction(OP_newfunction, propertyGetterFunction);
+            propertyCount += 5;
+        }
+        else if (type == WatcherType.XML)
+        {
+            ret.pushNumericConstant(3);
+
+            XMLWatcherInfo xmlWatcherInfo = (XMLWatcherInfo)watcherInfoBase;
+            ret.addInstruction(OP_pushstring, xmlWatcherInfo.getPropertyName());
+            outputBindings(ret, xmlWatcherInfo.getBindings());
+            propertyCount += 3;
+        }
+        else assert false;     
+
+        // then recurse into children
+        Set<Entry<Object, WatcherInfoBase>> children = watcherInfoBase.getChildren();
+        if (children != null)
+        {
+            int childCount = 0;
+            for ( Entry<Object, WatcherInfoBase> ent : children)
+            {
+                childCount += encodeWatcher(ret, ent.getValue());
+            }
+            ret.addInstruction(OP_newarray, childCount);
+            propertyCount++;
+        }
+        else
+        {
+            ret.addInstruction(OP_pushnull);
+            propertyCount++;
+        }
+
+        return propertyCount;
+    }
+    
+    private String getSourceStringFromMemberAccessExpressionNode(MemberAccessExpressionNode node)
+    {
+        String s = "";
+        
+        IExpressionNode left = node.getLeftOperandNode();
+        if (left instanceof FunctionCallNode) //  probably a cast
+        {
+            IASNode child = ((FunctionCallNode)left).getArgumentsNode().getChild(0);
+            if (child instanceof IdentifierNode)
+                s = getSourceStringFromIdentifierNode((IdentifierNode)child);
+            else if (child instanceof MemberAccessExpressionNode)
+                s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
+        }
+        else if (left instanceof MemberAccessExpressionNode)
+            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)left);
+        else if (left instanceof IdentifierNode)
+            s = getSourceStringFromIdentifierNode((IdentifierNode)left);
+        else
+            System.out.println("expected binding member access left node" + node.toString());
+        s += ".";
+        
+        IExpressionNode right = node.getRightOperandNode();
+        if (right instanceof FunctionCallNode) //  probably a cast
+        {
+            IASNode child = ((FunctionCallNode)right).getArgumentsNode().getChild(0);
+            if (child instanceof IdentifierNode)
+                s += getSourceStringFromIdentifierNode((IdentifierNode)child);
+            else if (child instanceof MemberAccessExpressionNode)
+                s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)child);
+        }
+        else if (right instanceof MemberAccessExpressionNode)
+            s += getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)right);
+        else if (right instanceof IdentifierNode)
+            s += getSourceStringFromIdentifierNode((IdentifierNode)right);
+        else
+            System.out.println("expected binding member access right node" + node.toString());
+        
+        return s;
+    }
+    
+    private String getSourceStringFromIdentifierNode(IdentifierNode node)
+    {
+        return node.getName();
+    }
+    
+    private String getSourceStringFromGetter(List<IExpressionNode> nodes)
+    {
+        String s = "";
+        IExpressionNode node = nodes.get(0);
+        if (node instanceof MemberAccessExpressionNode)
+        {
+            s = getSourceStringFromMemberAccessExpressionNode((MemberAccessExpressionNode)node);
+        }
+        return s;
+    }
+    
+    private void outputEventNames(InstructionList ret, List<String> events)
+    {
+        if (events.size() > 1)
+        {
+            for (String event : events)
+                ret.addInstruction(OP_pushstring, event);
+            ret.addInstruction(OP_newarray, events.size());
+        }
+        else if (events.size() == 1)
+            ret.addInstruction(OP_pushstring, events.get(0));
+        else
+            ret.addInstruction(OP_pushnull);
+    }
+    
+    private void outputBindings(InstructionList ret, List<BindingInfo> bindings)
+    {
+        if (bindings.size() > 1)
+        {
+            for (BindingInfo binding : bindings)
+                ret.pushNumericConstant(binding.getIndex());
+            ret.addInstruction(OP_newarray, bindings.size());
+        }
+        else if (bindings.size() == 1)
+            ret.pushNumericConstant(bindings.get(0).getIndex());
+        else
+            ret.addInstruction(OP_pushnull);
+        
+    }
+    
     /**
      * Generates all the Binding objects, and and "getter" functions required to implement them
      * puts Binding into this._bindings

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/734f9bec/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
index ad04252..1c247f2 100644
--- a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
+++ b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProjectConfigurator.java
@@ -19,10 +19,17 @@
 
 package org.apache.flex.compiler.internal.projects;
 
+import static org.apache.flex.abc.ABCConstants.CONSTANT_PackageNs;
+import static org.apache.flex.abc.ABCConstants.CONSTANT_Qname;
+
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.flex.abc.semantics.Name;
+import org.apache.flex.abc.semantics.Namespace;
+import org.apache.flex.abc.semantics.Nsset;
 import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.internal.as.codegen.BindableHelper;
 import org.apache.flex.compiler.mxml.IMXMLTypeConstants;
 
 /**
@@ -170,5 +177,43 @@ public class FlexProjectConfigurator
         project.setRepeaterClass(IMXMLTypeConstants.Repeater);
         
         project.setNamedColors(NAMED_COLORS);
+        
+        if (configuration != null)
+        {
+            String configValue = configuration.getBindingEventHandlerEvent();
+            int dotIndex;
+            dotIndex = configValue.lastIndexOf(".");
+            String packageName = configValue.substring(0, dotIndex - 1);
+            String className = configValue.substring(dotIndex + 1);
+            BindableHelper.NAME_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
+            
+            configValue = configuration.getBindingEventHandlerClass();
+            dotIndex = configValue.lastIndexOf(".");
+            packageName = configValue.substring(0, dotIndex - 1);
+            className = configValue.substring(dotIndex + 1);
+            BindableHelper.NAME_EVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
+    
+            configValue = configuration.getBindingEventHandlerInterface();
+            dotIndex = configValue.lastIndexOf(".");
+            packageName = configValue.substring(0, dotIndex - 1);
+            className = configValue.substring(dotIndex + 1);
+            BindableHelper.NAME_IEVENT_DISPATCHER = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
+    
+            configValue = configuration.getBindingValueChangeEvent();
+            dotIndex = configValue.lastIndexOf(".");
+            packageName = configValue.substring(0, dotIndex - 1);
+            className = configValue.substring(dotIndex + 1);
+            BindableHelper.NAME_PROPERTY_CHANGE_EVENT = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
+            BindableHelper.NAMESPACE_MX_EVENTS = new Namespace(CONSTANT_PackageNs, packageName);
+            
+            configValue = configuration.getBindingValueChangeEventKind();
+            dotIndex = configValue.lastIndexOf(".");
+            packageName = configValue.substring(0, dotIndex - 1);
+            className = configValue.substring(dotIndex + 1);
+            BindableHelper.NAME_PROPERTY_CHANGE_EVENT_KIND = new Name(CONSTANT_Qname, new Nsset(new Namespace(CONSTANT_PackageNs, packageName)), className);
+        
+            configValue = configuration.getBindingValueChangeEventType();
+            BindableHelper.PROPERTY_CHANGE = configValue;
+        }
     }
 }