* mb-parser.jay: Removed 'static_constructor_declaration' - this is not required...
[mono.git] / mcs / mbas / expression.cs
index e7dc2050a7467945a42fd32b2c2e0706d4e66764..e59f8f8c26e9e5fb0016e063f43e1ace6dda5e65 100644 (file)
@@ -9,7 +9,7 @@
 //
 #define USE_OLD
 
-namespace Mono.CSharp {
+namespace Mono.MonoBASIC {
        using System;
        using System.Collections;
        using System.Reflection;
@@ -143,7 +143,7 @@ namespace Mono.CSharp {
                        Error (
                                23, "Operator " + OperName (Oper) +
                                " cannot be applied to operand of type '" +
-                               TypeManager.CSharpName (t) + "'");
+                               TypeManager.MonoBASIC_Name (t) + "'");
                }
 
                /// <remarks>
@@ -484,7 +484,7 @@ namespace Mono.CSharp {
                        }
 
                        Error (187, "No such operator '" + OperName (Oper) + "' defined for type '" +
-                              TypeManager.CSharpName (expr_type) + "'");
+                              TypeManager.MonoBASIC_Name (expr_type) + "'");
                        return null;
                }
 
@@ -692,7 +692,7 @@ namespace Mono.CSharp {
                        Error (
                                23, "Operator " + OperName (mode) + 
                                " cannot be applied to operand of type '" +
-                               TypeManager.CSharpName (t) + "'");
+                               TypeManager.MonoBASIC_Name (t) + "'");
                }
 
                /// <summary>
@@ -781,7 +781,7 @@ namespace Mono.CSharp {
                        }
 
                        Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
-                              TypeManager.CSharpName (expr_type) + "'");
+                              TypeManager.MonoBASIC_Name (expr_type) + "'");
                        return null;
                }
 
@@ -1074,13 +1074,13 @@ namespace Mono.CSharp {
                                        Warning (
                                                183,
                                                "The expression is always of type '" +
-                                               TypeManager.CSharpName (probe_type) + "'");
+                                               TypeManager.MonoBASIC_Name (probe_type) + "'");
                                else if (warning_never_matches){
                                        if (!(probe_type.IsInterface || expr.Type.IsInterface))
                                                Warning (
                                                        184,
                                                        "The expression is never of type '" +
-                                                       TypeManager.CSharpName (probe_type) + "'");
+                                                       TypeManager.MonoBASIC_Name (probe_type) + "'");
                                }
                        }
 
@@ -1113,8 +1113,8 @@ namespace Mono.CSharp {
                {
                        Report.Error (
                                39, loc, "as operator can not convert from '" +
-                               TypeManager.CSharpName (source) + "' to '" +
-                               TypeManager.CSharpName (target) + "'");
+                               TypeManager.MonoBASIC_Name (source) + "' to '" +
+                               TypeManager.MonoBASIC_Name (target) + "'");
                }
                
                public override Expression DoResolve (EmitContext ec)
@@ -1130,7 +1130,7 @@ namespace Mono.CSharp {
 
                        if (TypeManager.IsValueType (probe_type)){
                                Report.Error (77, loc, "The as operator should be used with a reference type only (" +
-                                             TypeManager.CSharpName (probe_type) + " is a value type");
+                                             TypeManager.MonoBASIC_Name (probe_type) + " is a value type)");
                                return null;
                        
                        }
@@ -1647,8 +1647,8 @@ namespace Mono.CSharp {
                        Report.Error (
                                34, loc, "Operator '" + OperName (oper) 
                                + "' is ambiguous on operands of type '"
-                               + TypeManager.CSharpName (l) + "' "
-                               + "and '" + TypeManager.CSharpName (r)
+                               + TypeManager.MonoBASIC_Name (l) + "' "
+                               + "and '" + TypeManager.MonoBASIC_Name (r)
                                + "'");
                }
 
@@ -1814,8 +1814,8 @@ namespace Mono.CSharp {
                {
                        Report.Error (19, loc,
                               "Operator " + name + " cannot be applied to operands of type '" +
-                              TypeManager.CSharpName (l) + "' and '" +
-                              TypeManager.CSharpName (r) + "'");
+                              TypeManager.MonoBASIC_Name (l) + "' and '" +
+                              TypeManager.MonoBASIC_Name (r) + "'");
                }
                
                void Error_OperatorCannotBeApplied ()
@@ -2752,8 +2752,8 @@ namespace Mono.CSharp {
                                        if (ConvertImplicit (ec, falseExpr, true_type, loc) != null){
                                                Error (172,
                                                       "Can not compute type of conditional expression " +
-                                                      "as '" + TypeManager.CSharpName (trueExpr.Type) +
-                                                      "' and '" + TypeManager.CSharpName (falseExpr.Type) +
+                                                      "as '" + TypeManager.MonoBASIC_Name (trueExpr.Type) +
+                                                      "' and '" + TypeManager.MonoBASIC_Name (falseExpr.Type) +
                                                       "' convert implicitly to each other");
                                                return null;
                                        }
@@ -2765,8 +2765,8 @@ namespace Mono.CSharp {
                                } else {
                                        Error (173, "The type of the conditional expression can " +
                                               "not be computed because there is no implicit conversion" +
-                                              " from '" + TypeManager.CSharpName (trueExpr.Type) + "'" +
-                                              " and '" + TypeManager.CSharpName (falseExpr.Type) + "'");
+                                              " from '" + TypeManager.MonoBASIC_Name (trueExpr.Type) + "'" +
+                                              " and '" + TypeManager.MonoBASIC_Name (falseExpr.Type) + "'");
                                        return null;
                                }
                        }
@@ -3136,10 +3136,10 @@ namespace Mono.CSharp {
        public class Invocation : ExpressionStatement {
                public ArrayList Arguments;
 
-               Expression expr;
+               public Expression expr;
                MethodBase method = null;
                bool is_base;
-
+               bool is_left_hand; // Needed for late bound calls
                static Hashtable method_parameter_cache;
                static MemberFilter CompareName;
 
@@ -3422,7 +3422,7 @@ namespace Mono.CSharp {
                        string ret_type = "";
 
                        if (mb is MethodInfo)
-                               ret_type = TypeManager.CSharpName (((MethodInfo) mb).ReturnType) + " ";
+                               ret_type = TypeManager.MonoBASIC_Name (((MethodInfo) mb).ReturnType) + " ";
                        
                        StringBuilder sb = new StringBuilder (ret_type + mb.Name);
                        ParameterData pd = GetParameterData (mb);
@@ -3573,8 +3573,8 @@ namespace Mono.CSharp {
                                ~(Parameter.Modifier.OUT | Parameter.Modifier.REF);
 
                        if (a_mod == p_mod || (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
-                               if (a_mod == Parameter.Modifier.NONE)
-                                       if (!ImplicitConversionExists (ec, a.Expr, ptype))
+                               if (a_mod == Parameter.Modifier.NONE)                                   
+                                       if (! (ImplicitConversionExists (ec, a.Expr, ptype) || RuntimeConversionExists (ec, a.Expr, ptype)) )
                                                return false;
                                
                                if ((a_mod & Parameter.Modifier.ISBYREF) != 0) {
@@ -3587,8 +3587,7 @@ namespace Mono.CSharp {
                                                return false;
                                }
                        } else
-                               return false;           
-                               
+                               return false;                                   
                        return true;                                    
                }
                
@@ -3768,7 +3767,7 @@ namespace Mono.CSharp {
                        Type current_type = null;
                        int argument_count;
                        ArrayList candidates = new ArrayList ();
-                       
+
                        foreach (MethodBase candidate in me.Methods){
                                int x;
 
@@ -3909,10 +3908,15 @@ namespace Mono.CSharp {
                        for (int j = 0; j < argument_count; j++) {
                                Argument a = (Argument) Arguments [j];
                                Expression a_expr = a.Expr;
-                               Type parameter_type = pd.ParameterType (j);
-                               
+                               Type parameter_type = pd.ParameterType(j);
+                                       
+                               if (parameter_type == null)
+                               {
+                                       Error_WrongNumArguments(loc, (InvokingProperty == null)?((delegate_type == null)?FullMethodDesc (method):delegate_type.ToString ()):InvokingProperty, argument_count);
+                                       return false;   
+                               }
                                if (pd.ParameterModifier (j) == Parameter.Modifier.PARAMS &&
-                                   chose_params_expanded)
+                               chose_params_expanded)
                                        parameter_type = TypeManager.TypeToCoreType (parameter_type.GetElementType ());
 
                                if (a.Type != parameter_type){
@@ -3977,6 +3981,12 @@ namespace Mono.CSharp {
 
                        return true;
                }
+       
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       this.is_left_hand = true;
+                       return DoResolve (ec);
+               }
 
                public override Expression DoResolve (EmitContext ec)
                {
@@ -3989,15 +3999,24 @@ namespace Mono.CSharp {
                        if (expr is BaseAccess)
                                is_base = true;
 
-                       expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       if ((ec.ReturnType != null) && (expr.ToString() == ec.BlockName)) {
+                               ec.InvokingOwnOverload = true;
+                               expr = expr.Resolve (ec, ResolveFlags.MethodGroup);
+                               ec.InvokingOwnOverload = false;
+                       }
+                       else                            
+                       {
+                               ec.InvokingOwnOverload = false;
+                               expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       }       
                        if (expr == null)
                                return null;
-                               
+
                        if (expr is Invocation) {
                                // FIXME Calls which return an Array are not resolved (here or in the grammar)
                                expr = expr.Resolve(ec);
                        }
-                       
+
                        if (!(expr is MethodGroupExpr)) 
                        {
                                Type expr_type = expr.Type;
@@ -4025,7 +4044,7 @@ namespace Mono.CSharp {
                                                return null;                            
                                }
                        }
-
+                       
                        if (expr is MethodGroupExpr) 
                        {
                                MethodGroupExpr mg = (MethodGroupExpr) expr;
@@ -4081,25 +4100,67 @@ namespace Mono.CSharp {
                                        expr_to_return = pe.DoResolve (ec);
                                        expr_to_return.eclass = ExprClass.PropertyAccess;
                                }
+                               else
+                               {
+                                       throw new Exception("Error resolving Property Access expression\n" + pe.ToString());
+                               }
                        }
 
-                       if (expr is FieldExpr || expr is LocalVariableReference) {
-                               // If we are here, expr must be an ArrayAccess
-                               // FIXME: we should check dimensions, etc.
-                               ArrayList idxs = new ArrayList();
-                               foreach (Argument a in Arguments) 
+                       if (expr is FieldExpr || expr is LocalVariableReference || expr is ParameterReference) {
+                               if (expr.Type.IsArray) {
+                                       // If we are here, expr must be an ArrayAccess
+                                       ArrayList idxs = new ArrayList();
+                                       foreach (Argument a in Arguments)
+                                       {
+                                               idxs.Add (a.Expr);
+                                       }
+                                       ElementAccess ea = new ElementAccess (expr, idxs, expr.Location);
+                                       ArrayAccess aa = new ArrayAccess (ea, expr.Location);
+                                       expr_to_return = aa.DoResolve(ec);
+                                       expr_to_return.eclass = ExprClass.Variable;
+                               }
+                               else
                                {
-                                       idxs.Add (a.Expr);
+                                       // We can't resolve now, but we
+                                       // have to try to access the array with a call
+                                       // to LateIndexGet/Set in the runtime
+                                       Expression lig_call_expr;
+
+                                       if (!is_left_hand)
+                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
+                                       else
+                                               lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexSet", Location.Null);
+                                       Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
+                                       ArrayList adims = new ArrayList();
+
+                                       ArrayList ainit = new ArrayList();
+                                       foreach (Argument a in Arguments)
+                                               ainit.Add ((Expression) a.Expr);
+
+                                       adims.Add ((Expression) new IntLiteral (Arguments.Count));
+
+                                       Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
+
+                                       ArrayList args = new ArrayList();
+                                       args.Add (new Argument(expr, Argument.AType.Expression));
+                                       args.Add (new Argument(oace, Argument.AType.Expression));
+                                       args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
+
+                                       Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
+                                       expr_to_return = lig_call.Resolve(ec);
+                                       expr_to_return.eclass = ExprClass.Variable;
                                }
-                               ElementAccess ea = new ElementAccess (expr, idxs, expr.Location);
-                               ArrayAccess aa = new ArrayAccess (ea, expr.Location);
-                               expr_to_return = aa.DoResolve(ec);
-                               expr_to_return.eclass = ExprClass.Variable;
                        }
 
                        return expr_to_return;
                }
 
+        static void Error_WrongNumArguments (Location loc, String name, int arg_count)
+        {
+            Report.Error (1501, loc, "No overload for method `" + name + "' takes `" +
+                                      arg_count + "' arguments");
+        }
+
                // <summary>
                //   Emits the list of arguments as an array
                // </summary>
@@ -4464,8 +4525,8 @@ namespace Mono.CSharp {
 
                        if (type.IsInterface || type.IsAbstract){
                                Error (
-                                       144, "It is not possible to create instances of interfaces " +
-                                       "or abstract classes");
+                                       30376, "It is not possible to create instances of Interfaces " +
+                                       "or classes marked as MustInherit");
                                return null;
                        }
                        
@@ -4687,7 +4748,6 @@ namespace Mono.CSharp {
                public bool CheckIndices (EmitContext ec, ArrayList probe, int idx, bool specified_dims)
                {
                        if (specified_dims) { 
-                               Console.WriteLine  ("specified_dims");
                                Argument a = (Argument) arguments [idx];
                                
                                if (!a.Resolve (ec, loc))
@@ -4897,6 +4957,7 @@ namespace Mono.CSharp {
                        //
                        Expression array_type_expr;
                        array_type_expr = new ComposedCast (requested_base_type, array_qualifier.ToString (), loc);
+                       string sss = array_qualifier.ToString ();
                        type = ec.DeclSpace.ResolveType (array_type_expr, false, loc);
 
                        if (type == null)
@@ -5505,7 +5566,7 @@ namespace Mono.CSharp {
                                return null;
 
                        if (!TypeManager.IsUnmanagedType (type_queried)){
-                               Report.Error (208, "Cannot take the size of an unmanaged type (" + TypeManager.CSharpName (type_queried) + ")");
+                               Report.Error (208, "Cannot take the size of an unmanaged type (" + TypeManager.MonoBASIC_Name (type_queried) + ")");
                                return null;
                        }
                        
@@ -5806,7 +5867,7 @@ namespace Mono.CSharp {
 
                        if (expr_type.IsPointer){
                                Error (23, "The '.' operator can not be applied to pointer operands (" +
-                                      TypeManager.CSharpName (expr_type) + ")");
+                                      TypeManager.MonoBASIC_Name (expr_type) + ")");
                                return null;
                        }
 
@@ -5827,7 +5888,7 @@ namespace Mono.CSharp {
                                        BindingFlags.NonPublic, Identifier);
                                        
                                if (lookup == null)
-                                       Error (117, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
+                                       Error (30456, "'" + expr_type + "' does not contain a definition for '" + Identifier + "'");
                                else
                                {
                                        if ((expr_type != ec.ContainerType) &&
@@ -5847,14 +5908,14 @@ namespace Mono.CSharp {
                                                if (lookup != null)
                                                        Error (1540, "Cannot access protected member '" +
                                                       expr_type + "." + Identifier + "' " +
-                                                      "via a qualifier of type '" + TypeManager.CSharpName (expr_type) + "'; the " +
-                                                      "qualifier must be of type '" + TypeManager.CSharpName (ec.ContainerType) + "' " +
+                                                      "via a qualifier of type '" + TypeManager.MonoBASIC_Name (expr_type) + "'; the " +
+                                                      "qualifier must be of type '" + TypeManager.MonoBASIC_Name (ec.ContainerType) + "' " +
                                                       "(or derived from it)");
                                                else
-                                                       Error (122, "'" + expr_type + "." + Identifier + "' " +
+                                                       Error (30390, "'" + expr_type + "." + Identifier + "' " +
                                                       "is inaccessible because of its protection level");
                                        } else
-                                               Error (122, "'" + expr_type + "." + Identifier + "' " +
+                                               Error (30390, "'" + expr_type + "." + Identifier + "' " +
                                               "is inaccessible because of its protection level");
                                }  
                                return null;
@@ -6118,7 +6179,7 @@ namespace Mono.CSharp {
                ElementAccess ea;
 
                LocalTemporary [] cached_locations;
-               
+
                public ArrayAccess (ElementAccess ea_data, Location l)
                {
                        ea = ea_data;
@@ -6140,6 +6201,35 @@ namespace Mono.CSharp {
 #endif
 
                        Type t = ea.Expr.Type;
+/*
+                       if (t == typeof (System.Object))
+                       {
+                               // We can't resolve now, but we
+                               // have to try to access the array with a call
+                               // to LateIndexGet in the runtime
+
+                               Expression lig_call_expr = Mono.MonoBASIC.Parser.DecomposeQI("Microsoft.VisualBasic.CompilerServices.LateBinding.LateIndexGet", Location.Null);
+                               Expression obj_type = Mono.MonoBASIC.Parser.DecomposeQI("System.Object", Location.Null);
+                               ArrayList adims = new ArrayList();
+
+                               ArrayList ainit = new ArrayList();
+                               foreach (Argument a in ea.Arguments)
+                                       ainit.Add ((Expression) a.Expr);
+
+                               adims.Add ((Expression) new IntLiteral (ea.Arguments.Count));
+
+                               Expression oace = new ArrayCreation (obj_type, adims, "", ainit, Location.Null);
+
+                               ArrayList args = new ArrayList();
+                               args.Add (new Argument(ea.Expr, Argument.AType.Expression));
+                               args.Add (new Argument(oace, Argument.AType.Expression));
+                               args.Add (new Argument(NullLiteral.Null, Argument.AType.Expression));
+
+                               Expression lig_call = new Invocation (lig_call_expr, args, Location.Null);
+                               lig_call = lig_call.Resolve(ec);
+                               return lig_call;
+                       }
+*/
                        if (t.GetArrayRank () != ea.Arguments.Count){
                                ea.Error (22,
                                          "Incorrect number of indexes for array " +
@@ -6511,7 +6601,7 @@ namespace Mono.CSharp {
                        }
 
                        Report.Error (21, loc,
-                                     "Type '" + TypeManager.CSharpName (lookup_type) +
+                                     "Type '" + TypeManager.MonoBASIC_Name (lookup_type) +
                                      "' does not have any indexers defined");
                        return null;
                }
@@ -6615,7 +6705,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (set == null){
-                               Error (200, "indexer X.this [" + TypeManager.CSharpName (right_type) +
+                               Error (200, "indexer X.this [" + TypeManager.MonoBASIC_Name (right_type) +
                                       "] lacks a 'set' accessor");
                                return null;
                        }
@@ -6645,7 +6735,7 @@ namespace Mono.CSharp {
        ///   The base operator for method names
        /// </summary>
        public class BaseAccess : Expression {
-               string member;
+               public string member;
                
                public BaseAccess (string member, Location l)
                {
@@ -6672,8 +6762,8 @@ namespace Mono.CSharp {
                                                      AllMemberTypes, AllBindingFlags, loc);
 
                        if (member_lookup == null) {
-                               Error (117,
-                                             TypeManager.CSharpName (base_type) + " does not " +
+                               Error (30456,
+                                             TypeManager.MonoBASIC_Name (base_type) + " does not " +
                                              "contain a definition for '" + member + "'");
                                return null;
                        }