*** empty log message ***
[mono.git] / mcs / mcs / expression.cs
index 6ef1a72693f62acc11f4fa24f1bc483c821457a7..47062869ba4d7debd08537c82e3f4ba17dfd3f9d 100755 (executable)
@@ -15,9 +15,9 @@
 //
 
 namespace CIR {
+       using System;
        using System.Collections;
        using System.Diagnostics;
-       using System;
        using System.Reflection;
        using System.Reflection.Emit;
        using System.Text;
@@ -325,9 +325,13 @@ namespace CIR {
                        string right = name.Substring (dot_pos + 1);
                        Type t;
 
-                       if ((t = tc.LookupType (left, false)) != null)
+                       if ((t = tc.LookupType (left, false)) != null){
+                               Expression e;
+                               
                                left_e = new TypeExpr (t);
-                       else {
+                               e = new MemberAccess (left_e, right);
+                               return e.Resolve (tc);
+                       } else {
                                //
                                // FIXME: IMplement:
                                
@@ -374,21 +378,53 @@ namespace CIR {
                                        return new EmptyCast (expr, target_type);
                                if (expr_type.IsValueType)
                                        return new BoxedCast (expr);
-                       } else if (expr_type.IsSubclassOf (target_type))
+                       } else if (expr_type.IsSubclassOf (target_type)) {
                                return new EmptyCast (expr, target_type);
-                       else 
-                               // FIXME: missing implicit reference conversions:
-                               // 
+                       } else {
                                // from any class-type S to any interface-type T.
+                               if (expr_type.IsClass && target_type.IsInterface) {
+                                       Type [] interfaces = expr_type.FindInterfaces (Module.FilterTypeName,
+                                                                                      target_type.FullName);
+                                       if (interfaces != null)
+                                               return new EmptyCast (expr, target_type);
+                               }       
+
                                // from any interface type S to interface-type T.
+                               // FIXME : Is it right to use IsAssignableFrom ?
+                               if (expr_type.IsInterface && target_type.IsInterface)
+                                       if (target_type.IsAssignableFrom (expr_type))
+                                               return new EmptyCast (expr, target_type);
+                               
+                               
                                // from an array-type S to an array-type of type T
+                               if (expr_type.IsArray && target_type.IsArray) {
+                                       
+                                       throw new Exception ("Implement array conversion");
+                                       
+                               }
+                               
                                // from an array-type to System.Array
+                               if (expr_type.IsArray && target_type.IsAssignableFrom (expr_type))
+                                       return new EmptyCast (expr, target_type);
+                               
                                // from any delegate type to System.Delegate
+                               if (expr_type.IsSubclassOf (TypeManager.delegate_type) &&
+                                   target_type == TypeManager.delegate_type)
+                                       if (target_type.IsAssignableFrom (expr_type))
+                                               return new EmptyCast (expr, target_type);
+                                       
                                // from any array-type or delegate type into System.ICloneable.
+                               if (expr_type.IsArray || expr_type.IsSubclassOf (TypeManager.delegate_type))
+                                       if (target_type == TypeManager.cloneable_interface)
+                                               throw new Exception ("Implement conversion to System.ICloneable");
+                               
                                // from the null type to any reference-type.
-                                    
+                               // FIXME : How do we do this ?
+
                                return null;
 
+                       }
+                       
                        return null;
                }
 
@@ -402,9 +438,8 @@ namespace CIR {
 
                        args.Add (new Argument (expr, Argument.AType.Expression));
 
-                       Console.WriteLine ("The InternalTypeConstructor is: " + expr);
                        Expression ne = new New (target.FullName, args,
-                                                new Location ("FIXME", 1, 1));
+                                                new Location (-1));
 
                        return ne.Resolve (tc);
                }
@@ -601,7 +636,7 @@ namespace CIR {
 
                                method = Invocation.OverloadResolve (tc, union, arguments, l, true);
 
-                               if (method != null) {
+                               if (method != null) { 
                                        MethodInfo mi = (MethodInfo) method;
                                        
                                        if (mi.ReturnType == target)
@@ -625,8 +660,7 @@ namespace CIR {
                                arguments = new ArrayList ();
                                arguments.Add (new Argument (source, Argument.AType.Expression));
                        
-                               method = Invocation.OverloadResolve (tc, union, arguments,
-                                                                    new Location ("FIXME", 1, 1), true);
+                               method = Invocation.OverloadResolve (tc, union, arguments, l, true);
                                if (method != null) {
                                        MethodInfo mi = (MethodInfo) method;
 
@@ -947,7 +981,6 @@ namespace CIR {
                                // ushort, int, uint, long, ulong,
                                // char, float or decimal
                                //
-                               Console.WriteLine ("Ok, I am a double " + target_type);
                                if (target_type == TypeManager.sbyte_type)
                                        return new OpcodeCast (expr, target_type, OpCodes.Conv_I1);
                                if (target_type == TypeManager.byte_type)
@@ -1298,7 +1331,7 @@ namespace CIR {
                        if (expr.Type == target_type)
                                return expr;
 
-                       return ConvertImplicit (tc, expr, target_type, new Location ("FIXME", 1, 1));
+                       return ConvertImplicit (tc, expr, target_type, new Location (-1));
                }
 
                void report23 (Report r, Type t)
@@ -1347,6 +1380,9 @@ namespace CIR {
                                op_name = "op_" + oper;
 
                        mg = MemberLookup (tc, expr_type, op_name, false);
+
+                       if (mg == null && expr_type != TypeManager.object_type)
+                               mg = MemberLookup (tc, expr_type.BaseType, op_name, false);
                        
                        if (mg != null) {
                                Arguments = new ArrayList ();
@@ -1447,7 +1483,7 @@ namespace CIR {
                                // It is also not clear if we should convert to Float
                                // or Double initially.
                                //
-                               Location l = new Location ("FIXME", 1, 1);
+                               Location l = new Location (-1);
                                
                                if (expr_type == TypeManager.uint32_type){
                                        //
@@ -1894,7 +1930,7 @@ namespace CIR {
                        if (expr.Type == target_type)
                                return expr;
 
-                       return ConvertImplicit (tc, expr, target_type, new Location ("FIXME", 1, 1));
+                       return ConvertImplicit (tc, expr, target_type, new Location (-1));
                }
                
                //
@@ -2066,7 +2102,13 @@ namespace CIR {
 
                        left_expr = MemberLookup (tc, l, op, false);
 
+                       if (left_expr == null && l != TypeManager.object_type)
+                               left_expr = MemberLookup (tc, l.BaseType, op, false);
+                       
                        right_expr = MemberLookup (tc, r, op, false);
+                       if (right_expr != null && r != TypeManager.object_type)
+                               right_expr = MemberLookup (tc, r.BaseType, op, false);
+                       
 
                        MethodGroupExpr union = Invocation.MakeUnionSet (left_expr, right_expr);
 
@@ -3550,8 +3592,12 @@ namespace CIR {
                }
        }
 
+       // <summary>
+       //   Implements the typeof operator
+       // </summary>
        public class TypeOf : Expression {
                public readonly string QueriedType;
+               Type typearg;
                
                public TypeOf (string queried_type)
                {
@@ -3560,19 +3606,20 @@ namespace CIR {
 
                public override Expression DoResolve (TypeContainer tc)
                {
-                       type = tc.LookupType (QueriedType, false);
+                       typearg = tc.LookupType (QueriedType, false);
 
-                       if (type == null)
+                       if (typearg == null)
                                return null;
-                       
+
+                       type = TypeManager.type_type;
                        eclass = ExprClass.Type;
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
-                       throw new Exception ("Implement me");
-                       // FIXME: Implement.
+                       ec.ig.Emit (OpCodes.Ldtoken, typearg);
+                       ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
                }
        }