Author: marek
Date: 2008-01-24 04:41:53 -0500 (Thu, 24 Jan 2008)
New Revision: 93767

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/convert.cs
   trunk/mcs/mcs/ecore.cs
   trunk/mcs/mcs/expression.cs
   trunk/mcs/mcs/generic.cs
Log:
2008-01-24  Marek Safar  <[EMAIL PROTECTED]>

        * convert.cs, ecore.cs, expression.cs, generic.cs: Implemented Coalesce 
and
        Condition expressions.
        


Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2008-01-24 08:44:24 UTC (rev 93766)
+++ trunk/mcs/mcs/ChangeLog     2008-01-24 09:41:53 UTC (rev 93767)
@@ -1,3 +1,8 @@
+2008-01-24  Marek Safar  <[EMAIL PROTECTED]>
+
+       * convert.cs, ecore.cs, expression.cs, generic.cs: Implemented Coalesce 
and
+       Condition expressions.
+       
 2008-01-23  Marek Safar  <[EMAIL PROTECTED]>
 
        * codegen.cs: Fixed AssemblyBuilder initialization on other platforms.

Modified: trunk/mcs/mcs/convert.cs
===================================================================
--- trunk/mcs/mcs/convert.cs    2008-01-24 08:44:24 UTC (rev 93766)
+++ trunk/mcs/mcs/convert.cs    2008-01-24 09:41:53 UTC (rev 93767)
@@ -1305,14 +1305,15 @@
                {
                        Type expr_type = expr.Type;
                        Expression e;
+                       
 #if GMCS_SOURCE
-                       // TODO: refactor to be a part of constant 
infrastructure
-                       if (expr is NullLiteral) {
-                           if (TypeManager.IsNullableType (target_type))
-                               return new Nullable.NullableLiteral 
(target_type, loc);
-                       }
-
                        if (TypeManager.IsNullableType (target_type)) {
+                               //
+                               // From null to any nullable type
+                               //
+                               if (expr_type == TypeManager.null_type)
+                                       return new Nullable.Null (target_type, 
loc);
+                               
                                Type target = TypeManager.GetTypeArguments 
(target_type) [0];
 
                                if (TypeManager.IsNullableType (expr.Type)) {
@@ -2112,10 +2113,10 @@
                                                return Nullable.Wrap.Create (e, 
ec);
                                }
                        } else if (TypeManager.IsNullableType (expr_type)) {
-                               Expression source = Nullable.Unwrap.Create 
(expr, ec);
-                               if (source != null) {
-                                       return ExplicitConversion (ec, source, 
target_type, loc);
-                               }
+                               e = ExplicitConversion (ec, 
Nullable.Unwrap.Create (expr, ec), target_type, loc);
+                               if (e != null)
+                                       e = EmptyCast.Create (e, target_type);
+                               return e;
                        }
 #endif
                        e = ExplicitConversionCore (ec, expr, target_type, loc);

Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs      2008-01-24 08:44:24 UTC (rev 93766)
+++ trunk/mcs/mcs/ecore.cs      2008-01-24 09:41:53 UTC (rev 93767)
@@ -926,7 +926,7 @@
                        if (operator_group == null)
                                return null;
 
-                       return new StaticCallExpr ((MethodInfo) operator_group, 
arguments, loc);
+                       return new UserOperatorCall (operator_group, arguments, 
null, loc);
                }
 
                /// <summary>
@@ -3645,7 +3645,8 @@
                                                return score - 20000;
 
                                        if 
(TypeManager.IsGenericMethodDefinition (candidate))
-                                               throw new 
InternalErrorException ("a generic method definition took part in overload 
resolution");
+                                               throw new 
InternalErrorException ("A generic method `{0}' definition took part in 
overload resolution",
+                                                       
TypeManager.CSharpSignature (candidate));
 
                                        pd = TypeManager.GetParameterData 
(candidate);
                                }

Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2008-01-24 08:44:24 UTC (rev 93766)
+++ trunk/mcs/mcs/expression.cs 2008-01-24 09:41:53 UTC (rev 93767)
@@ -17,25 +17,43 @@
        using System.Reflection.Emit;
        using System.Text;
 
-       /// <summary>
-       ///   This is just a helper class, it is generated by Unary, 
UnaryMutator
-       ///   when an overloaded method has been found.  It just emits the code 
for a
-       ///   static call.
-       /// </summary>
-       public class StaticCallExpr : ExpressionStatement {
-               ArrayList args;
-               MethodInfo mi;
+       //
+       // This is an user operator expression, automatically created during
+       // resolve phase
+       //
+       public class UserOperatorCall : Expression {
+               public delegate Expression ExpressionTreeExpression 
(EmitContext ec, MethodGroupExpr mg);
 
-               public StaticCallExpr (MethodInfo m, ArrayList a, Location l)
+               readonly ArrayList arguments;
+               readonly MethodGroupExpr mg;
+               readonly ExpressionTreeExpression expr_tree;
+
+               public UserOperatorCall (MethodGroupExpr mg, ArrayList args, 
ExpressionTreeExpression expr_tree, Location loc)
                {
-                       mi = m;
-                       args = a;
+                       this.mg = mg;
+                       this.arguments = args;
+                       this.expr_tree = expr_tree;
 
-                       type = m.ReturnType;
+                       type = ((MethodInfo)mg).ReturnType;
                        eclass = ExprClass.Value;
-                       loc = l;
+                       this.loc = loc;
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       if (expr_tree != null)
+                               return expr_tree (ec, mg);
+
+                       ArrayList args = new ArrayList (arguments.Count + 1);
+                       args.Add (new Argument (new NullConstant 
(loc).CreateExpressionTree (ec)));
+                       args.Add (new Argument (mg.CreateExpressionTree (ec)));
+                       foreach (Argument a in arguments) {
+                               args.Add (new Argument 
(a.Expr.CreateExpressionTree (ec)));
+                       }
+
+                       return CreateExpressionFactoryCall ("Call", args);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        //
@@ -46,12 +64,11 @@
 
                public override void Emit (EmitContext ec)
                {
-                       Invocation.EmitArguments (ec, args, false, null);
-                       ec.ig.Emit (OpCodes.Call, mi);
-                       return;
+                       mg.EmitCall (ec, arguments);
                }
-               
-               static public StaticCallExpr MakeSimpleCall (EmitContext ec, 
MethodGroupExpr mg,
+
+               [Obsolete ("It may not be compatible with expression trees")]
+               static public UserOperatorCall MakeSimpleCall (EmitContext ec, 
MethodGroupExpr mg,
                                                         Expression e, Location 
loc)
                {
                        ArrayList args;
@@ -69,18 +86,12 @@
                        if (mg == null)
                                return null;
 
-                       return new StaticCallExpr ((MethodInfo) mg, args, loc);
+                       return new UserOperatorCall (mg, args, null, loc);
                }
 
-               public override void EmitStatement (EmitContext ec)
-               {
-                       Emit (ec);
-                       if (TypeManager.TypeToCoreType (type) != 
TypeManager.void_type)
-                               ec.ig.Emit (OpCodes.Pop);
-               }
-               
+               [Obsolete ("It may not be compatible with expression trees")]
                public MethodInfo Method {
-                       get { return mi; }
+                       get { return (MethodInfo)mg; }
                }
        }
 
@@ -370,17 +381,18 @@
                        Type expr_type = Expr.Type;
                        string op_name = oper_names [(int) Oper];
 
-                       Expression mg = MemberLookup (ec.ContainerType, 
expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
-                       if (mg != null) {
-                               Expression e = StaticCallExpr.MakeSimpleCall (
-                                       ec, (MethodGroupExpr) mg, Expr, loc);
+                       MethodGroupExpr user_op = MemberLookup 
(ec.ContainerType, expr_type, op_name, MemberTypes.Method, AllBindingFlags, 
loc) as MethodGroupExpr;
+                       if (user_op != null) {
+                               ArrayList args = new ArrayList (1);
+                               args.Add (new Argument (Expr));
+                               user_op = user_op.OverloadResolve (ec, ref 
args, false, loc);
 
-                               if (e == null){
+                               if (user_op == null) {
                                        Error23 (expr_type);
                                        return null;
                                }
-                               
-                               return e;
+
+                               return new UserOperatorCall (user_op, args, 
CreateExpressionTree, loc);
                        }
 
                        switch (Oper){
@@ -568,6 +580,30 @@
                        return null;
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       return CreateExpressionTree (ec, null);
+               }
+
+               Expression CreateExpressionTree (EmitContext ec, 
MethodGroupExpr user_op)
+               {
+                       string method_name; 
+                       switch (Oper) {
+                               case Operator.UnaryNegation:
+                                       method_name = "Negate";
+                                       break;
+
+                               default:
+                                       throw new InternalErrorException 
("Unknown unary operator " + Oper.ToString ());
+                       }
+
+                       ArrayList args = new ArrayList (2);
+                       args.Add (new Argument (Expr.CreateExpressionTree 
(ec)));
+                       if (user_op != null)
+                               args.Add (new Argument 
(user_op.CreateExpressionTree (ec)));
+                       return CreateExpressionFactoryCall (method_name, args);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        if (Oper == Operator.AddressOf) {
@@ -604,7 +640,7 @@
                public override void Emit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       
+
                        switch (Oper) {
                        case Operator.UnaryPlus:
                                throw new Exception ("This should be caught by 
Resolve");
@@ -800,7 +836,7 @@
                //
                // This is expensive for the simplest case.
                //
-               StaticCallExpr method;
+               UserOperatorCall method;
 
                public UnaryMutator (Mode m, Expression e, Location l)
                {
@@ -856,7 +892,7 @@
                        mg = MemberLookup (ec.ContainerType, expr_type, 
op_name, MemberTypes.Method, AllBindingFlags, loc);
 
                        if (mg != null) {
-                               method = StaticCallExpr.MakeSimpleCall (
+                               method = UserOperatorCall.MakeSimpleCall (
                                        ec, (MethodGroupExpr) mg, expr, loc);
 
                                type = method.Type;
@@ -1280,8 +1316,8 @@
                        Type etype = expr.Type;
 
                        if (type.IsValueType && !TypeManager.IsNullableType 
(type)) {
-                               Report.Error (77, loc, "The as operator must be 
used with a reference type (`" +
-                                             TypeManager.CSharpName (type) + 
"' is a value type)");
+                               Report.Error (77, loc, "The `as' operator 
cannot be used with a non-nullable value type `{0}'",
+                                             TypeManager.CSharpName (type));
                                return null;
                        
                        }
@@ -3044,6 +3080,12 @@
                        case Operator.BitwiseAnd:
                                method_name = "And";
                                break;
+                       case Operator.GreaterThan:
+                               method_name = "GreaterThan";
+                               break;
+                       case Operator.LessThan:
+                               method_name = "LessThan";
+                               break;
                        case Operator.LogicalAnd:
                                method_name = "AndAlso";
                                break;
@@ -3227,9 +3269,12 @@
        
        //
        // User-defined conditional logical operator
+       //
        public class ConditionalLogicalOperator : Expression {
                Expression left, right;
                bool is_and;
+               Expression op_true, op_false, op;
+               LocalTemporary left_temp;
 
                public ConditionalLogicalOperator (bool is_and, Expression 
left, Expression right, Type t, Location loc)
                {
@@ -3252,9 +3297,6 @@
                               "declarations of operator true and operator 
false");
                }
 
-               Expression op_true, op_false, op;
-               LocalTemporary left_temp;
-
                public override Expression DoResolve (EmitContext ec)
                {
                        MethodGroupExpr operator_group;
@@ -3283,7 +3325,7 @@
                                return null;
                        }
 
-                       op = new StaticCallExpr (method, arguments, loc);
+                       op = new UserOperatorCall (operator_group, arguments, 
null, loc);
 
                        op_true = GetOperatorTrue (ec, left_temp, loc);
                        op_false = GetOperatorFalse (ec, left_temp, loc);
@@ -3444,6 +3486,15 @@
                        }
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       ArrayList args = new ArrayList (3);
+                       args.Add (new Argument (expr.CreateExpressionTree 
(ec)));
+                       args.Add (new Argument (true_expr.CreateExpressionTree 
(ec)));
+                       args.Add (new Argument (false_expr.CreateExpressionTree 
(ec)));
+                       return CreateExpressionFactoryCall ("Condition", args);
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        expr = expr.Resolve (ec);
@@ -5342,7 +5393,7 @@
 
                        return true;
                }
-               
+
                public override Expression CreateExpressionTree (EmitContext ec)
                {
                        if (dimensions != 1) {

Modified: trunk/mcs/mcs/generic.cs
===================================================================
--- trunk/mcs/mcs/generic.cs    2008-01-24 08:44:24 UTC (rev 93766)
+++ trunk/mcs/mcs/generic.cs    2008-01-24 09:41:53 UTC (rev 93767)
@@ -3163,7 +3163,6 @@
 
                        public override Expression DoResolve (EmitContext ec)
                        {
-                               expr = expr.Resolve (ec);
                                if (expr == null)
                                        return null;
 
@@ -3284,7 +3283,6 @@
 
                        public override Expression DoResolve (EmitContext ec)
                        {
-                               expr = expr.Resolve (ec);
                                if (expr == null)
                                        return null;
 
@@ -3306,14 +3304,23 @@
                        }
                }
 
-               public class NullableLiteral : NullLiteral, IMemoryLocation {
-                       public NullableLiteral (Type target_type, Location loc)
-                               : base (loc)
+               //
+               // Represents null value converted to nullable type
+               //
+               public class Null : Expression, IMemoryLocation
+               {
+                       public Null (Type target_type, Location loc)
                        {
                                this.type = target_type;
+                               this.loc = loc;
 
                                eclass = ExprClass.Value;
                        }
+                       
+                       public override Expression CreateExpressionTree 
(EmitContext ec)
+                       {
+                               return EmptyCast.Create (new NullConstant 
(loc), type).CreateExpressionTree (ec);
+                       }                       
                
                        public override Expression DoResolve (EmitContext ec)
                        {
@@ -3328,6 +3335,12 @@
                                ec.ig.Emit (OpCodes.Initobj, type);
                                value_target.Emit (ec);
                        }
+                       
+                       public override bool IsNull {
+                               get {
+                                       return true;
+                               }
+                       }                       
 
                        public void AddressOf (EmitContext ec, AddressOp Mode)
                        {
@@ -3368,7 +3381,7 @@
                                if (wrap == null)
                                        return null;
 
-                               null_value = new NullableLiteral (wrap.Type, 
loc).Resolve (ec);
+                               null_value = new Null (wrap.Type, loc).Resolve 
(ec);
                                if (null_value == null)
                                        return null;
 
@@ -3445,7 +3458,7 @@
 
                        protected override Expression ResolveUnderlying 
(Expression unwrap, EmitContext ec)
                        {
-                               return new Unary (Oper, unwrap, loc);
+                               return new Unary (Oper, unwrap, loc).Resolve 
(ec);
                        }
                }
 
@@ -3486,7 +3499,7 @@
                                    ((left.Type == TypeManager.bool_type) && 
(right.Type == TypeManager.bool_type))) {
                                        Expression empty = new EmptyExpression 
(TypeManager.bool_type);
                                        bool_wrap = Wrap.Create (empty, ec);
-                                       null_value = new NullableLiteral 
(bool_wrap.Type, loc).Resolve (ec);
+                                       null_value = new Null (bool_wrap.Type, 
loc).Resolve (ec);
 
                                        type = bool_wrap.Type;
                                        is_boolean = true;
@@ -3519,7 +3532,7 @@
                                                return null;
 
                                        type = underlying.Type;
-                                       null_value = new NullableLiteral (type, 
loc).Resolve (ec);
+                                       null_value = new Null (type, 
loc).Resolve (ec);
                                }
 
                                eclass = ExprClass.Value;
@@ -3740,7 +3753,6 @@
                public class NullCoalescingOperator : Expression
                {
                        Expression left, right;
-                       Expression expr;
                        Unwrap unwrap;
 
                        public NullCoalescingOperator (Expression left, 
Expression right, Location loc)
@@ -3748,8 +3760,6 @@
                                this.left = left;
                                this.right = right;
                                this.loc = loc;
-
-                               eclass = ExprClass.Value;
                        }
                        
                        public override Expression CreateExpressionTree 
(EmitContext ec)
@@ -3766,14 +3776,14 @@
                                        return this;
 
                                left = left.Resolve (ec);
-                               if (left == null)
-                                       return null;
+                               right = right.Resolve (ec);
 
-                               right = right.Resolve (ec);
-                               if (right == null)
+                               if (left == null || right == null)
                                        return null;
 
+                               eclass = ExprClass.Value;
                                Type ltype = left.Type, rtype = right.Type;
+                               Expression expr;
 
                                if (TypeManager.IsNullableType (ltype)) {
                                        NullableInfo info = new NullableInfo 
(ltype);
@@ -3785,6 +3795,7 @@
                                        expr = Convert.ImplicitConversion (ec, 
right, info.UnderlyingType, loc);
                                        if (expr != null) {
                                                left = unwrap;
+                                               right = expr;
                                                type = expr.Type;
                                                return this;
                                        }
@@ -3796,6 +3807,7 @@
                                expr = Convert.ImplicitConversion (ec, right, 
ltype, loc);
                                if (expr != null) {
                                        type = expr.Type;
+                                       right = expr;
                                        return this;
                                }
 
@@ -3803,7 +3815,6 @@
                                expr = Convert.ImplicitConversion (ec, 
left_null, rtype, loc);
                                if (expr != null) {
                                        left = expr;
-                                       expr = right;
                                        type = rtype;
                                        return this;
                                }
@@ -3827,7 +3838,7 @@
                                        ig.Emit (OpCodes.Br, end_label);
 
                                        ig.MarkLabel (is_null_label);
-                                       expr.Emit (ec);
+                                       right.Emit (ec);
 
                                        ig.MarkLabel (end_label);
                                } else {
@@ -3838,12 +3849,11 @@
                                        ig.MarkLabel (is_null_label);
 
                                        ig.Emit (OpCodes.Pop);
-                                       expr.Emit (ec);
+                                       right.Emit (ec);
 
                                        ig.MarkLabel (end_label);
                                }
                        }
-
                        protected override void CloneTo (CloneContext clonectx, 
Expression t)
                        {
                                NullCoalescingOperator target = 
(NullCoalescingOperator) t;
@@ -3883,7 +3893,7 @@
                                if (underlying == null)
                                        return null;
 
-                               null_value = new NullableLiteral (expr.Type, 
loc).Resolve (ec);
+                               null_value = new Null (expr.Type, loc).Resolve 
(ec);
                                if (null_value == null)
                                        return null;
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to