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