Merge pull request #2700 from akoeplinger/monotouch-mobile-static
[mono.git] / mcs / class / System.Web / System.Web.UI / ControlBuilder.cs
index 1486aca37088d812b9c992925ea9cf4b73547e47..c250639cbd28c56862de52b7b3e93437630c9aeb 100644 (file)
@@ -4,9 +4,10 @@
 // Authors:
 //     Duncan Mak  (duncan@ximian.com)
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//      Marek Habersack <mhabersack@novell.com>
 //
 // (C) 2002, 2003 Ximian, Inc. (http://www.ximian.com)
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -38,6 +39,9 @@ using System.Web.Compilation;
 using System.Web.Configuration;
 using System.IO;
 using System.Web.UI.WebControls;
+using System.Web.Util;
+
+using _Location = System.Web.Compilation.Location;
 
 namespace System.Web.UI {
 
@@ -76,8 +80,12 @@ namespace System.Web.UI {
                CodeMemberMethod renderMethod;
                int renderIndex;
                bool isProperty;
+               bool isPropertyWritable;
                ILocation location;
                ArrayList otherTags;
+
+               int localVariableCount = 0;
+               bool? isTemplate;
                
                public ControlBuilder ()
                {
@@ -142,6 +150,11 @@ namespace System.Web.UI {
                        set { method = value; }
                }
 
+               internal CodeMemberMethod DataBindingMethod {
+                       get;
+                       set;
+               }
+                       
                internal CodeStatementCollection MethodStatements {
                        get { return methodStatements; }
                        set { methodStatements = value; }
@@ -160,9 +173,13 @@ namespace System.Web.UI {
                        get { return isProperty; }
                }
 
+               internal bool IsPropertyWritable {
+                       get { return isPropertyWritable; }
+               }
+               
                internal ILocation Location {
                        get { return location; }
-                       set { location = value; }
+                       set { location = new _Location (value); }
                }
        
                internal ArrayList OtherTags {
@@ -218,6 +235,28 @@ namespace System.Web.UI {
                        }
                }
 
+               internal bool IsNamingContainer {
+                       get {
+                               if (type == null)
+                                       return false;
+
+                               return typeof (INamingContainer).IsAssignableFrom (type);
+                       }
+               }
+
+               internal bool IsTemplate {
+                       get {
+                               if (isTemplate == null)
+                                       isTemplate = (typeof (TemplateBuilder).IsAssignableFrom (GetType ()));
+
+                               return isTemplate.Value;
+                       }
+               }
+               
+               internal bool PropertyBuilderShouldReturnValue {
+                       get { return isProperty && isPropertyWritable && RenderMethod == null && !IsTemplate && !(this is CollectionBuilder) && !(this is RootBuilder); }
+               }
+               
                ControlBuilder MyNamingContainer {
                        get {
                                if (myNamingContainer == null) {
@@ -237,12 +276,7 @@ namespace System.Web.UI {
                        }
                }
                        
-#if NET_2_0
-               public virtual
-#else
-               internal
-#endif
-               Type BindingContainerType {
+               public virtual Type BindingContainerType {
                        get {
                                ControlBuilder cb = (this is TemplateBuilder && !(this is RootBuilder)) ? this : MyNamingContainer;
                                
@@ -253,10 +287,8 @@ namespace System.Web.UI {
                                        return typeof (Control);
                                }
 
-#if NET_2_0
                                if (cb != this && cb is ContentBuilderInternal && !typeof (INonBindingContainer).IsAssignableFrom (cb.BindingContainerType))
                                        return cb.BindingContainerType;
-#endif
 
                                Type ct;
                                if (cb is TemplateBuilder) {
@@ -317,7 +349,7 @@ namespace System.Web.UI {
                
                internal RootBuilder Root {
                        get {
-                               if (GetType () == typeof (RootBuilder))
+                               if (typeof (RootBuilder).IsAssignableFrom (GetType ()))
                                        return (RootBuilder) this;
 
                                return (RootBuilder) parentBuilder.Root;
@@ -354,7 +386,6 @@ namespace System.Web.UI {
                                templateChildren.Add (child);
                        }
 
-#if NET_2_0
                        if (parser == null)
                                return;
                        
@@ -372,7 +403,6 @@ namespace System.Web.UI {
                        
                        parser.AddImport (component.Namespace);
                        parser.AddDependency (component.Source);
-#endif
                }
                
                public virtual bool AllowWhitespaceLiterals ()
@@ -451,13 +481,12 @@ namespace System.Web.UI {
                {
                }
 
-#if NET_2_0            
                static Type MapTagType (Type tagType)
                {
                        if (tagType == null)
                                return null;
                        
-                       PagesSection ps = WebConfigurationManager.GetWebApplicationSection ("system.web/pages") as PagesSection;
+                       PagesSection ps = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
                        if (ps == null)
                                return tagType;
 
@@ -519,7 +548,6 @@ namespace System.Web.UI {
                        
                        return tagType;
                }
-#endif
 
                public static ControlBuilder CreateBuilderFromType (TemplateParser parser,
                                                                    ControlBuilder parentBuilder,
@@ -530,14 +558,8 @@ namespace System.Web.UI {
                                                                    int line,
                                                                    string sourceFileName)
                {
-
-                       Type tagType;
-#if NET_2_0
-                       tagType = MapTagType (type);
-#else
-                       tagType = type;
-#endif
-                       ControlBuilder  builder;
+                       Type tagType = MapTagType (type);
+                       ControlBuilder builder;
                        object [] atts = tagType.GetCustomAttributes (typeof (ControlBuilderAttribute), true);
                        if (atts != null && atts.Length > 0) {
                                ControlBuilderAttribute att = (ControlBuilderAttribute) atts [0];
@@ -595,6 +617,7 @@ namespace System.Web.UI {
                                builder = CreateBuilderFromType (parser, parentBuilder, propType, prop.Name,
                                                                 null, atts, line, fileName);
                                builder.isProperty = true;
+                               builder.isPropertyWritable = prop.CanWrite;
                                if (idx >= 0)
                                        builder.originalTagName = propName;
                                return builder;
@@ -604,6 +627,7 @@ namespace System.Web.UI {
                        builder.fileName = fileName;
                        builder.line = line;
                        builder.isProperty = true;
+                       builder.isPropertyWritable = prop.CanWrite;
                        if (idx >= 0)
                                builder.originalTagName = propName;
                        return builder;
@@ -618,7 +642,7 @@ namespace System.Web.UI {
                {
                        this.parser = parser;
                        if (parser != null)
-                               this.location = parser.Location;
+                               this.Location = parser.Location;
 
                        this.parentBuilder = parentBuilder;
                        this.type = type;
@@ -677,8 +701,14 @@ namespace System.Web.UI {
                        return "_bctrl_" + nextID++;
                }
 
+               internal string GetNextLocalVariableName (string baseName)
+               {
+                       localVariableCount++;
+                       return baseName + localVariableCount.ToString ();
+               }
+               
                internal virtual ControlBuilder CreateSubBuilder (string tagid,
-                                                                 Hashtable atts,
+                                                                 IDictionary atts,
                                                                  Type childType,
                                                                  TemplateParser parser,
                                                                  ILocation location)
@@ -688,22 +718,29 @@ namespace System.Web.UI {
                                if (defaultPropertyBuilder == null)
                                        childBuilder = CreatePropertyBuilder (tagid, parser, atts);
                                else {
-                                       if (String.Compare (defaultPropertyBuilder.TagName, tagid, true, CultureInfo.InvariantCulture) == 0) {
+                                       if (String.Compare (defaultPropertyBuilder.TagName, tagid, true, Helpers.InvariantCulture) == 0) {
                                                // The child tag is the same what our default property name. Act as if there was
                                                // no default property builder, or otherwise we'll end up with invalid nested
                                                // builder call.
                                                defaultPropertyBuilder = null;
                                                childBuilder = CreatePropertyBuilder (tagid, parser, atts);
-                                       } else
-                                               childBuilder = defaultPropertyBuilder.CreateSubBuilder (tagid, atts,
-                                                                                                       null, parser,
-                                                                                                       location);
+                                       } else {
+                                               Type ct = ControlType;
+                                               MemberInfo[] mems = ct != null ? ct.GetMember (tagid, MemberTypes.Property, FlagsNoCase) : null;
+                                               PropertyInfo prop = mems != null && mems.Length > 0 ? mems [0] as PropertyInfo : null;
+
+                                               if (prop != null && typeof (ITemplate).IsAssignableFrom (prop.PropertyType)) {
+                                                       childBuilder = CreatePropertyBuilder (tagid, parser, atts);
+                                                       defaultPropertyBuilder = null;
+                                               } else
+                                                       childBuilder = defaultPropertyBuilder.CreateSubBuilder (tagid, atts, null, parser, location);
+                                       }
                                }
 
                                return childBuilder;
                        }
 
-                       if (String.Compare (tagName, tagid, true, CultureInfo.InvariantCulture) == 0)
+                       if (String.Compare (tagName, tagid, true, Helpers.InvariantCulture) == 0)
                                return null;
                        
                        childType = GetChildControlType (tagid, atts);
@@ -747,21 +784,20 @@ namespace System.Web.UI {
                                }
                        }
                }
-#if NET_2_0
+
                [MonoTODO ("unsure, lack documentation")]
                public virtual object BuildObject ()
                {
                        return CreateInstance ();
                }
                
-               [MonoTODO]
                public virtual void ProcessGeneratedCode(CodeCompileUnit codeCompileUnit,
-                       CodeTypeDeclaration baseType,
-                       CodeTypeDeclaration derivedType,
-                       CodeMemberMethod buildMethod,
-                       CodeMemberMethod dataBindingMethod)
+                                                        CodeTypeDeclaration baseType,
+                                                        CodeTypeDeclaration derivedType,
+                                                        CodeMemberMethod buildMethod,
+                                                        CodeMemberMethod dataBindingMethod)
                {
-                       throw new NotImplementedException ();
+                       // nothing to do
                }
 
                internal void ResetState()
@@ -777,6 +813,5 @@ namespace System.Web.UI {
                                }
                        }
                }
-#endif
        }
 }