Indent
[mono.git] / mcs / mcs / convert.cs
index b1e5946b001207ebf3d69608bb7ad21b81ad3838..4ed1f25adb5cf2c6aca8cbf5e6f4f0172021c589 100644 (file)
@@ -52,9 +52,6 @@ namespace Mono.CSharp {
                }
 #endif
 
-               //
-               // From a one-dimensional array-type S[] to System.Collections.IList<S> and base
-               // interfaces of this interface.
                //
                // From a one-dimensional array-type S[] to System.Collections.IList<T> and base
                // interfaces of this interface, provided there is an implicit reference conversion
@@ -63,7 +60,7 @@ namespace Mono.CSharp {
                static bool Array_To_IList (Type array, Type list)
                {
 #if GMCS_SOURCE
-                       if (!array.IsArray || (array.GetArrayRank () != 1) || !list.IsGenericType)
+                       if ((array.GetArrayRank () != 1) || !list.IsGenericType)
                                return false;
 
                        Type gt = list.GetGenericTypeDefinition ();
@@ -82,7 +79,7 @@ namespace Mono.CSharp {
                                MyEmptyExpr = new EmptyExpression ();
                        MyEmptyExpr.SetType (TypeManager.GetElementType (array));
 
-                       return ImplicitReferenceConversionCore (MyEmptyExpr, arg_type);
+                       return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type);
 #else
                        return false;
 #endif
@@ -278,7 +275,7 @@ namespace Mono.CSharp {
                                return nl.ConvertImplicitly(target_type);
                        }
 
-                       if (ImplicitReferenceConversionCore (expr, target_type)) {
+                       if (ImplicitReferenceConversionExists (expr, target_type)) {
                                // 
                                // Reduce implicit reference conversion to object
                                //
@@ -299,10 +296,23 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               static public bool ImplicitReferenceConversionCore (Expression expr, Type target_type)
+               //
+               // 6.1.6 Implicit reference conversions
+               //
+               public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
                {
+                       if (target_type.IsValueType)
+                               return false;
+
                        Type expr_type = expr.Type;
 
+                       // from the null type to any reference-type.
+                       if (expr_type == TypeManager.null_type)
+                               return target_type != TypeManager.anonymous_method_type;
+
+                       if (TypeManager.IsGenericParameter (expr_type))
+                               return ImplicitTypeParameterConversion (expr, target_type) != null;
+
                        //
                        // notice that it is possible to write "ValueType v = 1", the ValueType here
                        // is an abstract class, and not really a value type, so we apply the same rules.
@@ -458,33 +468,6 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               //
-               // Tests whether an implicit reference conversion exists between expr_type
-               // and target_type
-               //
-               public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
-               {
-                       if (target_type.IsValueType)
-                               return false;
-
-                       Type expr_type = expr.Type;
-
-                       // from the null type to any reference-type.
-                       if (expr_type == TypeManager.null_type){
-                               return target_type != TypeManager.anonymous_method_type;
-                       }
-
-                       if (TypeManager.IsGenericParameter (expr_type))
-                               return ImplicitTypeParameterConversion (expr, target_type) != null;
-
-                       bool use_class_cast;
-                       if (ImplicitReferenceConversionCore (expr, target_type) ||
-                           ImplicitBoxingConversionExists (expr, target_type, out use_class_cast))
-                               return true;
-
-                       return false;
-               }
-
                /// <summary>
                ///   Implicit Numeric Conversions.
                ///
@@ -827,6 +810,10 @@ namespace Mono.CSharp {
                        if (ImplicitReferenceConversionExists (expr, target_type))
                                return true;
 
+                       bool use_class_cast;
+                       if (ImplicitBoxingConversionExists (expr, target_type, out use_class_cast))
+                               return true;
+
                        //
                        // Implicit Constant Expression Conversions
                        //
@@ -985,8 +972,8 @@ namespace Mono.CSharp {
                        //
                        Type source_type = source.Type;
                        foreach (MethodBase mb in list){
-                               ParameterData pd = TypeManager.GetParameterData (mb);
-                               Type param_type = pd.ParameterType (0);
+                               AParametersCollection pd = TypeManager.GetParameterData (mb);
+                               Type param_type = pd.Types [0];
 
                                if (param_type == source_type)
                                        return param_type;
@@ -1118,9 +1105,9 @@ namespace Mono.CSharp {
                        }
 
                        foreach (MethodInfo m in mg.Methods) {
-                               ParameterData pd = TypeManager.GetParameterData (m);
+                               AParametersCollection pd = TypeManager.GetParameterData (m);
                                Type return_type = TypeManager.TypeToCoreType (m.ReturnType);
-                               Type arg_type = pd.ParameterType (0);
+                               Type arg_type = pd.Types [0];
 
                                if (source_type != arg_type) {
                                        if (!ImplicitStandardConversionExists (source, arg_type)) {
@@ -1199,7 +1186,7 @@ namespace Mono.CSharp {
                        foreach (MethodInfo m in ops) {
                                if (TypeManager.TypeToCoreType (m.ReturnType) != most_specific_target)
                                        continue;
-                               if (TypeManager.GetParameterData (m).ParameterType (0) != most_specific_source)
+                               if (TypeManager.GetParameterData (m).Types [0] != most_specific_source)
                                        continue;
                                // Ambiguous: more than one conversion operator satisfies the signature.
                                if (method != null)
@@ -1246,7 +1233,7 @@ namespace Mono.CSharp {
                        if (method == null)
                                return null;
 
-                       Type most_specific_source = TypeManager.GetParameterData (method).ParameterType (0);
+                       Type most_specific_source = TypeManager.GetParameterData (method).Types [0];
 
                        //
                        // This will do the conversion to the best match that we
@@ -1351,8 +1338,11 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (expr_type.Equals (target_type) && expr_type != TypeManager.null_type)
-                               return expr;
+                       if (expr_type.Equals (target_type)) {
+                               if (expr_type != TypeManager.null_type && expr_type != TypeManager.anonymous_method_type)
+                                       return expr;
+                               return null;
+                       }
 
                        //
                        // Attempt to do the implicit constant expression conversions
@@ -1384,11 +1374,17 @@ namespace Mono.CSharp {
                        if (e != null)
                                return e;
 
-                       if (TypeManager.IsEnumType (target_type) && expr is IntLiteral){
-                               IntLiteral i = (IntLiteral) expr;
-
-                               if (i.Value == 0)
-                                       return new EnumConstant ((Constant) expr, target_type);
+                       if (expr is IntConstant && TypeManager.IsEnumType (target_type)){
+                               Constant i = (Constant) expr;
+                               //
+                               // LAMESPEC: Conversion from any 0 constant is allowed
+                               //
+                               // An implicit enumeration conversion permits the decimal-integer-literal 0
+                               // to be converted to any enum-type and to any nullable-type whose underlying
+                               // type is an enum-type
+                               //
+                               if (i.IsDefaultValue)
+                                       return new EnumConstant (i, target_type);
                        }
 
                        if (ec.InUnsafe) {
@@ -1971,11 +1967,11 @@ namespace Mono.CSharp {
                                //
                                // LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
                                //
-                if (expr_type == TypeManager.intptr_type || expr_type == TypeManager.uintptr_type) {
+                               if (expr_type == TypeManager.intptr_type || expr_type == TypeManager.uintptr_type) {
                                        ne = ExplicitUserConversion (ec, expr, TypeManager.GetEnumUnderlyingType (target_type), loc);
                                        if (ne != null)
                                                return ExplicitConversionCore (ec, ne, target_type, loc);
-                }
+                               }
                                
                                return null;
                        }