2001-09-18 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / mcs / expression.cs
index 4bf101ba845628e33d22d83d29866f37dfcf9a8d..08dfb19ccfb2bbf060ed35340f4555fec2b80257 100755 (executable)
@@ -111,22 +111,10 @@ namespace CIR {
                //
                // This is so we can catch correctly attempts to invoke instance methods
                // from a static body (scan for error 120 in ResolveSimpleName).
-               // 
-               protected static Expression MemberLookup (RootContext rc, Type t, string name, bool same_type)
-               {
-                       MemberTypes mt =
-                               MemberTypes.Constructor |
-                               MemberTypes.Event       |
-                               MemberTypes.Field       |
-                               MemberTypes.Method      |
-                               MemberTypes.NestedType  |
-                               MemberTypes.Property;
-                       
-                       BindingFlags bf =
-                               BindingFlags.Public |
-                               BindingFlags.Static |
-                               BindingFlags.Instance;
-                       
+               //
+               public static Expression MemberLookup (RootContext rc, Type t, string name,
+                                                         bool same_type, MemberTypes mt, BindingFlags bf)
+               {
                        if (same_type)
                                bf |= BindingFlags.NonPublic;
 
@@ -137,7 +125,7 @@ namespace CIR {
                        
                        if (mi.Length == 1 && !(mi [0] is MethodBase))
                                return Expression.ExprClassFromMemberInfo (mi [0]);
-
+                       
                        for (int i = 0; i < mi.Length; i++)
                                if (!(mi [i] is MethodBase)){
                                        rc.Report.Error (-5, "Do not know how to reproduce this case: " + 
@@ -156,6 +144,25 @@ namespace CIR {
 
                        return new MethodGroupExpr (mi);
                }
+
+               public const MemberTypes AllMemberTypes =
+                       MemberTypes.Constructor |
+                       MemberTypes.Event       |
+                       MemberTypes.Field       |
+                       MemberTypes.Method      |
+                       MemberTypes.NestedType  |
+                       MemberTypes.Property;
+               
+               public const BindingFlags AllBindingsFlags =
+                       BindingFlags.Public |
+                       BindingFlags.Static |
+                       BindingFlags.Instance;
+
+               public static Expression MemberLookup (RootContext rc, Type t, string name,
+                                                         bool same_type)
+               {
+                       return MemberLookup (rc, t, name, same_type, AllMemberTypes, AllBindingsFlags);
+               }
                
                // <summary>
                //   Resolves the E in `E.I' side for a member_access
@@ -647,6 +654,7 @@ namespace CIR {
                Expression left, right;
                MethodBase method;
                ArrayList  Arguments;
+               
 
                public Binary (Operator oper, Expression left, Expression right)
                {
@@ -901,9 +909,10 @@ namespace CIR {
                        }
 
                        if (left_expr != null || right_expr != null) {
-
-                               // Now we need to form the union of these two sets and then call OverloadResolve
-                               // on that.
+                               //
+                               // Now we need to form the union of these two sets and
+                               // then call OverloadResolve on that.
+                               //
                                MethodGroupExpr left_set = null, right_set = null;
                                int length1 = 0, length2 = 0;
                                
@@ -916,7 +925,7 @@ namespace CIR {
                                        right_set = (MethodGroupExpr) right_expr;
                                        length2 = right_set.Methods.Length;
                                }
-                               
+
                                MemberInfo [] mi = new MemberInfo [length1 + length2];
                                if (left_set != null)
                                        left_set.Methods.CopyTo (mi, 0);
@@ -928,8 +937,8 @@ namespace CIR {
                                Arguments = new ArrayList ();
                                Arguments.Add (new Argument (left, Argument.AType.Expression));
                                Arguments.Add (new Argument (right, Argument.AType.Expression));
-                               
-                               method = Invocation.OverloadResolve (tc, union, Arguments);
+
+                               method = Invocation.OverloadResolve (union, Arguments);
                                if (method != null)
                                        return this;
 
@@ -1082,11 +1091,29 @@ namespace CIR {
                        OpCode opcode;
 
                        if (method != null) {
-                               if (method is MethodInfo) {
-                                       Invocation.EmitArguments (ec, Arguments);
-                                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
-                                       return;
-                               }
+
+                               bool is_static = method.IsStatic;
+
+                               // FIXME : I am just not able to get this right !!
+                               // There's something wrong with this part which causes
+                               // an InvalidProgramException if this code is emitted
+                               
+                               //if (Arguments != null)
+                               //      Invocation.EmitArguments (ec, Arguments);
+                               
+                               //if (is_static){
+                               //      if (method is MethodInfo)
+                               //              ig.Emit (OpCodes.Call, (MethodInfo) method);
+                               //      else
+                               //              ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                               //} else {
+                               //      if (method is MethodInfo)
+                               //              ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+                               //      else
+                               //              ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
+                               //}
+                               
+                               //return;
                        }
                        
                        left.Emit (ec);
@@ -1519,9 +1546,9 @@ namespace CIR {
                                throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
                        }
                        
-                       if (t == a.Expr.Type)
+                       if (t == a.Expr.Type) 
                                return 0;
-
+                       
                        // FIXME: Implement implicit conversions here.
                        // FIXME: Implement better conversion here.
                        
@@ -1532,7 +1559,7 @@ namespace CIR {
                //   Returns the Parameters (a ParameterData interface) for the
                //   Method `mb'
                // </summary>
-               static ParameterData GetParameterData (TypeContainer tc, MethodBase mb)
+               static ParameterData GetParameterData (MethodBase mb)
                {
                        object pd = method_parameter_cache [mb];
 
@@ -1557,9 +1584,18 @@ namespace CIR {
                
                // <summary>
                //   Find the Applicable Function Members (7.4.2.1)
+               //
+               //   me: Method Group expression with the members to select.
+               //       it might contain constructors or methods (or anything
+               //       that maps to a method).
+               //
+               //   Arguments: ArrayList containing resolved Argument objects.
+               //
+               //   Returns: The MethodBase (either a ConstructorInfo or a MethodInfo)
+               //            that is the best match of me on Arguments.
+               //
                // </summary>
-               public static MethodBase OverloadResolve (TypeContainer tc, MethodGroupExpr me,
-                                                         ArrayList Arguments)
+               public static MethodBase OverloadResolve (MethodGroupExpr me, ArrayList Arguments)
                {
                        ArrayList afm = new ArrayList ();
                        int best_match = 10000;
@@ -1577,7 +1613,7 @@ namespace CIR {
                                MethodBase mb = me.Methods [i];
                                ParameterData pd;
 
-                               pd = GetParameterData (tc, mb);
+                               pd = GetParameterData (mb);
 
                                // If this is the case, we have a method with no args - presumably
                                if (pd == null && argument_count == 0)
@@ -1649,7 +1685,7 @@ namespace CIR {
                                }
                        }
 
-                       method = OverloadResolve (tc, (MethodGroupExpr) this.expr, Arguments);
+                       method = OverloadResolve ((MethodGroupExpr) this.expr, Arguments);
 
                        if (method == null){
                                tc.RootContext.Report.Error (-6,
@@ -1692,20 +1728,22 @@ namespace CIR {
 
                                mg.InstanceExpression.Emit (ec);
                        }
-                       
-                       EmitArguments (ec, Arguments);
 
-                       if (method.IsVirtual){
+                       if (Arguments != null)
+                               EmitArguments (ec, Arguments);
+
+                       if (is_static){
                                if (method is MethodInfo)
-                                       ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+                                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
                                else
-                                       ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
+                                       ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
                        } else {
                                if (method is MethodInfo)
-                                       ec.ig.Emit (OpCodes.Call, (MethodInfo) method);
+                                       ec.ig.Emit (OpCodes.Callvirt, (MethodInfo) method);
                                else
-                                       ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
-                       }
+                                       ec.ig.Emit (OpCodes.Callvirt, (ConstructorInfo) method);
+                       } 
+
                }
        }
 
@@ -1751,20 +1789,8 @@ namespace CIR {
 
                        Expression ml;
 
-                       MemberTypes mt =
-                               MemberTypes.Constructor;
-                       
-                       BindingFlags bf =
-                               BindingFlags.Public |
-                               BindingFlags.Instance;
-                       
-                       MemberInfo [] mi = tc.RootContext.TypeManager.FindMembers (type, mt, bf, null, null);
-
-                       Console.WriteLine ("Found: " + mi.Length);
-                       for (int i = 0; i < mi.Length; i++)
-                               Console.WriteLine (" " + i + ": " + mi [i]);
-                       
-                       ml = MemberLookup (tc.RootContext, type, ".ctor", false);
+                       ml = MemberLookup (tc.RootContext, type, ".ctor", false,
+                                          MemberTypes.Constructor, AllBindingsFlags);
 
                        if (! (ml is MethodGroupExpr)){
                                //
@@ -1784,9 +1810,9 @@ namespace CIR {
                                }
                        }
 
-                       method = Invocation.OverloadResolve (tc, (MethodGroupExpr) ml, Arguments);
+                       method = Invocation.OverloadResolve ((MethodGroupExpr) ml, Arguments);
 
-                       if (method == null){
+                       if (method == null) {
                                tc.RootContext.Report.Error (-6,
                                "New invocation: Can not find a constructor for this argument list");
                                return null;