boolean isDeclared = self.isDeclared();
String id = isDeclared ? self.getId() : varName;
int line = getLineRef();
CodeFragmentList list = new CodeFragmentList();
// function header
list.add("private function ", getDefinitionName(), "() : ", selfTypeName, line);
list.add("{", line);
// value creation
StringBuilder stringBuilder = new StringBuilder("\tvar " + varName + " : " + selfTypeName + " = ");
if (modelHasInlineRValue())
{
stringBuilder.append(getInlineRValue());
}
else if (value instanceof Vector)
{
Vector vector = (Vector) value;
stringBuilder.append("new " + selfTypeName + "(" + vector.size());
if (vector.isFixed())
{
stringBuilder.append(", true)");
}
else
{
stringBuilder.append(")");
}
}
else
{
// TODO confirm the availability of a 0-arg ctor!! but do it upstream from here, like when Model is built
stringBuilder.append("new " + selfTypeName + "()");
}
stringBuilder.append(";");
list.add(stringBuilder.toString(), line);
if (!modelHasInlineRValue())
{
if (value instanceof Vector)
{
Vector vector = (Vector) value;
addAssignExprs(list, vector.getElementInitializerIterator(), varName);
}
else
{
// set properties
addAssignExprs(list, self.getPropertyInitializerIterator(self.getType().hasDynamic()), varName);
}
}
// set styles
addAssignExprs(list, self.getStyleInitializerIterator(), varName);
// set effects
addAssignExprs(list, self.getEffectInitializerIterator(), varName);
// add event handlers
addAssignExprs(list, self.getEventInitializerIterator(), varName);
// register effect names
String effectEventNames = self.getEffectNames();
if (effectEventNames.length() > 0)
{
list.add("\t", varName, ".registerEffects([ ", effectEventNames, " ]);", line);
}
// post-init actions for values that are being assigned to properties (via id attribution)
if (isDeclared && standardDefs.isIUIComponentWithIdProperty(selfType))
{
// set id on IUIComponents that carry an id prop
list.add("\t", varName, ".id = \"", id, "\";", line);
}
// Design layer related items
if (self.layerParent != null)
{
if (self instanceof DesignLayer)
{
list.add("\t", self.layerParent.getId(), ".addLayer(", varName, ");", line);
}
else if (self.getType().isAssignableTo(standardDefs.INTERFACE_IVISUALELEMENT))
{
list.add("\t", varName, ".designLayer = ", self.layerParent.getId(), ";", line);
}
}
// UIComponent-specific init steps
if (standardDefs.isIUIComponent(selfType))
{
assert self instanceof MovieClip : "isIUIComponent(selfType) but !(self instanceof MovieClip)";
MovieClip movieClip = (MovieClip) self;
// MXML implementations of IUIComponent initialize set their document property to themselves at
// construction time. Others need it set to the enclosing document (us).
list.add("\tif (!", varName, ".document) ", varName, ".document = this;", line);
// add visual children
if (!standardDefs.isRepeater(selfType))
{
if (standardDefs.isContainer(selfType))
{
if (movieClip.hasChildren())
{
list.add("\t", varName, ".mx_internal::_documentDescriptor = ", line);
DescriptorGenerator.addDescriptorInitializerFragments(list, movieClip,
Collections.<String>emptySet(),
false, "\t\t");
list.add("\t;", line);
list.add("\t", varName, ".mx_internal::_documentDescriptor.document = this;", line);
}
}
else
{
// non-repeater - replicate DI child-creation sequence procedurally:
Iterator childIter = movieClip.getChildInitializerIterator();
while (childIter.hasNext())
{
VisualChildInitializer init = (VisualChildInitializer)childIter.next();
// Filter out state specific children.
if ( !((Model)init.getValue()).isStateSpecific())
{
list.add("\t", init.getAssignExpr(varName), ";", init.getLineRef());
}
}
}
}
else
{
// repeater-specific init sequence: don't add children directly, instead use existing DI setup
// initializing repeater's childDescriptors property, for now
list.add("\tvar cd:Array = ", varName, ".childDescriptors = [", line);
for (Iterator childIter = movieClip.children().iterator(); childIter.hasNext(); )
{
VisualChildInitializer init = (VisualChildInitializer)childIter.next();
DescriptorGenerator.addDescriptorInitializerFragments(list, (MovieClip)init.getValue(), "\t\t");
if (childIter.hasNext())
{
list.add(",", 0);
}
}
list.add("\t];", line);
list.add("\tfor (var i:int = 0; i < cd.length; i++) cd[i].document = this;", line);
}
}
// TODO: Remove [IMXMLObject] metadata support once we have a
// non-framework dependent swc to link in mx.core.IMXMLObject
// call IMXMLObject.initialized() on implementors
if (self.getType().isAssignableTo(standardDefs.INTERFACE_IMXMLOBJECT)
|| self.getType().hasMetadata(StandardDefs.MD_IMXMLOBJECT, true))
{
String idParam = (isDeclared ? TextGen.quoteWord(id) : "null");
list.add("\t", varName, ".initialized(this, ", idParam, ")", line);
}
// generate idAssigned dispatching logic for user declared instances.
if (isDeclared)
{
if (self.getRepeaterLevel() == 0)
{
list.add("\t", id, " = ", varName, ";", line);
}
else
{
ThreadLocalToolkit.log(new DeclaredAndProceduralWithinRepeater(), self.getDocument().getSourcePath(), line);
}
// evaluate all property bindings for this object - i.e. initialize properties of the object whose values
// are binding expressions. E.g. if we've just created <mx:Foo id="bar" x="100" y="{baz.z}"/>, then
// we need to evaluate (baz.z) and assign it to bar.y. This explicit evaluation pass is necessary because
// baz may already have been initialized, although the fact that we do it even when that's not the case is
// suboptimal.
list.add("\t", NameFormatter.toDot(standardDefs.CLASS_BINDINGMANAGER),
".executeBindings(this, ", TextGen.quoteWord(id), ", " + id + ");", line);
}
// If this is a stateful Halo Container, with itemCreationPolicy "immediate" we need to ensure
// that the instance and all descendants are instantiated.
if (standardDefs.isContainer(selfType) && self.isEarlyInit())
{
list.add("\t", varName,".initialize();", line);
}
// return created value
list.add("\treturn ", varName, ";", line);
list.add("}", line);
Type lvalueType = getLValueType();
if (standardDefs.isITransientDeferredInstance(lvalueType) || self.getIsTransient())
list = getDestructorBody(list, line);