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/10/31 18:44:12 UTC
git commit: [flex-falcon] [refs/heads/develop] - changes to get
BasicTests to run with new MXML and Databinding codegen
Updated Branches:
refs/heads/develop b08d11d2f -> a5c3a4fee
changes to get BasicTests to run with new MXML and Databinding codegen
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/a5c3a4fe
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/a5c3a4fe
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/a5c3a4fe
Branch: refs/heads/develop
Commit: a5c3a4fee02461ab35d1d93c2c6f1f6eeeb65a30
Parents: b08d11d
Author: Alex Harui <ah...@apache.org>
Authored: Thu Oct 31 10:43:36 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Thu Oct 31 10:43:36 2013 -0700
----------------------------------------------------------------------
.../as/codegen/MXMLClassDirectiveProcessor.java | 451 +++++++++++++++----
.../databinding/BindingCodeGenUtils.java | 2 +-
.../databinding/MXMLBindingDirectiveHelper.java | 39 +-
.../compiler/internal/projects/FlexProject.java | 9 +-
.../internal/targets/FlexAppSWFTarget.java | 5 +
.../flex/compiler/mxml/IMXMLTypeConstants.java | 4 +
6 files changed, 421 insertions(+), 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/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 a868416..a344b32 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
@@ -20,6 +20,7 @@ package org.apache.flex.compiler.internal.as.codegen;
import static org.apache.flex.abc.ABCConstants.CONSTANT_Qname;
import static org.apache.flex.abc.ABCConstants.OP_applytype;
+import static org.apache.flex.abc.ABCConstants.OP_call;
import static org.apache.flex.abc.ABCConstants.OP_callproperty;
import static org.apache.flex.abc.ABCConstants.OP_callpropvoid;
import static org.apache.flex.abc.ABCConstants.OP_callsupervoid;
@@ -29,6 +30,7 @@ import static org.apache.flex.abc.ABCConstants.OP_constructsuper;
import static org.apache.flex.abc.ABCConstants.OP_dup;
import static org.apache.flex.abc.ABCConstants.OP_finddef;
import static org.apache.flex.abc.ABCConstants.OP_findpropstrict;
+import static org.apache.flex.abc.ABCConstants.OP_getglobalscope;
import static org.apache.flex.abc.ABCConstants.OP_getlex;
import static org.apache.flex.abc.ABCConstants.OP_getlocal0;
import static org.apache.flex.abc.ABCConstants.OP_getlocal1;
@@ -134,6 +136,7 @@ import org.apache.flex.compiler.definitions.references.IReference;
import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference;
import org.apache.flex.compiler.definitions.references.ReferenceFactory;
import org.apache.flex.compiler.exceptions.CodegenInterruptedException;
+import org.apache.flex.compiler.internal.abc.FunctionGeneratorHelper;
import org.apache.flex.compiler.internal.caches.CSSDocumentCache;
import org.apache.flex.compiler.internal.codegen.databinding.MXMLBindingDirectiveHelper;
import org.apache.flex.compiler.internal.css.codegen.CSSCompilationSession;
@@ -142,12 +145,14 @@ import org.apache.flex.compiler.internal.css.codegen.CSSEmitter;
import org.apache.flex.compiler.internal.definitions.ClassDefinition;
import org.apache.flex.compiler.internal.definitions.DefinitionBase;
import org.apache.flex.compiler.internal.definitions.EventDefinition;
+import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
import org.apache.flex.compiler.internal.definitions.NamespaceDefinition;
import org.apache.flex.compiler.internal.definitions.TypeDefinitionBase;
import org.apache.flex.compiler.internal.projects.FlexProject;
import org.apache.flex.compiler.internal.resourcebundles.ResourceBundleUtils;
import org.apache.flex.compiler.internal.scopes.ASProjectScope;
import org.apache.flex.compiler.internal.scopes.ASScope;
+import org.apache.flex.compiler.internal.semantics.SemanticUtils;
import org.apache.flex.compiler.internal.tree.as.NodeBase;
import org.apache.flex.compiler.internal.tree.as.VariableNode;
import org.apache.flex.compiler.mxml.IMXMLLanguageConstants;
@@ -264,6 +269,18 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
private static final String EVENT_HANDLER_NAME_BASE = ">";
/**
+ * Autogenerated vector generator methods are named >v0, >v1, etc.
+ * Using short names, and using the same names in each MXML document,
+ * decreases SWF size.
+ * Using a character that is not legal in ActionScript identifiers
+ * means that even if the event handler must be public
+ * (because it is referenced in a descriptor)
+ * the name will not collide with the name of a developer-written
+ * method and cannot be accessed from developer code.
+ */
+ private static final String VECTOR_GENERATOR_NAME_BASE = ">v";
+
+ /**
* Autogenerated instance initialization methods are named i0, i1, etc.
*/
private static final String INSTANCE_INITIALIZER_NAME_BASE = "i";
@@ -371,6 +388,42 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
/**
* Creates a MethodInfo describing the signature for an autogenerated
+ * vector generator method.
+ * @param vectorNode - a node, which is used to determine
+ * the type of the 'vector'.
+ * @param handlerName - the name for the autogenerated event handler method.
+ * @return The MethodInfo specifying the signature of the vector generator method.
+ */
+ public static MethodInfo createVectorGeneratorMethodInfo(ICompilerProject project,
+ IMXMLVectorNode vectorNode,
+ String handlerName)
+ {
+ MethodInfo mi = new MethodInfo();
+
+ mi.setMethodName(handlerName);
+
+ ITypeDefinition type = vectorNode.getType();
+ Name typeName = ((TypeDefinitionBase)type).getMName(project);
+
+ Vector<Name> paramTypes = new Vector<Name>();
+ paramTypes.add(IMXMLTypeConstants.NAME_ARRAY);
+ mi.setParamTypes(paramTypes);
+
+ Vector<String> paramName = new Vector<String>();
+ paramName.add("array");
+ mi.setParamNames(paramName);
+
+ // TODO: Allow these MXML nodes to use registers.
+ mi.setFlags(mi.getFlags() | ABCConstants.NEED_ACTIVATION);
+
+ // Event handlers return void.
+ mi.setReturnType(typeName);
+
+ return mi;
+ }
+
+ /**
+ * Creates a MethodInfo describing the signature for an autogenerated
* MXML instance initializer corresponding to an MXMLInstanceNode.
* Instance initializers have no parameters, and their return type
* is the type of the instance that they create.
@@ -424,6 +477,12 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
private int eventHandlerCounter = 0;
/**
+ * An incrementing counter used to create the names of the
+ * auto-generated vector generator methods.
+ */
+ private int vectorGeneratorCounter = 0;
+
+ /**
* We delegate much of the work for databindings down to this guy
*/
private final MXMLBindingDirectiveHelper bindingDirectiveHelper = new MXMLBindingDirectiveHelper(this, emitter);
@@ -470,6 +529,21 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
new HashMap<IMXMLEventSpecifierNode, Name>();
/**
+ * A Map mapping an vector type to the Name of the vector "generator"
+ * method (>v0, >v1, etc.) associated with that node.
+ * <p>
+ * The handler method may or may not exist at the time
+ * that the handler name is assigned to the event node.
+ * For example, when a State tag appears before
+ * an instance tag with a state-dependent event,
+ * the name will get assigned and the code generated later.
+ * <p>
+ * This map is managed ONLY by getVectorGeneratorName().
+ */
+ private final Map<Name, Name> VectorGeneratorMap =
+ new HashMap<Name, Name>();
+
+ /**
* This flag keeps track of whether there were styles
* specified on the class definition tag.
* <p>
@@ -660,6 +734,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
Context stateContext = new Context((IMXMLInstanceNode)node, il);
stateContext.isContentFactory = true;
processNode(node, stateContext);
+ stateContext.transfer(IL.MXML_CONTENT_FACTORY);
stateContext.addInstruction(OP_newarray, stateContext.getCounter(IL.MXML_CONTENT_FACTORY));
}
else
@@ -1109,7 +1184,21 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
// call the Binding helper to get all the data binding setup code
addBindingCodeForCtor(ctor_insns);
-
+
+ // add call to MXMLAttributes
+ if (getProject().getTargetSettings().getMxmlChildrenAsData())
+ {
+ // generateMXMLAttributes(attributes);
+ FunctionDefinition funcDef = (FunctionDefinition)SemanticUtils.findProperty(classDefinition.getContainedScope(),
+ "generateMXMLAttributes",
+ getProject(), false);
+ Name funcName = ((FunctionDefinition)funcDef).getMName(getProject());
+ ctor_insns.addInstruction(OP_getlocal0);
+ ctor_insns.addInstruction(OP_findpropstrict, NAME_MXML_PROPERTIES_GETTER);
+ ctor_insns.addInstruction(OP_getproperty, NAME_MXML_PROPERTIES_GETTER);
+ ctor_insns.addInstruction(OP_callpropvoid, new Object[] {funcName, 1 });
+ }
+
ctor_insns.addInstruction(OP_returnvoid);
mbv.visit();
@@ -2035,6 +2124,33 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
}
/**
+ * Determines the Name of the event handler method for an event node.
+ * This can get called to preassign the name before the method gets generated.
+ */
+ public Name getVectorGeneratorName(Name typeName)
+ {
+ // Check the map to see if a handler name
+ // has already been assigned to this event node.
+ Name name = VectorGeneratorMap.get(typeName);
+
+ // If so, return it.
+ if (name != null)
+ return name;
+
+ // Otherwise, generate the next one in the sequence ">v1", ">v1", etc.
+ String baseName = VECTOR_GENERATOR_NAME_BASE + vectorGeneratorCounter++;
+
+ // Either make the Name public or put it in the special
+ // private namespace for APIs that are autogenerated.
+ name = createMXMLPrivateName(baseName);
+
+ // Remember it in the map.
+ VectorGeneratorMap.put(typeName, name);
+
+ return name;
+ }
+
+ /**
* Determines whether a node is state-dependent.
* TODO: we should move to IMXMLNode
*/
@@ -2273,7 +2389,8 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
// try to determine if this is the children of an MX Container
boolean isMXMLDisplayObjectChild = node.getNodeID() == ASTNodeID.MXMLInstanceID &&
- node.getParent().getNodeID() == ASTNodeID.MXMLInstanceID;
+ (node.getParent().getNodeID() == ASTNodeID.MXMLInstanceID ||
+ node.getParent().getNodeID() == ASTNodeID.MXMLDocumentID);
if (isMXMLDisplayObjectChild)
{
// if it is, build up the children in this instruction list
@@ -2501,8 +2618,10 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
return n == null || isDataBindingNode(n);
}
- boolean isChildrenAsDataCodeGen(IMXMLExpressionNode node)
+ boolean isChildrenAsDataCodeGen(IMXMLExpressionNode node, Context context)
{
+ if (context.parentContext.makingSimpleArray) return false;
+
return (getProject().getTargetSettings().getMxmlChildrenAsData() &&
(node.getParent().getNodeID() == ASTNodeID.MXMLPropertySpecifierID ||
node.getParent().getNodeID() == ASTNodeID.MXMLStyleSpecifierID));
@@ -2517,7 +2636,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLBoolean(IMXMLBooleanNode booleanNode, Context context)
{
- if (isChildrenAsDataCodeGen(booleanNode))
+ if (isChildrenAsDataCodeGen(booleanNode, context))
context.addInstruction(OP_pushtrue); // simple type
boolean value = isDataBound(booleanNode) ? false : booleanNode.getValue();
@@ -2535,7 +2654,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLInt(IMXMLIntNode intNode, Context context)
{
- if (isChildrenAsDataCodeGen(intNode))
+ if (isChildrenAsDataCodeGen(intNode, context))
context.addInstruction(OP_pushtrue); // simple type
int value = isDataBound(intNode) ? 0 : intNode.getValue();
@@ -2552,7 +2671,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLUint(IMXMLUintNode uintNode, Context context)
{
- if (isChildrenAsDataCodeGen(uintNode))
+ if (isChildrenAsDataCodeGen(uintNode, context))
context.addInstruction(OP_pushtrue); // simple type
long value = isDataBound(uintNode) ? 0 : uintNode.getValue();
@@ -2569,7 +2688,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLNumber(IMXMLNumberNode numberNode, Context context)
{
- if (isChildrenAsDataCodeGen(numberNode))
+ if (isChildrenAsDataCodeGen(numberNode, context))
context.addInstruction(OP_pushtrue); // simple type
double value = isDataBound(numberNode) ? Double.NaN : numberNode.getValue();
@@ -2586,7 +2705,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLString(IMXMLStringNode stringNode, Context context)
{
- if (isChildrenAsDataCodeGen(stringNode))
+ if (isChildrenAsDataCodeGen(stringNode, context))
context.addInstruction(OP_pushtrue); // simple type
String value = isDataBound(stringNode) ? null : stringNode.getValue();
@@ -2612,7 +2731,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
if (isDataBindingNode(classNode))
return;
- if (isChildrenAsDataCodeGen(classNode))
+ if (isChildrenAsDataCodeGen(classNode, context))
context.addInstruction(OP_pushtrue); // simple type
IExpressionNode expressionNode = (IExpressionNode)classNode.getExpressionNode();
@@ -2643,7 +2762,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
if (isDataBindingNode(functionNode))
return;
- if (isChildrenAsDataCodeGen(functionNode))
+ if (isChildrenAsDataCodeGen(functionNode, context))
context.addInstruction(OP_pushtrue); // simple type
IExpressionNode expressionNode = (IExpressionNode)functionNode.getExpressionNode();
@@ -2732,9 +2851,12 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
emitDesignLayerInstance(node, designLayerInstanceContext);
endContext(node, designLayerInstanceContext, context);
- // The DesignLayer object will not be added to the parent object, so it
- // need to be removed from the stack.
- context.mainInstructionList.addInstruction(ABCConstants.OP_pop);
+ if (!getProject().getTargetSettings().getMxmlChildrenAsData())
+ {
+ // The DesignLayer object will not be added to the parent object, so it
+ // need to be removed from the stack.
+ context.mainInstructionList.addInstruction(ABCConstants.OP_pop);
+ }
}
/**
@@ -2763,31 +2885,49 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
private void emitDesignLayerInstance(IMXMLDesignLayerNode node, Context context)
{
+ boolean newCodeGen = getProject().getTargetSettings().getMxmlChildrenAsData();
+
traverse(node, context, MXML_SPECIFIER_NODES);
// Construct DesignLayer instance in the context's mainInstructionList.
final Name instanceClassName = context.instanceClassName;
context.addInstruction(OP_findpropstrict, instanceClassName);
context.addInstruction(OP_constructprop, new Object[] {instanceClassName, 0});
- setSpecifiers(context);
- callInitialized(node, context);
-
- for (int i = 0; i < node.getChildCount(); i++)
+ int numElements = setSpecifiers(context, newCodeGen, false);
+ numElements++; // for pushing the class
+ if (!newCodeGen)
{
- final IASNode child = node.getChild(i);
- if (child instanceof IMXMLDesignLayerNode)
+ callInitialized(node, context);
+
+ for (int i = 0; i < node.getChildCount(); i++)
{
- // Call temp.addLayer(child) if there's a DesignLayer node in the direct children.
- final IMXMLDesignLayerNode designLayerChildNode = (IMXMLDesignLayerNode)child;
- if (!designLayerChildNode.skipCodeGeneration())
- callAddLayer(node, context, designLayerChildNode);
+ final IASNode child = node.getChild(i);
+ if (child instanceof IMXMLDesignLayerNode)
+ {
+ // Call temp.addLayer(child) if there's a DesignLayer node in the direct children.
+ final IMXMLDesignLayerNode designLayerChildNode = (IMXMLDesignLayerNode)child;
+ if (!designLayerChildNode.skipCodeGeneration())
+ callAddLayer(node, context, designLayerChildNode);
+ }
+ else if (child instanceof IMXMLInstanceNode)
+ {
+ // Set directInstanceChild.designLayer = designLayer.
+ final IMXMLInstanceNode instanceChildNode = (IMXMLInstanceNode)child;
+ setDesignLayer(node, context, instanceChildNode);
+ }
}
- else if (child instanceof IMXMLInstanceNode)
+ }
+ else
+ {
+ if (context.parentContext.isContentFactory)
+ context.parentContext.incrementCounter(IL.MXML_CONTENT_FACTORY, numElements);
+ else if (!context.parentContext.isContentFactory)
{
- // Set directInstanceChild.designLayer = designLayer.
- final IMXMLInstanceNode instanceChildNode = (IMXMLInstanceNode)child;
- setDesignLayer(node, context, instanceChildNode);
- }
+ if (context.parentContext.makingArrayValues)
+ context.parentContext.numArrayValues += numElements;
+ else
+ context.addInstruction(OP_newarray, numElements); // if not in content factory, create the array now
+ }
}
}
@@ -2840,12 +2980,47 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLObject(IMXMLObjectNode objectNode, Context context)
{
+ boolean newCodeGen = getProject().getTargetSettings().getMxmlChildrenAsData();
+
+ context.makingSimpleArray = context.parentContext.makingSimpleArray;
+
+ if (newCodeGen && !context.makingSimpleArray)
+ {
+ context.addInstruction(OP_findpropstrict, IMXMLTypeConstants.NAME_OBJECT);
+ context.addInstruction(OP_getproperty, IMXMLTypeConstants.NAME_OBJECT);
+ }
traverse(objectNode, context);
+ int numElements = context.getCounter(IL.PROPERTIES);
+ if (newCodeGen && !context.makingSimpleArray)
+ context.pushNumericConstant(numElements);
context.transfer(IL.PROPERTIES);
- int n = objectNode.getChildCount();
- context.addInstruction(OP_newobject, n);
+ if (!newCodeGen || context.makingSimpleArray)
+ {
+ int n = objectNode.getChildCount();
+ context.addInstruction(OP_newobject, n);
+ }
+ else
+ {
+ context.pushNumericConstant(context.getCounter(IL.STYLES));
+ context.pushNumericConstant(context.getCounter(IL.EFFECT_STYLES));
+ context.pushNumericConstant(context.getCounter(IL.EVENTS));
+ context.addInstruction(OP_pushnull); // no children
+ numElements *= 3; // 3 entries per property
+ numElements += 6;
+
+ if (context.parentContext.isContentFactory)
+ context.parentContext.incrementCounter(IL.MXML_CONTENT_FACTORY, numElements);
+ else if (!context.parentContext.isContentFactory)
+ {
+ if (context.parentContext.makingArrayValues)
+ context.parentContext.numArrayValues += numElements;
+ else
+ context.addInstruction(OP_newarray, numElements); // if not in content factory, create the array now
+ }
+
+ }
}
/**
@@ -2868,16 +3043,15 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLArray(IMXMLArrayNode arrayNode, Context context)
{
+ boolean isSimple = true;
if (getProject().getTargetSettings().getMxmlChildrenAsData())
{
if (!context.isContentFactory)
{
if (context.parentContext.isStateDescriptor)
context.addInstruction(OP_pushnull); // array of descriptors
- else
- {
- boolean isSimple = true;
-
+ else if (!context.parentContext.makingSimpleArray)
+ {
for (int i = 0; i < arrayNode.getChildCount(); i++)
{
final IASNode child = arrayNode.getChild(i);
@@ -2889,6 +3063,7 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
}
}
context.makingArrayValues = true;
+ context.makingSimpleArray = isSimple;
context.addInstruction(isSimple ? OP_pushtrue : OP_pushnull); // arrays are simple values
}
}
@@ -2929,7 +3104,10 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
}
else if (context.makingArrayValues)
{
- context.addInstruction(OP_newarray, context.numArrayValues);
+ if (isSimple)
+ context.addInstruction(OP_newarray, nMax);
+ else
+ context.addInstruction(OP_newarray, context.numArrayValues);
return;
}
}
@@ -2988,6 +3166,47 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
/**
* Generates instructions in the current context
+ * to set an event handler specified by an {@code IMXMLEventSpecifierNode}.
+ * <p>
+ * This is accomplished by generating a call to <code>addEventListener()</code>
+ * on the target.
+ */
+ Name generateVectorGenerator(Name typeName, IMXMLVectorNode vectorNode)
+ {
+ // Event nodes (including state-dependent ones)
+ // generate a new event handler method.
+ // Create a MethodInfo and a method trait for the handler.
+ Name name = getVectorGeneratorName(typeName);
+ MethodInfo methodInfo = createVectorGeneratorMethodInfo(
+ getProject(), vectorNode, name.getBaseName());
+ addMethodTrait(name, methodInfo, false);
+
+ ICompilerProject project = getProject();
+ ASProjectScope projectScope = (ASProjectScope)project.getScope();
+ IDefinition vectorDef = projectScope.findDefinitionByName(IASLanguageConstants.Vector_qname);
+ Name vectorName = ((ClassDefinition)vectorDef).getMName(project);
+
+ InstructionList generatorFunctionBody = new InstructionList();
+ generatorFunctionBody.addInstruction(OP_getlocal0);
+ generatorFunctionBody.addInstruction(OP_pushscope);
+ // Synthesize the class Vector.<T>.
+ generatorFunctionBody.addInstruction(OP_getlex, vectorName);
+ generatorFunctionBody.addInstruction(OP_getlex, typeName);
+ generatorFunctionBody.addInstruction(OP_applytype, 1);
+ generatorFunctionBody.addInstruction(OP_getglobalscope);
+ generatorFunctionBody.addInstruction(OP_getlocal1);
+ generatorFunctionBody.addInstruction(OP_call, 1);
+ generatorFunctionBody.addInstruction(OP_returnvalue);
+
+
+ // now generate the function
+ FunctionGeneratorHelper.generateFunction(emitter, methodInfo, generatorFunctionBody);
+
+ return name;
+ }
+
+ /**
+ * Generates instructions in the current context
* to push the value of an {@code IMXMLVectorNode}.
* <p>
* First this method creates the synthetic Vector.<T> type
@@ -3011,6 +3230,9 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
*/
void processMXMLVector(IMXMLVectorNode vectorNode, Context context)
{
+ if (getProject().getTargetSettings().getMxmlChildrenAsData())
+ context.addInstruction(OP_pushundefined); // vector type
+
ICompilerProject project = getProject();
int n = vectorNode.getChildCount();
ITypeDefinition type = vectorNode.getType();
@@ -3025,38 +3247,64 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
Nsset nsSet = new Nsset(new Namespace(ABCConstants.CONSTANT_PackageNs));
Name indexName = new Name(ABCConstants.CONSTANT_MultinameL, nsSet, null);
- // Synthesize the class Vector.<T>.
- context.addInstruction(OP_getlex, vectorName);
- context.addInstruction(OP_getlex, typeName);
- context.addInstruction(OP_applytype, 1);
-
- // Call the Vector.<T> constructor with 1 or two arguments.
- // The first is the number of elements.
- // The second is 'fixed', which defaults to false.
- context.pushNumericConstant(n);
- if (fixed)
- context.addInstruction(OP_pushtrue);
- context.addInstruction(OP_construct, fixed ? 2 : 1);
-
- // Set each element of the vector.
- for (int i = 0; i < n; i++)
+ if (getProject().getTargetSettings().getMxmlChildrenAsData())
{
- // Push the vector instance whose element we're setting.
- context.addInstruction(OP_dup);
-
- // Push the index of the element we're setting.
- context.pushNumericConstant(i);
+ context.addInstruction(OP_getlex, typeName); // push the type so decoders have a hint
+ Name vectorGenerator = generateVectorGenerator(typeName, vectorNode);
+ context.addInstruction(OP_getlocal0);
+ context.addInstruction(OP_getproperty, vectorGenerator);
- // Push the value of the element we're setting.
- // Note: Here we call processNode() on each child,
- // rather than calling traverse(), because we need to emit
- // code before and after each element value push.
- IMXMLInstanceNode elementNode = (IMXMLInstanceNode)vectorNode.getChild(i);
- processNode(elementNode, context);
+ context.makingArrayValues = true;
+ // Set each element of the vector.
+ for (int i = 0; i < n; i++)
+ {
+ // Push the value of the element we're setting.
+ // Note: Here we call processNode() on each child,
+ // rather than calling traverse(), because we need to emit
+ // code before and after each element value push.
+ IMXMLInstanceNode elementNode = (IMXMLInstanceNode)vectorNode.getChild(i);
+ processNode(elementNode, context);
+
+ }
+ // the type hint and conversion function add 2
+ context.addInstruction(OP_newarray, context.numArrayValues + 2);
+ context.makingArrayValues = false;
+ }
+ else
+ {
+ // Synthesize the class Vector.<T>.
+ context.addInstruction(OP_getlex, vectorName);
+ context.addInstruction(OP_getlex, typeName);
+ context.addInstruction(OP_applytype, 1);
- // Set the element to the value.
- // This will pop the previous three values.
- context.addInstruction(OP_setproperty, indexName);
+ // Call the Vector.<T> constructor with 1 or two arguments.
+ // The first is the number of elements.
+ // The second is 'fixed', which defaults to false.
+ context.pushNumericConstant(n);
+ if (fixed)
+ context.addInstruction(OP_pushtrue);
+ context.addInstruction(OP_construct, fixed ? 2 : 1);
+
+ // Set each element of the vector.
+ for (int i = 0; i < n; i++)
+ {
+ // Push the vector instance whose element we're setting.
+ context.addInstruction(OP_dup);
+
+ // Push the index of the element we're setting.
+ context.pushNumericConstant(i);
+
+ // Push the value of the element we're setting.
+ // Note: Here we call processNode() on each child,
+ // rather than calling traverse(), because we need to emit
+ // code before and after each element value push.
+ IMXMLInstanceNode elementNode = (IMXMLInstanceNode)vectorNode.getChild(i);
+ processNode(elementNode, context);
+
+ // Set the element to the value.
+ // This will pop the previous three values.
+ context.addInstruction(OP_setproperty, indexName);
+ }
}
}
@@ -3129,7 +3377,9 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
// if not in content factory, create the array now
// this is for an ArrayList as the dataProvider
- setDocument(instanceNode, false, context);
+ // AJH: maybe we shouldn't call setDocument at all
+ if (!getProject().getTargetSettings().getMxmlChildrenAsData())
+ setDocument(instanceNode, false, context);
// Sets the id property if the instance
// implements IDeferredInstantiationUIComponent.
@@ -3563,9 +3813,11 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
if (styleNode.getParent() instanceof IMXMLClassDefinitionNode)
{
context.startUsing(IL.MODULE_FACTORY_STYLES);
+ context.makingSimpleArray = true;
setFactoryStyle(styleNode, context);
+ context.makingSimpleArray = false;
context.stopUsing(IL.MODULE_FACTORY_STYLES, 1);
hasStyleSpecifiers = true;
@@ -3573,11 +3825,32 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
else if (generateDescriptorCode(styleNode, context))
{
- context.startUsing(IL.DESCRIPTOR_STYLES);
-
- setFactoryStyle(styleNode, context);
-
- context.stopUsing(IL.DESCRIPTOR_STYLES, 1);
+ if (!getProject().getTargetSettings().getMxmlChildrenAsData())
+ {
+ context.startUsing(IL.DESCRIPTOR_STYLES);
+
+ setFactoryStyle(styleNode, context);
+
+ context.stopUsing(IL.DESCRIPTOR_STYLES, 1);
+ }
+ else
+ {
+ context.startUsing(IL.STYLES);
+
+ String styleName = styleNode.getName();
+
+ // Push the first argument: the name of the style.
+ context.addInstruction(OP_pushstring, styleName);
+
+ context.isContentFactory = false;
+
+ // Push the second argument: the value of the style.
+ // Do this by codegen'ing sole child, which is an IMXMLInstanceNode.
+ traverse(styleNode, context);
+
+ context.stopUsing(IL.STYLES, 1);
+
+ }
}
else if (generateNonDescriptorCode(styleNode, context))
@@ -3739,13 +4012,29 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
if (generateDescriptorCode(eventNode, context))
{
- context.startUsing(IL.DESCRIPTOR_EVENTS);
-
- context.addInstruction(OP_pushstring, eventName);
-
- context.addInstruction(OP_pushstring, eventHandler.getBaseName());
-
- context.stopUsing(IL.DESCRIPTOR_EVENTS, 1);
+ if (getProject().getTargetSettings().getMxmlChildrenAsData())
+ {
+ context.startUsing(IL.EVENTS);
+
+ // Push the first argument: the name of the event (e.g., "click").
+ context.addInstruction(OP_pushstring, eventName);
+
+ // Push the second argument: the handler reference (e.g., >0).
+ context.addInstruction(OP_getlocal0);
+ context.addInstruction(OP_getproperty, eventHandler);
+
+ context.stopUsing(IL.EVENTS, 1);
+ }
+ else
+ {
+ context.startUsing(IL.DESCRIPTOR_EVENTS);
+
+ context.addInstruction(OP_pushstring, eventName);
+
+ context.addInstruction(OP_pushstring, eventHandler.getBaseName());
+
+ context.stopUsing(IL.DESCRIPTOR_EVENTS, 1);
+ }
}
if (generateNonDescriptorCode(eventNode, context))
@@ -5010,6 +5299,14 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
boolean hasBeads;
/**
+ * This flag is true when setting styles
+ * in a style factory or making other
+ * simple arrays that don't have instances
+ * as values.
+ */
+ boolean makingSimpleArray;
+
+ /**
* This flag is true when setting values
* in an array (other than contextFactory)
*/
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingCodeGenUtils.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingCodeGenUtils.java b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingCodeGenUtils.java
index 7b27329..296a81b 100644
--- a/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingCodeGenUtils.java
+++ b/compiler/src/org/apache/flex/compiler/internal/codegen/databinding/BindingCodeGenUtils.java
@@ -450,7 +450,7 @@ public class BindingCodeGenUtils
// version 2: just throw
- private static void makeParameterFunction(IABCVisitor emitter, InstructionList ret, IExpressionNode[] params)
+ public static void makeParameterFunction(IABCVisitor emitter, InstructionList ret, IExpressionNode[] params)
{
//----------- step 1: build up a method info for the function
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/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 1054c40..7d7d41d 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
@@ -40,11 +40,13 @@ 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.targets.FlexAppSWFTarget;
import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAsNode;
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.targets.ISWFTarget;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.mxml.IMXMLBindingNode;
@@ -149,13 +151,24 @@ public class MXMLBindingDirectiveHelper
// Just comment it out before checking
//System.out.println("db: " + bindingDataBase);
+ boolean isFlexSDK = false;
+ ISWFTarget target = host.getProject().getSWFTarget();
+ if (target instanceof FlexAppSWFTarget)
+ {
+ if (!((FlexAppSWFTarget)target).isFlexInfo())
+ {
+ makeSpecialMemberVariablesForBinding();
+ isFlexSDK = true;
+ }
+ else
+ host.addVariableTrait(IMXMLTypeConstants.NAME_BINDINGS, NAME_ARRAYTYPE);
+ }
+
if (host.getProject().getTargetSettings().getMxmlChildrenAsData())
- return outputBindingInfoAsData();
+ return outputBindingInfoAsData(isFlexSDK);
InstructionList ret = new InstructionList();
-
- makeSpecialMemberVariablesForBinding();
-
+
makePropertyGetterIfNeeded();
ret.addAll(makeBindingsAndGetters());
@@ -167,10 +180,9 @@ public class MXMLBindingDirectiveHelper
return ret;
}
- private InstructionList outputBindingInfoAsData()
+ private InstructionList outputBindingInfoAsData(boolean isFlexSDK)
{
System.out.println("outputBindingInfoAsData");
- host.addVariableTrait(IMXMLTypeConstants.NAME_BINDINGS, NAME_ARRAYTYPE);
InstructionList ret = new InstructionList();
int propertyCount = 0;
@@ -185,14 +197,14 @@ public class MXMLBindingDirectiveHelper
s = bi.getSourceString();
if (s == null)
s = getSourceStringFromGetter(bi.getExpressionNodesForGetter());
- if (s.contains("."))
+ if (s.contains(".") && !isFlexSDK)
{
String[] parts = s.split("\\.");
for (String part : parts)
ret.addInstruction(OP_pushstring, part);
ret.addInstruction(OP_newarray, parts.length);
}
- else if (s == null || s.length() == 0)
+ else if (s == null || s.length() == 0 || isFlexSDK)
{
BindingCodeGenUtils.generateGetter(emitter, ret, bi.getExpressionNodesForGetter(), host.getInstanceScope());
}
@@ -231,6 +243,12 @@ public class MXMLBindingDirectiveHelper
ret.addInstruction(OP_swap);
// stack : bindings, this
ret.addInstruction(OP_setproperty, IMXMLTypeConstants.NAME_BINDINGS);
+
+ if (isFlexSDK)
+ {
+ ret.addInstruction(OP_getlocal0);
+ ret.addInstruction(OP_callpropvoid, IMXMLTypeConstants.ARG_SETUPBINDINGS);
+ }
return ret;
}
@@ -247,9 +265,12 @@ public class MXMLBindingDirectiveHelper
FunctionWatcherInfo functionWatcherInfo = (FunctionWatcherInfo)watcherInfoBase;
ret.addInstruction(OP_pushstring, functionWatcherInfo.getFunctionName());
+ InstructionList paramFunction = new InstructionList();
+ BindingCodeGenUtils.makeParameterFunction(emitter, paramFunction, functionWatcherInfo.params);
+ ret.addAll(paramFunction);
outputEventNames(ret, functionWatcherInfo.getEventNames());
outputBindings(ret, functionWatcherInfo.getBindings());
- propertyCount += 4;
+ propertyCount += 5;
}
else if ((type == WatcherType.STATIC_PROPERTY) || (type == WatcherType.PROPERTY))
{
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
index 2b525b9..69f0bff 100644
--- a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
+++ b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java
@@ -508,13 +508,18 @@ public class FlexProject extends ASProject implements IFlexProject
targetSettings = value;
}
+ private ISWFTarget target;
+
+ public ISWFTarget getSWFTarget()
+ {
+ return target;
+ }
+
@Override
public ISWFTarget createSWFTarget(ITargetSettings targetSettings, ITargetProgressMonitor progressMonitor) throws InterruptedException
{
this.targetSettings = targetSettings;
- ISWFTarget target;
-
if (isFlex())
{
String rootClassName = targetSettings.getRootClassName();
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/compiler/src/org/apache/flex/compiler/internal/targets/FlexAppSWFTarget.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/targets/FlexAppSWFTarget.java b/compiler/src/org/apache/flex/compiler/internal/targets/FlexAppSWFTarget.java
index e1993ef..8a2afeb 100644
--- a/compiler/src/org/apache/flex/compiler/internal/targets/FlexAppSWFTarget.java
+++ b/compiler/src/org/apache/flex/compiler/internal/targets/FlexAppSWFTarget.java
@@ -127,6 +127,11 @@ public class FlexAppSWFTarget extends AppSWFTarget
private final FlexProject flexProject;
+ public boolean isFlexInfo()
+ {
+ return getDelegate().isFlexInfo(getRootClassDefinition());
+ }
+
private FlexDelegate delegate;
private FlexDelegate getDelegate()
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c3a4fe/compiler/src/org/apache/flex/compiler/mxml/IMXMLTypeConstants.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/mxml/IMXMLTypeConstants.java b/compiler/src/org/apache/flex/compiler/mxml/IMXMLTypeConstants.java
index 59b7203..a93bf9b 100644
--- a/compiler/src/org/apache/flex/compiler/mxml/IMXMLTypeConstants.java
+++ b/compiler/src/org/apache/flex/compiler/mxml/IMXMLTypeConstants.java
@@ -175,10 +175,13 @@ public interface IMXMLTypeConstants
// I can't get Flex to work when I use attempt to use mx_internal
// It almost works, but something in the M7 test app doens't quite work...
+ // AJH: 10/30/13 BindingManager is using hasOwnProperty(_bindingsByDestination)
+ // which I don't think works with mx_internal
//public final Name NAME_WATCHERS = new Name (NAMESPACE_MX_INTERNAL,"_watchers"); // member variable of component with bindings
//public final Name NAME_BINDINGS = new Name (NAMESPACE_MX_INTERNAL,"_bindings"); // member variable of component with bindings
//public final Name NAME_BINDINGSBYDESTINATION = new Name(NAMESPACE_MX_INTERNAL,"_bindingsByDestination"); // member variable of component with bindings
//public final Name NAME_BINDINGSBEGINWITHWORD = new Name(NAMESPACE_MX_INTERNAL,"_bindingsBeginWithWord"); // member variable of component with bindings
+ public final Name NAME_SETUPBINDINGS = new Name(NAMESPACE_MX_INTERNAL,"setupBindings"); // member function of component with bindings
public final Name NAME_WATCHERS = new Name("_watchers"); // member variable of component with bindings
public final Name NAME_BINDINGS = new Name("_bindings"); // member variable of component with bindings
@@ -193,6 +196,7 @@ public interface IMXMLTypeConstants
new Name("updateParent"), 1};
public final Object[] ARG_ADDCHILD = new Object[] {new Name("addChild"), 1};
public final Object[] ARG_EXECUTE = new Object[] {NAME_EXECUTE, 0};
+ public final Object[] ARG_SETUPBINDINGS = new Object[] {NAME_SETUPBINDINGS, 0};
// this is a "Name" to use for the property "array index"
public final Name NAME_ARRAYINDEXPROP = new Name(ABCConstants.CONSTANT_MultinameL, new Nsset(new Namespace(CONSTANT_PackageNs)), null);