using System.CodeDom;
using System.Collections;
using System.ComponentModel;
+using System.Configuration;
+using System.Collections.Specialized;
+using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Reflection;
+using System.Resources;
using System.Text;
using System.Web;
+using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Util;
using System.ComponentModel.Design.Serialization;
using System.Text.RegularExpressions;
-#if NET_2_0
-using System.Configuration;
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using System.Web.Configuration;
-#endif
namespace System.Web.Compilation
{
internal static CodeVariableReferenceExpression ctrlVar = new CodeVariableReferenceExpression ("__ctrl");
-#if NET_2_0
List <string> masterPageContentPlaceHolders;
+ static Regex startsWithBindRegex = new Regex (@"^Bind\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase);
// When modifying those, make sure to look at the SanitizeBindCall to make sure it
// picks up correct groups.
static Regex bindRegex = new Regex (@"Bind\s*\(\s*[""']+(.*?)[""']+((\s*,\s*[""']+(.*?)[""']+)?)\s*\)\s*%>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
static Regex bindRegexInValue = new Regex (@"Bind\s*\(\s*[""']+(.*?)[""']+((\s*,\s*[""']+(.*?)[""']+)?)\s*\)\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
-#endif
static Regex evalRegexInValue = new Regex (@"(.*)Eval\s*\(\s*[""']+(.*?)[""']+((\s*,\s*[""']+(.*?)[""']+)?)\s*\)(.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
-#if NET_2_0
List <string> MasterPageContentPlaceHolders {
get {
if (masterPageContentPlaceHolders == null)
return masterPageContentPlaceHolders;
}
}
-#endif
+
public TemplateControlCompiler (TemplateControlParser parser)
: base (parser)
{
{
if (builder == null || builder.ID == null || builder.ControlType == null)
return;
-#if NET_2_0
+
if (partialNameOverride [builder.ID] != null)
return;
-#endif
MemberAttributes ma = MemberAttributes.Family;
currentLocation = builder.Location;
CodeMemberField field;
field = new CodeMemberField (builder.ControlType.FullName, builder.ID);
field.Attributes = ma;
-#if NET_2_0
field.Type.Options |= CodeTypeReferenceOptions.GlobalReference;
if (partialClass != null)
partialClass.Members.Add (AddLinePragma (field, builder));
else
-#endif
mainClass.Members.Add (AddLinePragma (field, builder));
}
return false;
if (!other.IsAssignableFrom (type)) {
-#if NET_2_0
ma |= MemberAttributes.New;
return false;
-#else
- string msg = String.Format ("The base class includes the field '{0}', but its " +
- "type '{1}' is not compatible with {2}",
- id, other, type);
- throw new ParseException (currentLocation, msg);
-#endif
}
return true;
* method, allow subclasses to insert control
* specific code. */
if (builder is RootBuilder) {
-#if NET_2_0
SetCustomAttributes (method);
-#endif
AddStatementsToInitMethod (method);
}
method.Statements.Add (initAsControl);
}
-#if NET_2_0
if (builder.ParentTemplateBuilder is System.Web.UI.WebControls.ContentBuilderInternal) {
PropertyInfo pi;
applyStyleSheetSkin.Parameters.Add (new CodePropertyReferenceExpression (thisRef, "Page"));
method.Statements.Add (applyStyleSheetSkin);
}
-#endif
// Process template children before anything else
ProcessTemplateChildren (builder);
string ctl_id = builder.GetAttribute ("id");
if (ctl_id != null && ctl_id.Length != 0)
CreateAssignStatementFromAttribute (builder, "id");
-
-#if NET_2_0
if (typeof (ContentPlaceHolder).IsAssignableFrom (type)) {
List <string> placeHolderIds = MasterPageContentPlaceHolders;
string cphID = builder.ID;
// this is the bit that causes the following stuff to end up in the else { }
builder.MethodStatements = condStatement.FalseStatements;
}
-#endif
}
mainClass.Members.Add (method);
if (templates != null && templates.Count > 0) {
foreach (TemplateBuilder tb in templates) {
CreateControlTree (tb, true, false);
-#if NET_2_0
if (tb.BindingDirection == BindingDirection.TwoWay) {
string extractMethod = CreateExtractValuesMethod (tb);
AddBindableTemplateInvocation (builder, tb.TagName, tb.Method.Name, extractMethod);
} else
-#endif
AddTemplateInvocation (builder, tb.TagName, tb.Method.Name);
}
}
}
-#if NET_2_0
void SetCustomAttribute (CodeMemberMethod method, UnknownAttributeDescriptor uad)
{
CodeAssignStatement assign = new CodeAssignStatement ();
foreach (UnknownAttributeDescriptor uad in attrs)
SetCustomAttribute (method, uad);
}
-#endif
protected virtual void AddStatementsToInitMethod (CodeMemberMethod method)
{
{
Match match = regex.Match (value);
if (!match.Success) {
-#if NET_2_0
if (isBind)
throw new HttpParseException ("Bind invocation wasn't formatted properly.");
-#endif
return null;
}
CodeExpression valueExpression = null;
value = value.Trim ();
-#if NET_2_0
bool need_if = false;
- if (StrUtils.StartsWith (value, "Bind", true)) {
+ if (startsWithBindRegex.Match (value).Success) {
valueExpression = CreateEvalInvokeExpression (bindRegexInValue, value, true);
if (valueExpression != null)
need_if = true;
} else
-#endif
if (StrUtils.StartsWith (value, "Eval", true))
valueExpression = CreateEvalInvokeExpression (evalRegexInValue, value, false);
valueExpression = new CodeSnippetExpression (value);
method = CreateDBMethod (builder, dbMethodName, GetContainerType (builder), builder.ControlType);
-
CodeVariableReferenceExpression targetExpr = new CodeVariableReferenceExpression ("target");
// This should be a CodePropertyReferenceExpression for properties... but it works anyway
expr = new CodeCastExpression (type, valueExpression);
CodeAssignStatement assign = new CodeAssignStatement (field, expr);
-#if NET_2_0
if (need_if) {
CodeExpression page = new CodePropertyReferenceExpression (thisRef, "Page");
CodeExpression left = new CodeMethodInvokeExpression (page, "GetDataItem");
CodeBinaryOperatorExpression ce = new CodeBinaryOperatorExpression (left, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression (null));
CodeConditionStatement ccs = new CodeConditionStatement (ce, assign);
method.Statements.Add (ccs);
- }
- else
-#endif
+ } else
method.Statements.Add (assign);
mainClass.Members.Add (method);
string dbMethodName = DataBoundProperty (builder, type, var_name, att);
AddEventAssign (method, builder, "DataBinding", typeof (EventHandler), dbMethodName);
return;
- }
-#if NET_2_0
- else if (isExpression && isWritable) {
+ } else if (isExpression && isWritable) {
AddExpressionAssign (method, builder, member, type, var_name, att);
return;
}
-#endif
CodeAssignStatement assign = new CodeAssignStatement ();
assign.Left = new CodePropertyReferenceExpression (ctrlVar, var_name);
return IsDirective (value, '#');
}
-#if NET_2_0
bool IsExpression (string value)
{
return IsDirective (value, '$');
}
}
}
-#endif
/*
static bool InvariantCompare (string a, string b)
{
- return (0 == String.Compare (a, b, false, CultureInfo.InvariantCulture));
+ return (0 == String.Compare (a, b, false, Helpers.InvariantCulture));
}
*/
static bool InvariantCompareNoCase (string a, string b)
{
- return (0 == String.Compare (a, b, true, CultureInfo.InvariantCulture));
+ return (0 == String.Compare (a, b, true, Helpers.InvariantCulture));
}
static MemberInfo GetFieldOrProperty (Type type, string name)
int hyphen = id.IndexOf ('-');
bool isPropertyInfo = (member is PropertyInfo);
bool isDataBound = IsDataBound (attValue);
-#if NET_2_0
bool isExpression = !isDataBound && IsExpression (attValue);
-#else
- bool isExpression = false;
-#endif
Type type;
if (isPropertyInfo) {
type = ((PropertyInfo) member).PropertyType;
}
if (InvariantCompareNoCase (member.Name, id)) {
-#if NET_2_0
if (isDataBound)
- RegisterBindingInfo (builder, member.Name, ref attValue);
-
-#endif
+ RegisterBindingInfo (builder, member.Name, ref attValue);
+
if (!IsWritablePropertyOrField (member))
return false;
string val = attValue;
if (attValue == null && is_bool)
val = "true"; // Font-Bold <=> Font-Bold="true"
-#if NET_2_0
+
if (isDataBound)
RegisterBindingInfo (builder, prefix + member.Name + "." + subprop.Name, ref attValue);
-#endif
+
AddCodeForPropertyOrField (builder, subprop.PropertyType,
prefix + member.Name + "." + subprop.Name,
val, subprop, isDataBound, isExpression);
return true;
}
-#if NET_2_0
CodeExpression CompileExpression (MemberInfo member, Type type, string value, bool useSetAttribute)
{
// First let's find the correct expression builder
string prefix = value.Substring (0, colon).Trim ();
string expr = value.Substring (colon + 1).Trim ();
- System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration ("");
- if (config == null)
- return null;
-
- CompilationSection cs = (CompilationSection)config.GetSection ("system.web/compilation");
+ CompilationSection cs = (CompilationSection)WebConfigurationManager.GetWebApplicationSection ("system.web/compilation");
if (cs == null)
return null;
return ret;
}
+
+ bool ResourceProviderHasObject (string key)
+ {
+ IResourceProvider rp = HttpContext.GetResourceProvider (InputVirtualPath.Absolute, true);
+ if (rp == null)
+ return false;
+
+ IResourceReader rr = rp.ResourceReader;
+ if (rr == null)
+ return false;
+
+ try {
+ IDictionaryEnumerator ide = rr.GetEnumerator ();
+ if (ide == null)
+ return false;
+
+ string dictKey;
+ while (ide.MoveNext ()) {
+ dictKey = ide.Key as string;
+ if (String.IsNullOrEmpty (dictKey))
+ continue;
+ if (String.Compare (key, dictKey, StringComparison.Ordinal) == 0)
+ return true;
+ }
+ } finally {
+ rr.Close ();
+ }
+
+ return false;
+ }
void AssignPropertyFromResources (ControlBuilder builder, MemberInfo mi, string attvalue)
{
if (!isProperty && !isField || !IsWritablePropertyOrField (mi))
return;
+ object[] attrs = mi.GetCustomAttributes (typeof (LocalizableAttribute), true);
+ if (attrs != null && attrs.Length > 0 && !((LocalizableAttribute)attrs [0]).IsLocalizable)
+ return;
+
string memberName = mi.Name;
string resname = String.Concat (attvalue, ".", memberName);
+ if (!ResourceProviderHasObject (resname))
+ return;
+
// __ctrl.Text = System.Convert.ToString(HttpContext.GetLocalResourceObject("ButtonResource1.Text"));
string inputFile = parser.InputFile;
string physPath = HttpContext.Current.Request.PhysicalApplicationPath;
AssignPropertiesFromResources (builder, controlType, attvalue);
}
-#endif
void AddEventAssign (CodeMemberMethod method, ControlBuilder builder, string name, Type type, string value)
{
Type type = builder.ControlType;
string attvalue = builder.GetAttribute (id);
- if (id.Length > 2 && id.Substring (0, 2).ToUpper () == "ON"){
+ if (id.Length > 2 && String.Compare (id.Substring (0, 2), "ON", true, Helpers.InvariantCulture) == 0){
if (ev_info == null)
ev_info = type.GetEvents ();
}
-#if NET_2_0
- if (id.ToLower () == "meta:resourcekey") {
+ if (String.Compare (id, "meta:resourcekey", StringComparison.OrdinalIgnoreCase) == 0) {
AssignPropertiesFromResources (builder, attvalue);
return;
}
-#endif
int hyphen = id.IndexOf ('-');
string alt_id = id;
CodeMemberMethod method = builder.Method;
bool isDatabound = IsDataBound (attvalue);
-#if NET_2_0
bool isExpression = !isDatabound && IsExpression (attvalue);
-#endif
if (isDatabound) {
string value = attvalue.Substring (3, attvalue.Length - 5).Trim ();
CodeExpression valueExpression = null;
-#if NET_2_0
- if (StrUtils.StartsWith (value, "Bind", true))
+ if (startsWithBindRegex.Match (value).Success)
valueExpression = CreateEvalInvokeExpression (bindRegexInValue, value, true);
else
-#endif
- if (StrUtils.StartsWith (value, "Eval", true))
- valueExpression = CreateEvalInvokeExpression (evalRegexInValue, value, false);
+ if (StrUtils.StartsWith (value, "Eval", true))
+ valueExpression = CreateEvalInvokeExpression (evalRegexInValue, value, false);
if (valueExpression == null && value != null && value.Trim () != String.Empty)
valueExpression = new CodeSnippetExpression (value);
expr.Parameters.Add (new CodePrimitiveExpression (id));
CodeExpression valueExpr = null;
-#if NET_2_0
if (isExpression)
valueExpr = CompileExpression (null, typeof (string), attvalue, true);
if (valueExpr == null)
-#endif
valueExpr = new CodePrimitiveExpression (attvalue);
expr.Parameters.Add (valueExpr);
continue;
// ID is assigned in BuildControltree
if (InvariantCompareNoCase (id, "id"))
- continue;
-
-#if NET_2_0
+ continue;
+
/* we skip SkinID here as it's assigned in BuildControlTree */
if (InvariantCompareNoCase (id, "skinid"))
continue;
if (InvariantCompareNoCase (id, "meta:resourcekey"))
continue; // ignore, this one's processed at the very end of
// the method
-#endif
CreateAssignStatementFromAttribute (builder, id);
}
}
AddEventAssign (method, builder, "DataBinding", typeof (EventHandler), dbMethodName);
method = CreateDBMethod (builder, dbMethodName, GetContainerType (builder), builder.ControlType);
+ builder.DataBindingMethod = method;
+
CodeCastExpression cast;
CodeMethodReferenceExpression methodExpr;
CodeMethodInvokeExpression expr;
builder.Method.Statements.Add (AddLinePragma (assign, builder));
}
-#if NET_2_0
void AddBindableTemplateInvocation (ControlBuilder builder, string name, string methodName, string extractMethodName)
{
CodePropertyReferenceExpression prop = new CodePropertyReferenceExpression (ctrlVar, name);
method.Statements.Add (AddLinePragma (invoke, cbuilder));
}
-#endif
void AddCodeRender (ControlBuilder parent, CodeRenderBuilder cr)
{
new CodeArgumentReferenceExpression ("__output"),
"Write");
- expr.Parameters.Add (new CodeSnippetExpression (cr.Code));
+ expr.Parameters.Add (GetWrappedCodeExpression (cr));
parent.RenderMethod.Statements.Add (AddLinePragma (expr, cr));
}
- static PropertyInfo GetContainerProperty (Type type, string[] propNames)
+ CodeExpression GetWrappedCodeExpression (CodeRenderBuilder cr)
{
- PropertyInfo prop;
-
- foreach (string name in propNames) {
- prop = type.GetProperty (name, noCaseFlags & ~BindingFlags.NonPublic);
- if (prop != null)
- return prop;
- }
-
- return null;
- }
-
-#if !NET_2_0
- static string[] containerPropNames = {"Items", "Rows"};
+ var ret = new CodeSnippetExpression (cr.Code);
+#if NET_4_0
+ if (cr.HtmlEncode) {
+ var encodeRef = new CodeMethodReferenceExpression (new CodeTypeReferenceExpression (typeof (HttpUtility)), "HtmlEncode");
+ return new CodeMethodInvokeExpression (encodeRef, new CodeExpression[] { ret });
+ } else
#endif
+ return ret;
+ }
static Type GetContainerType (ControlBuilder builder)
{
- Type type = builder.BindingContainerType;
-
-#if NET_2_0
- return type;
-#else
-
- PropertyInfo prop = GetContainerProperty (type, containerPropNames);
- if (prop == null)
- return type;
-
- Type ptype = prop.PropertyType;
- if (!typeof (ICollection).IsAssignableFrom (ptype))
- return type;
-
- prop = ptype.GetProperty ("Item", noCaseFlags & ~BindingFlags.NonPublic);
- if (prop == null)
- return type;
-
- return prop.PropertyType;
-#endif
+ return builder.BindingContainerType;
}
CodeMemberMethod CreateDBMethod (ControlBuilder builder, string name, Type container, Type target)
// Add the DataBind handler
method = CreateDBMethod (builder, dbMethodName, GetContainerType (builder), typeof (DataBoundLiteralControl));
+ builder.DataBindingMethod = method;
CodeVariableReferenceExpression targetExpr = new CodeVariableReferenceExpression ("target");
CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression ();
method.Statements.Add (AddLinePragma (invoke, builder));
mainClass.Members.Add (method);
-
+
AddChildCall (builder, db);
}
if (!isTemplate && !inTemplate) {
CreateField (builder, true);
} else if (!isTemplate) {
- bool doCheck = false;
-
-#if NET_2_0
+ bool doCheck = false;
bool singleInstance = false;
ControlBuilder pb = builder.ParentBuilder;
TemplateBuilder tpb;
}
if (!singleInstance)
-#endif
builder.ID = builder.GetNextID (null);
-#if NET_2_0
else
doCheck = true;
-#endif
+
CreateField (builder, doCheck);
}
FlushText (builder, sb);
if (b is ObjectTagBuilder) {
ProcessObjectTag ((ObjectTagBuilder) b);
- continue;
- }
-
- StringPropertyBuilder pb = b as StringPropertyBuilder;
- if (pb != null){
+ } else if (b is StringPropertyBuilder) {
+ StringPropertyBuilder pb = b as StringPropertyBuilder;
if (pb.Children != null && pb.Children.Count > 0) {
StringBuilder asb = new StringBuilder ();
foreach (string s in pb.Children)
assign.Right = new CodePrimitiveExpression (asb.ToString ());
method.Statements.Add (AddLinePragma (assign, builder));
}
- continue;
- }
-
-#if NET_2_0
- if (b is ContentBuilderInternal) {
+ } else if (b is ContentBuilderInternal) {
ContentBuilderInternal cb = (ContentBuilderInternal) b;
CreateControlTree (cb, false, true);
AddContentTemplateInvocation (cb, builder.Method, cb.Method.Name);
continue;
}
-#endif
- // Ignore TemplateBuilders - they are processed in InitMethod
- if (b is TemplateBuilder)
- continue;
- if (b is CodeRenderBuilder) {
+ // Ignore TemplateBuilders - they are processed in InitMethod
+ else if (b is TemplateBuilder) {
+ } else if (b is CodeRenderBuilder) {
AddCodeRender (builder, (CodeRenderBuilder) b);
- continue;
- }
-
- if (b is DataBindingBuilder) {
+ } else if (b is DataBindingBuilder) {
AddDataBindingLiteral (builder, (DataBindingBuilder) b);
- continue;
- }
-
- if (b is ControlBuilder) {
+ } else if (b is ControlBuilder) {
ControlBuilder child = (ControlBuilder) b;
CreateControlTree (child, inTemplate, builder.ChildrenAsProperties);
AddChildCall (builder, child);
continue;
- }
+ } else
+ throw new Exception ("???");
- throw new Exception ("???");
+ ControlBuilder bldr = b as ControlBuilder;
+ bldr.ProcessGeneratedCode (CompileUnit, BaseType, DerivedType, bldr.Method, bldr.DataBindingMethod);
}
FlushText (builder, sb);
}
-
ControlBuilder defaultPropertyBuilder = builder.DefaultPropertyBuilder;
if (defaultPropertyBuilder != null) {
CreateControlTree (defaultPropertyBuilder, false, true);
builder.MethodStatements.Add (invoke);
}
-#if NET_2_0
if (builder is RootBuilder)
if (!String.IsNullOrEmpty (parser.MetaResourceKey))
AssignPropertiesFromResources (builder, parser.BaseType, parser.MetaResourceKey);
if ((!isTemplate || builder is RootBuilder) && !String.IsNullOrEmpty (builder.GetAttribute ("meta:resourcekey")))
CreateAssignStatementFromAttribute (builder, "meta:resourcekey");
-#endif
if (!childrenAsProperties && typeof (Control).IsAssignableFrom (builder.ControlType))
builder.Method.Statements.Add (new CodeMethodReturnStatement (ctrlVar));
+
+ builder.ProcessGeneratedCode (CompileUnit, BaseType, DerivedType, builder.Method, builder.DataBindingMethod);
}
-#if NET_2_0
protected override void AddStatementsToConstructor (CodeConstructor ctor)
{
if (masterPageContentPlaceHolders == null || masterPageContentPlaceHolders.Count == 0)
CodeMethodInvokeExpression mcall;
foreach (string id in masterPageContentPlaceHolders) {
mcall = new CodeMethodInvokeExpression (ilistRef, "Add");
- mcall.Parameters.Add (new CodePrimitiveExpression (id));
+ mcall.Parameters.Add (new CodePrimitiveExpression (id.ToLowerInvariant ()));
statements.Add (mcall);
}
}
-#endif
protected internal override void CreateMethods ()
{
CreateFrameworkInitializeMethod ();
}
-#if NET_2_0
protected override void InitializeType ()
{
List <string> registeredTagNames = parser.RegisteredTagNames;
CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (baseRef, "FrameworkInitialize");
method.Statements.Add (invoke);
}
-#endif
void CallSetStringResourcePointer (CodeMemberMethod method)
{
method.Name = "FrameworkInitialize";
method.Attributes = MemberAttributes.Family | MemberAttributes.Override;
PrependStatementsToFrameworkInitialize (method);
-#if NET_2_0
CallBaseFrameworkInitialize (method);
-#endif
CallSetStringResourcePointer (method);
AppendStatementsToFrameworkInitialize (method);
mainClass.Members.Add (method);
CodeCastExpression cast = new CodeCastExpression (appType.FullName, propRef);
prop.GetStatements.Add (new CodeMethodReturnStatement (cast));
-#if NET_2_0
if (partialClass != null)
partialClass.Members.Add (prop);
else
-#endif
- mainClass.Members.Add (prop);
+ mainClass.Members.Add (prop);
}
-#if NET_2_0
void CreateContentPlaceHolderTemplateProperty (string backingField, string name)
{
CodeMemberProperty prop = new CodeMemberProperty ();
mainClass.Members.Add (prop);
}
-#endif
void CreateAutoHandlers ()
{
prop.GetStatements.Add (ret);
prop.SetStatements.Add (new CodeAssignStatement (fldRef, new CodePropertySetValueReferenceExpression ()));
-#if NET_2_0
CodeAttributeDeclaration attr = new CodeAttributeDeclaration ("System.Obsolete");
- prop.CustomAttributes.Add (attr);
-#endif
-
+ prop.CustomAttributes.Add (attr);
mainClass.Members.Add (prop);
// Add the __autoHandlers field
mainClass.Members.Add (prop);
}
-#if NET_2_0
protected virtual string HandleUrlProperty (string str, MemberInfo member)
{
return str;
}
-#endif
TypeConverter GetConverterForMember (MemberInfo member)
{
- TypeConverterAttribute tca = null;
- object[] attrs;
-
-#if NET_2_0
- attrs = member.GetCustomAttributes (typeof (TypeConverterAttribute), true);
- if (attrs.Length > 0)
- tca = attrs [0] as TypeConverterAttribute;
-#else
- attrs = member.GetCustomAttributes (true);
-
- foreach (object attr in attrs) {
- tca = attr as TypeConverterAttribute;
-
- if (tca != null)
- break;
- }
-#endif
-
- if (tca == null)
+ TypeDescriptionProvider prov = TypeDescriptor.GetProvider (member.ReflectedType);
+ if (prov == null)
return null;
- string typeName = tca.ConverterTypeName;
- if (typeName == null || typeName.Length == 0)
- return null;
+ ICustomTypeDescriptor desc = prov.GetTypeDescriptor (member.ReflectedType);
+ PropertyDescriptorCollection coll = desc != null ? desc.GetProperties () : null;
- Type t = null;
- try {
- t = HttpApplication.LoadType (typeName);
- } catch (Exception) {
- // ignore
- }
+ if (coll == null || coll.Count == 0)
+ return null;
- if (t == null)
+ PropertyDescriptor pd = coll.Find (member.Name, false);
+ if (pd == null)
return null;
- return (TypeConverter) Activator.CreateInstance (t);
+ return pd.Converter;
}
CodeExpression CreateNullableExpression (Type type, CodeExpression inst, bool nullable)
{
-#if NET_2_0
if (!nullable)
return inst;
- return new CodeObjectCreateExpression (
- type,
- new CodeExpression[] {inst}
- );
-#else
- return inst;
-#endif
+ return new CodeObjectCreateExpression (type, new CodeExpression[] {inst});
}
bool SafeCanConvertFrom (Type type, TypeConverter cvt)
bool wasNullable = false;
Type originalType = type;
-#if NET_2_0
+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
Type[] types = type.GetGenericArguments();
originalType = type;
type = types[0]; // we're interested only in the first type here
wasNullable = true;
}
-#endif
+
if (type == typeof (string)) {
- if (preConverted)
+ object[] urlAttr = member.GetCustomAttributes (typeof (UrlPropertyAttribute), true);
+ if (urlAttr.Length != 0)
+ str = HandleUrlProperty ((preConverted && convertedFromAttr is string) ? (string)convertedFromAttr : str, member);
+ else if (preConverted)
return CreateNullableExpression (originalType,
new CodePrimitiveExpression ((string) convertedFromAttr),
wasNullable);
-
-#if NET_2_0
- object[] urlAttr = member.GetCustomAttributes (typeof (UrlPropertyAttribute), true);
- if (urlAttr.Length != 0)
- str = HandleUrlProperty (str, member);
-#endif
+
return CreateNullableExpression (originalType, new CodePrimitiveExpression (str), wasNullable);
} else if (type == typeof (bool)) {
if (preConverted)
return CreateNullableExpression (originalType, new CodePrimitiveExpression (true), wasNullable);
else if (InvariantCompareNoCase (str, "false"))
return CreateNullableExpression (originalType, new CodePrimitiveExpression (false), wasNullable);
-#if NET_2_0
else if (wasNullable && InvariantCompareNoCase(str, "null"))
return new CodePrimitiveExpression (null);
-#endif
else
throw new ParseException (currentLocation,
"Value '" + str + "' is not a valid boolean.");
return CreateNullableExpression (originalType,
new CodePrimitiveExpression (
Convert.ChangeType (preConverted ? convertedFromAttr : str,
- type, CultureInfo.InvariantCulture)),
+ type, Helpers.InvariantCulture)),
wasNullable);
if (type == typeof (string [])) {
}
}
- TypeConverter converter = preConverted ? cvt :
- wasNullable ? TypeDescriptor.GetConverter (type) :
- TypeDescriptor.GetProperties (member.DeclaringType) [member.Name].Converter;
+ TypeConverter converter = preConverted ? cvt : wasNullable ? TypeDescriptor.GetConverter (type) : null;
+ if (converter == null) {
+ PropertyDescriptor pdesc = TypeDescriptor.GetProperties (member.DeclaringType) [member.Name];
+ if (pdesc != null)
+ converter = pdesc.Converter;
+ else {
+ Type memberType;
+ switch (member.MemberType) {
+ case MemberTypes.Field:
+ memberType = ((FieldInfo)member).FieldType;
+ break;
+
+ case MemberTypes.Property:
+ memberType = ((PropertyInfo)member).PropertyType;
+ break;
+
+ default:
+ memberType = null;
+ break;
+ }
+
+ if (memberType == null)
+ return null;
+ converter = TypeDescriptor.GetConverter (memberType);
+ }
+ }
+
if (preConverted || (converter != null && SafeCanConvertFrom (typeof (string), converter))) {
object value = preConverted ? convertedFromAttr : converter.ConvertFromInvariantString (str);
return CreateNullableExpression (originalType, GenerateInstance (idesc, true),
wasNullable);
- return new CodeCastExpression (type, GenerateInstance (idesc, true));
+ CodeExpression instance = GenerateInstance (idesc, true);
+ if (type.IsPublic)
+ return new CodeCastExpression (type, instance);
+ else
+ return instance;
}
CodeExpression exp = GenerateObjectInstance (value, false);
{
if (value is System.Web.UI.WebControls.Unit) {
System.Web.UI.WebControls.Unit s = (System.Web.UI.WebControls.Unit) value;
+ if (s.IsEmpty) {
+ FieldInfo f = typeof (Unit).GetField ("Empty");
+ return new InstanceDescriptor (f, null);
+ }
ConstructorInfo c = typeof(System.Web.UI.WebControls.Unit).GetConstructor (
BindingFlags.Instance | BindingFlags.Public,
null,
if (value is System.Web.UI.WebControls.FontUnit) {
System.Web.UI.WebControls.FontUnit s = (System.Web.UI.WebControls.FontUnit) value;
+ if (s.IsEmpty) {
+ FieldInfo f = typeof (FontUnit).GetField ("Empty");
+ return new InstanceDescriptor (f, null);
+ }
Type cParamType = null;
object cParam = null;