2007-02-06 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / const.cs
index 7422b492b3f23be40c2771edca882855dc315718..3e1e9c37dc62966de5c1d3ec78719cbf6bfbb1c0 100644 (file)
@@ -20,10 +20,10 @@ namespace Mono.CSharp {
        {
                void CheckObsoleteness (Location loc);
                bool ResolveValue ();
-               Constant Value { get; }
+               Constant CreateConstantReference (Location loc);
        }
 
-       public class Const : FieldMember, IConstant {
+       public class Const : FieldBase, IConstant {
                Constant value;
                bool in_transit;
                bool define_called;
@@ -83,15 +83,16 @@ namespace Mono.CSharp {
                        // Decimals cannot be emitted into the constant blob.  So, convert to 'readonly'.
                        if (ttype == TypeManager.decimal_type) {
                                field_attr |= FieldAttributes.InitOnly;
-                               Parent.PartialContainer.RegisterFieldForInitialization (this);
                        } else {
                                field_attr |= FieldAttributes.Literal;
                        }
 
                        FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr);
-
                        TypeManager.RegisterConstant (FieldBuilder, this);
 
+                       if (ttype == TypeManager.decimal_type)
+                               Parent.PartialContainer.RegisterFieldForInitialization (this, new FieldInitializer (FieldBuilder, initializer));
+
                        return true;
                }
 
@@ -177,22 +178,25 @@ namespace Mono.CSharp {
                        if (value == null)
                                return false;
 
-                       value = value.ImplicitConversionRequired (MemberType, Location);
-                       if (value == null)
-                               return false;
-
-                       if (!MemberType.IsValueType && MemberType != TypeManager.string_type && !value.IsDefaultValue) {
-                               Error_ConstantCanBeInitializedWithNullOnly (Location, GetSignatureForError ());
+                       Constant c  = value.ConvertImplicitly (MemberType);
+                       if (c == null) {
+                               if (!MemberType.IsValueType && MemberType != TypeManager.string_type && !value.IsDefaultValue)
+                                       Error_ConstantCanBeInitializedWithNullOnly (Location, GetSignatureForError ());
+                               else
+                                       value.Error_ValueCannotBeConverted (null, Location, MemberType, false);
                                return false;
                        }
 
+                       value = c;
                        return true;
                }
 
-               public Constant Value {
-                       get {
-                               return value;
-                       }
+               public Constant CreateConstantReference (Location loc)
+               {
+                       if (value == null)
+                               return null;
+
+                       return Constant.CreateConstant (value.Type, value.GetValue(), loc);
                }
 
                #endregion
@@ -201,14 +205,14 @@ namespace Mono.CSharp {
        public class ExternalConstant : IConstant
        {
                FieldInfo fi;
-               Constant value;
+               object value;
 
                public ExternalConstant (FieldInfo fi)
                {
                        this.fi = fi;
                }
 
-               private ExternalConstant (FieldInfo fi, Constant value):
+               private ExternalConstant (FieldInfo fi, object value):
                        this (fi)
                {
                        this.value = value;
@@ -229,7 +233,7 @@ namespace Mono.CSharp {
                                return null;
 
                        IConstant ic = new ExternalConstant (fi,
-                               new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value, Location.Null));
+                               ((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value);
 
                        return ic;
                }
@@ -251,20 +255,13 @@ namespace Mono.CSharp {
                        if (value != null)
                                return true;
 
-                       if (fi.DeclaringType.IsEnum) {
-                               value = Expression.Constantify (fi.GetValue (fi), TypeManager.EnumToUnderlying (fi.FieldType));
-                               value = new EnumConstant (value, fi.DeclaringType);
-                               return true;
-                       }
-
-                       value = Expression.Constantify (fi.GetValue (fi), fi.FieldType);
+                       value = fi.GetValue (fi);
                        return true;
                }
 
-               public Constant Value {
-                       get {
-                               return value;
-                       }
+               public Constant CreateConstantReference (Location loc)
+               {
+                       return Constant.CreateConstant (fi.FieldType, value, loc);
                }
 
                #endregion