void InitMethod (ControlBuilder builder, bool isTemplate, bool childrenAsProperties)
{
currentLocation = builder.Location;
bool inBuildControlTree = builder is RootBuilder;
string tailname = (inBuildControlTree ? "Tree" : ("_" + builder.ID));
// bool isProperty = builder.IsProperty;
CodeMemberMethod method = new CodeMemberMethod ();
builder.Method = method;
builder.MethodStatements = method.Statements;
method.Name = "__BuildControl" + tailname;
method.Attributes = MemberAttributes.Private | MemberAttributes.Final;
Type type = builder.ControlType;
/* in the case this is the __BuildControlTree
* method, allow subclasses to insert control
* specific code. */
if (inBuildControlTree) {
SetCustomAttributes (method);
AddStatementsToInitMethodTop (builder, method);
}
if (builder.HasAspCode) {
CodeMemberMethod renderMethod = new CodeMemberMethod ();
builder.RenderMethod = renderMethod;
renderMethod.Name = "__Render" + tailname;
renderMethod.Attributes = MemberAttributes.Private | MemberAttributes.Final;
CodeParameterDeclarationExpression arg1 = new CodeParameterDeclarationExpression ();
arg1.Type = new CodeTypeReference (typeof (HtmlTextWriter));
arg1.Name = "__output";
CodeParameterDeclarationExpression arg2 = new CodeParameterDeclarationExpression ();
arg2.Type = new CodeTypeReference (typeof (Control));
arg2.Name = "parameterContainer";
renderMethod.Parameters.Add (arg1);
renderMethod.Parameters.Add (arg2);
mainClass.Members.Add (renderMethod);
}
if (childrenAsProperties || type == null) {
string typeString;
bool isGlobal = true;
bool returnsControl;
if (builder is RootBuilder) {
typeString = parser.ClassName;
isGlobal = false;
returnsControl = false;
} else {
returnsControl = builder.PropertyBuilderShouldReturnValue;
if (type != null && builder.IsProperty && !typeof (ITemplate).IsAssignableFrom (type)) {
typeString = type.FullName;
isGlobal = !type.IsPrimitive;
} else
typeString = "System.Web.UI.Control";
ProcessTemplateChildren (builder);
}
CodeTypeReference ctrlTypeRef = new CodeTypeReference (typeString);
if (isGlobal)
ctrlTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;
if (returnsControl) {
method.ReturnType = ctrlTypeRef;
// $controlType _ctrl = new $controlType ($parameters);
//
method.Statements.Add (CreateControlVariable (type, builder, method, ctrlTypeRef));
} else
method.Parameters.Add (new CodeParameterDeclarationExpression (typeString, "__ctrl"));
} else {
CodeTypeReference ctrlTypeRef = new CodeTypeReference (type.FullName);
if (!type.IsPrimitive)
ctrlTypeRef.Options |= CodeTypeReferenceOptions.GlobalReference;
if (typeof (Control).IsAssignableFrom (type))
method.ReturnType = ctrlTypeRef;
// $controlType _ctrl = new $controlType ($parameters);
//
method.Statements.Add (AddLinePragma (CreateControlVariable (type, builder, method, ctrlTypeRef), builder));
// this.$builderID = _ctrl;
//
CodeFieldReferenceExpression builderID = new CodeFieldReferenceExpression ();
builderID.TargetObject = thisRef;
builderID.FieldName = builder.ID;
CodeAssignStatement assign = new CodeAssignStatement ();
assign.Left = builderID;
assign.Right = ctrlVar;
method.Statements.Add (AddLinePragma (assign, builder));
if (typeof (UserControl).IsAssignableFrom (type)) {
CodeMethodReferenceExpression mref = new CodeMethodReferenceExpression ();
mref.TargetObject = builderID;
mref.MethodName = "InitializeAsUserControl";
CodeMethodInvokeExpression initAsControl = new CodeMethodInvokeExpression (mref);
initAsControl.Parameters.Add (new CodePropertyReferenceExpression (thisRef, "Page"));
method.Statements.Add (initAsControl);
}
if (builder.ParentTemplateBuilder is System.Web.UI.WebControls.ContentBuilderInternal) {
PropertyInfo pi;
try {
pi = type.GetProperty ("TemplateControl");
} catch (Exception) {
pi = null;
}
if (pi != null && pi.CanWrite) {
// __ctrl.TemplateControl = this;
assign = new CodeAssignStatement ();
assign.Left = new CodePropertyReferenceExpression (ctrlVar, "TemplateControl");;
assign.Right = thisRef;
method.Statements.Add (assign);
}
}
// _ctrl.SkinID = $value
// _ctrl.ApplyStyleSheetSkin (this);
//
// the SkinID assignment needs to come
// before the call to
// ApplyStyleSheetSkin, for obvious
// reasons. We skip SkinID in
// CreateAssignStatementsFromAttributes
// below.
//
string skinid = builder.GetAttribute ("skinid");
if (!String.IsNullOrEmpty (skinid))
CreateAssignStatementFromAttribute (builder, "skinid");
if (typeof (WebControl).IsAssignableFrom (type)) {
CodeMethodInvokeExpression applyStyleSheetSkin = new CodeMethodInvokeExpression (ctrlVar, "ApplyStyleSheetSkin");
if (typeof (Page).IsAssignableFrom (parser.BaseType))
applyStyleSheetSkin.Parameters.Add (thisRef);
else
applyStyleSheetSkin.Parameters.Add (new CodePropertyReferenceExpression (thisRef, "Page"));
method.Statements.Add (applyStyleSheetSkin);
}
// Process template children before anything else
ProcessTemplateChildren (builder);
// process ID here. It should be set before any other attributes are
// assigned, since the control code may rely on ID being set. We
// skip ID in CreateAssignStatementsFromAttributes
string ctl_id = builder.GetAttribute ("id");
if (ctl_id != null && ctl_id.Length != 0)
CreateAssignStatementFromAttribute (builder, "id");
if (typeof (ContentPlaceHolder).IsAssignableFrom (type)) {
List <string> placeHolderIds = MasterPageContentPlaceHolders;
string cphID = builder.ID;
if (!placeHolderIds.Contains (cphID))
placeHolderIds.Add (cphID);
CodeConditionStatement condStatement;
// Add the __Template_* field
string templateField = "__Template_" + cphID;
CodeMemberField fld = new CodeMemberField (typeof (ITemplate), templateField);
fld.Attributes = MemberAttributes.Private;
mainClass.Members.Add (fld);
CodeFieldReferenceExpression templateID = new CodeFieldReferenceExpression ();
templateID.TargetObject = thisRef;
templateID.FieldName = templateField;
CreateContentPlaceHolderTemplateProperty (templateField, "Template_" + cphID);
// if ((this.ContentTemplates != null)) {
// this.__Template_$builder.ID = ((System.Web.UI.ITemplate)(this.ContentTemplates["$builder.ID"]));
// }
//
CodeFieldReferenceExpression contentTemplates = new CodeFieldReferenceExpression ();
contentTemplates.TargetObject = thisRef;
contentTemplates.FieldName = "ContentTemplates";
CodeIndexerExpression indexer = new CodeIndexerExpression ();
indexer.TargetObject = new CodePropertyReferenceExpression (thisRef, "ContentTemplates");
indexer.Indices.Add (new CodePrimitiveExpression (cphID));
assign = new CodeAssignStatement ();
assign.Left = templateID;
assign.Right = new CodeCastExpression (new CodeTypeReference (typeof (ITemplate)), indexer);
condStatement = new CodeConditionStatement (new CodeBinaryOperatorExpression (contentTemplates,
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression (null)),
assign);
method.Statements.Add (condStatement);
// if ((this.__Template_mainContent != null)) {
// this.__Template_mainContent.InstantiateIn(__ctrl);
// }
// and also set things up such that any additional code ends up in:
// else {
// ...
// }
//
CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression ();
methodRef.TargetObject = templateID;
methodRef.MethodName = "InstantiateIn";
CodeMethodInvokeExpression instantiateInInvoke;
instantiateInInvoke = new CodeMethodInvokeExpression (methodRef, ctrlVar);
condStatement = new CodeConditionStatement (new CodeBinaryOperatorExpression (templateID,
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression (null)),
new CodeExpressionStatement (instantiateInInvoke));
method.Statements.Add (condStatement);
// this is the bit that causes the following stuff to end up in the else { }
builder.MethodStatements = condStatement.FalseStatements;
}
}
if (inBuildControlTree)
AddStatementsToInitMethodBottom (builder, method);
mainClass.Members.Add (method);
}