2008-06-11 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / ecore.cs
index db9467305b45cb465108bef5ca34115055c21308..9470b01ac6fc4efaa1107081a56d21971bbb060b 100644 (file)
@@ -97,15 +97,10 @@ namespace Mono.CSharp {
                void AddressOf (EmitContext ec, AddressOp mode);
        }
 
-       /// <summary>
-       ///   This interface is implemented by variables
-       /// </summary>
+       // TODO: Rename to something meaningful, this is flow-analysis interface only
        public interface IVariable {
-               VariableInfo VariableInfo {
-                       get;
-               }
-
-               bool VerifyFixed ();
+               VariableInfo VariableInfo { get; }
+               bool IsFixed { get; }
        }
 
        /// <remarks>
@@ -393,12 +388,6 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       if (Type != TypeManager.string_type && this is Constant && !(this is EmptyConstantCast)) {
-                               Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
-                                       ((Constant)(this)).GetValue ().ToString (), TypeManager.CSharpName (target));
-                               return;
-                       }
-
                        Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
                                TypeManager.CSharpName (type),
                                TypeManager.CSharpName (target));
@@ -1390,9 +1379,7 @@ namespace Mono.CSharp {
                }
 
                public override bool IsNull {
-                       get     {
-                               return child.IsNull;
-                       }
+                       get { return child.IsNull; }
                }
        }
 
@@ -1408,6 +1395,10 @@ namespace Mono.CSharp {
                        if (c != null)
                                return new EmptyConstantCast (c, type);
 
+                       EmptyCast e = child as EmptyCast;
+                       if (e != null)
+                               return new EmptyCast (e.child, type);
+
                        return new EmptyCast (child, type);
                }
 
@@ -1420,7 +1411,6 @@ namespace Mono.CSharp {
                {
                        child.EmitSideEffect (ec);
                }
-
        }
 
        /// <summary>
@@ -3412,8 +3402,11 @@ namespace Mono.CSharp {
                                //
                                if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) {
                                        p = TypeManager.GetTypeArguments (p) [0];
+                               }
+                               if (TypeManager.DropGenericTypeArguments (q) == TypeManager.expression_type) {
                                        q = TypeManager.GetTypeArguments (q) [0];
                                }
+                               
                                p = Delegate.GetInvokeMethod (null, p).ReturnType;
                                q = Delegate.GetInvokeMethod (null, q).ReturnType;
                        } else {
@@ -3639,8 +3632,18 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
+                       if (best_candidate == null) {
+                               Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
+                               return null;
+                       }
+
                        if (best_candidate.IsConstructor)
                                return new TypeOfConstructorInfo (best_candidate, loc);
+
+                       IMethodData md = TypeManager.GetMethod (best_candidate);
+                       if (md != null && md.IsExcluded ())
+                               Report.Error (765, loc,
+                                       "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
                        return new TypeOfMethodInfo (best_candidate, loc);
                }
@@ -3860,21 +3863,13 @@ namespace Mono.CSharp {
                                return 0;
                        }
 
-                       // FIXME: Kill this abomination (EmitContext.TempEc)
-                       EmitContext prevec = EmitContext.TempEc;
-                       EmitContext.TempEc = ec;
-                       try {
-                               if (delegate_type != null ?
-                                       !Delegate.IsTypeCovariant (argument.Expr, parameter) :
-                                       !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
-                                       return 2;
-
-                               if (arg_mod != param_mod)
-                                       return 1;
+                       if (delegate_type != null ?
+                               !Delegate.IsTypeCovariant (argument.Expr, parameter) :
+                               !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+                               return 2;
 
-                       } finally {
-                               EmitContext.TempEc = prevec;
-                       }
+                       if (arg_mod != param_mod)
+                               return 1;
 
                        return 0;
                }
@@ -4747,7 +4742,7 @@ namespace Mono.CSharp {
 
                        // If the instance expression is a local variable or parameter.
                        IVariable var = InstanceExpression as IVariable;
-                       if ((var == null) || (var.VariableInfo == null))
+                       if (var == null || var.VariableInfo == null)
                                return this;
 
                        VariableInfo vi = var.VariableInfo;
@@ -4798,7 +4793,7 @@ namespace Mono.CSharp {
                override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        IVariable var = InstanceExpression as IVariable;
-                       if ((var != null) && (var.VariableInfo != null))
+                       if (var != null && var.VariableInfo != null)
                                var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
 
                        bool lvalue_instance = !FieldInfo.IsStatic && FieldInfo.DeclaringType.IsValueType;
@@ -4860,19 +4855,20 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool VerifyFixed ()
-               {
-                       IVariable variable = InstanceExpression as IVariable;
-                       // A variable of the form V.I is fixed when V is a fixed variable of a struct type.
-                       // We defer the InstanceExpression check after the variable check to avoid a 
-                       // separate null check on InstanceExpression.
-                       return variable != null && InstanceExpression.Type.IsValueType && variable.VerifyFixed ();
-               }
-
                public override int GetHashCode ()
                {
                        return FieldInfo.GetHashCode ();
                }
+               
+               public bool IsFixed {
+                       get {
+                               IVariable variable = InstanceExpression as IVariable;
+                               // A variable of the form V.I is fixed when V is a fixed variable of a struct type.
+                               // We defer the InstanceExpression check after the variable check to avoid a 
+                               // separate null check on InstanceExpression.
+                               return variable != null && InstanceExpression.Type.IsValueType && variable.IsFixed;
+                       }
+               }               
 
                public override bool Equals (object obj)
                {
@@ -5093,8 +5089,9 @@ namespace Mono.CSharp {
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
+                       ArrayList args;
                        if (IsSingleDimensionalArrayLength ()) {
-                               ArrayList args = new ArrayList (1);
+                               args = new ArrayList (1);
                                args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
                                return CreateExpressionFactoryCall ("ArrayLength", args);
                        }
@@ -5104,12 +5101,13 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       // TODO: it's waiting for PropertyExpr refactoring
-                       //ArrayList args = new ArrayList (2);
-                       //args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
-                       //args.Add (getter expression);
-                       //return CreateExpressionFactoryCall ("Property", args);
-                       throw new NotImplementedException ();
+                       args = new ArrayList (2);
+                       if (InstanceExpression == null)
+                               args.Add (new Argument (new NullLiteral (loc)));
+                       else
+                               args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
+                       args.Add (new Argument (new TypeOfMethodInfo (getter, loc)));
+                       return CreateExpressionFactoryCall ("Property", args);
                }
 
                public Expression CreateSetterTypeOfExpression ()
@@ -5259,7 +5257,7 @@ namespace Mono.CSharp {
 
                        string t_name = InstanceExpression.Type.Name;
                        int t_name_len = t_name.Length;
-                       return t_name_len > 2 && t_name [t_name_len - 2] == '[' && t_name [t_name_len - 3] != ']';
+                       return t_name_len > 2 && t_name [t_name_len - 2] == '[';
                }
 
                override public Expression DoResolve (EmitContext ec)
@@ -5650,28 +5648,28 @@ namespace Mono.CSharp {
                }
        }
 
-       public class TemporaryVariable : Expression, IMemoryLocation
+       public class TemporaryVariable : VariableReference
        {
                LocalInfo li;
                Variable var;
-               
+
                public TemporaryVariable (Type type, Location loc)
                {
                        this.type = type;
                        this.loc = loc;
-                       eclass = ExprClass.Value;
+                       eclass = ExprClass.Variable;
                }
 
                public override Expression CreateExpressionTree (EmitContext ec)
                {
                        throw new NotSupportedException ("ET");
                }
-               
+
                public override Expression DoResolve (EmitContext ec)
                {
                        if (li != null)
                                return this;
-                       
+
                        TypeExpr te = new TypeExpression (type, loc);
                        li = ec.CurrentBlock.AddTemporaryVariable (te, loc);
                        if (!li.Resolve (ec))
@@ -5682,46 +5680,34 @@ namespace Mono.CSharp {
                                var = scope.AddLocal (li);
                                type = var.Type;
                        }
-                       
+
                        return this;
                }
 
-               public Variable Variable {
-                       get { return var != null ? var : li.Variable; }
-               }
-               
                public override void Emit (EmitContext ec)
                {
-                       Variable.EmitInstance (ec);
-                       Variable.Emit (ec);
+                       Emit (ec, false);
                }
-               
-               public void EmitLoadAddress (EmitContext ec)
+
+               public void EmitAssign (EmitContext ec, Expression source)
                {
-                       Variable.EmitInstance (ec);
-                       Variable.EmitAddressOf (ec);
+                       EmitAssign (ec, source, false, false);
                }
-               
-               public void Store (EmitContext ec, Expression right_side)
-               {
-                       Variable.EmitInstance (ec);
-                       right_side.Emit (ec);
-                       Variable.EmitAssign (ec);
+
+               public override bool IsFixed {
+                       get { return true; }
                }
-               
-               public void EmitThis (EmitContext ec)
-               {
-                       Variable.EmitInstance (ec);
+
+               public override bool IsRef {
+                       get { return false; }
                }
-               
-               public void EmitStore (EmitContext ec)
-               {
-                       Variable.EmitAssign (ec);
+
+               public override Variable Variable {
+                       get { return var != null ? var : li.Variable; }
                }
-               
-               public void AddressOf (EmitContext ec, AddressOp mode)
-               {
-                       EmitLoadAddress (ec);
+
+               public override VariableInfo VariableInfo {
+                       get { throw new NotImplementedException (); }
                }
        }