Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / System.Core / System.Linq.Expressions / ConstantExpression.cs
index 9e0e5a07629496822866a0b839b3bd2953f8a86c..dd45bdc967c6f7a82073b4e3e792a66fb915b7ba 100644 (file)
@@ -52,9 +52,30 @@ namespace System.Linq.Expressions {
 
                internal override void Emit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
+                       if (Type.IsNullable ()) {
+                               EmitNullableConstant (ec, Type, value);
+                               return;
+                       }
+
+                       EmitConstant (ec, Type, value);
+               }
+
+               void EmitNullableConstant (EmitContext ec, Type type, object value)
+               {
+                       if (value == null) {
+                               var local = ec.ig.DeclareLocal (type);
+                               ec.EmitNullableInitialize (local);
+                       } else {
+                               EmitConstant (ec, type.GetFirstGenericArgument (), value);
+                               ec.EmitNullableNew (type);
+                       }
+               }
+
+               void EmitConstant (EmitContext ec, Type type, object value)
+               {
+                       var ig = ec.ig;
 
-                       switch (Type.GetTypeCode (Type)){
+                       switch (Type.GetTypeCode (type)){
                        case TypeCode.Byte:
                                ig.Emit (OpCodes.Ldc_I4, (int) ((byte)value));
                                return;
@@ -129,18 +150,45 @@ namespace System.Linq.Expressions {
 
                                ig.Emit (OpCodes.Newobj, typeof (Decimal).GetConstructor (new Type [5] { ti, ti, ti, typeof(bool), typeof(byte) }));
                                return;
-                        }
+                       }
+
+                       case TypeCode.DateTime: {
+                               var date = (DateTime) value;
+                               var local = ig.DeclareLocal (typeof (DateTime));
+
+                               ig.Emit (OpCodes.Ldloca, local);
+                               ig.Emit (OpCodes.Ldc_I8, date.Ticks);
+                               ig.Emit (OpCodes.Ldc_I4, (int) date.Kind);
+                               ig.Emit (OpCodes.Call, typeof (DateTime).GetConstructor (new [] { typeof (long), typeof (DateTimeKind) }));
+                               ig.Emit (OpCodes.Ldloc, local);
+
+                               return;
+                       }
+
+                       case TypeCode.DBNull:
+                               ig.Emit (OpCodes.Ldsfld, typeof (DBNull).GetField ("Value", BindingFlags.Public | BindingFlags.Static));
+                               return;
 
                        case TypeCode.String:
-                               ig.Emit (OpCodes.Ldstr, (string) value);
+                               EmitIfNotNull (ec, c => c.ig.Emit (OpCodes.Ldstr, (string) value));
                                return;
 
                        case TypeCode.Object:
-                               ec.EmitReadGlobal (value);
+                               EmitIfNotNull (ec, c => c.EmitReadGlobal (value));
                                return;
                        }
 
                        throw new NotImplementedException (String.Format ("No support for constants of type {0} yet", Type));
                }
+
+               void EmitIfNotNull (EmitContext ec, Action<EmitContext> emit)
+               {
+                       if (value == null) {
+                               ec.ig.Emit (OpCodes.Ldnull);
+                               return;
+                       }
+
+                       emit (ec);
+               }
        }
 }