X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fnullable.cs;h=c5ec3b4ff86a72b86d75117fb1413292e9b2bcfd;hb=07d69753d509f305d975819ffa4c803e2b1bcc12;hp=0f84d59b9e74b570bb2245e22f6b966a40829f3b;hpb=e38feeb62009d2a5fe0afa99a5bdce3c3a538138;p=mono.git diff --git a/mcs/mcs/nullable.cs b/mcs/mcs/nullable.cs index 0f84d59b9e7..c5ec3b4ff86 100644 --- a/mcs/mcs/nullable.cs +++ b/mcs/mcs/nullable.cs @@ -14,7 +14,6 @@ using System; using System.Reflection; using System.Reflection.Emit; -using System.Collections; namespace Mono.CSharp.Nullable { @@ -74,7 +73,7 @@ namespace Mono.CSharp.Nullable Value = value_pi.GetGetMethod (false); // When compiling corlib - if (type.Module == RootContext.ToplevelTypes.Builder) { + if (TypeManager.IsBeingCompiled (type)) { TypeContainer tc = TypeManager.LookupGenericTypeContainer (type); // TODO: check for correct overload @@ -85,7 +84,7 @@ namespace Mono.CSharp.Nullable } #if MS_COMPATIBLE - if (UnderlyingType.Module == RootContext.ToplevelTypes.Builder) { + if (TypeManager.IsBeingCompiled (UnderlyingType)) { ConstructorInfo cinfo = TypeManager.DropGenericTypeArguments (type).GetConstructors ()[0]; Constructor = TypeBuilder.GetConstructor (type, cinfo); return; @@ -137,7 +136,7 @@ namespace Mono.CSharp.Nullable return expr.CreateExpressionTree (ec); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { return this; } @@ -205,12 +204,10 @@ namespace Mono.CSharp.Nullable LocalVariable.Emit (ec); } -#if NET_4_0 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx) { return expr.MakeExpression (ctx); } -#endif public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { @@ -276,7 +273,7 @@ namespace Mono.CSharp.Nullable throw new NotSupportedException ("ET"); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { return this; } @@ -337,10 +334,10 @@ namespace Mono.CSharp.Nullable // // Represents null literal lifted to nullable type // - public class LiftedNull : EmptyConstantCast, IMemoryLocation + public class LiftedNull : NullConstant, IMemoryLocation { private LiftedNull (Type nullable_type, Location loc) - : base (new NullLiteral (loc), nullable_type) + : base (nullable_type, loc) { eclass = ExprClass.Value; } @@ -358,15 +355,6 @@ namespace Mono.CSharp.Nullable return ReducedExpression.Create (Create (e.Type, e.Location), e); } - public override Expression CreateExpressionTree (ResolveContext ec) - { - Arguments args = new Arguments (2); - args.Add (new Argument (this)); - args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); - - return CreateExpressionFactoryCall (ec, "Constant", args); - } - public override void Emit (EmitContext ec) { // TODO: generate less temporary variables @@ -387,9 +375,12 @@ namespace Mono.CSharp.Nullable } } + // + // Generic lifting expression, supports all S/S? -> T/T? cases + // public class Lifted : Expression, IMemoryLocation { - Expression expr, wrap, null_value; + Expression expr, null_value; Unwrap unwrap; public Lifted (Expression expr, Unwrap unwrap, Type type) @@ -407,22 +398,33 @@ namespace Mono.CSharp.Nullable public override Expression CreateExpressionTree (ResolveContext ec) { - return wrap.CreateExpressionTree (ec); + return expr.CreateExpressionTree (ec); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { - wrap = Wrap.Create (expr, type); - if (wrap == null) - return null; - // - // It's null when lifted conversion is transparent + // It's null when lifting non-nullable type // - if (unwrap == null) - return wrap; + if (unwrap == null) { + // S -> T? is wrap only + if (TypeManager.IsNullableType (type)) + return Wrap.Create (expr, type); + + // S -> T can be simplified + return expr; + } + + // Wrap target for T? + if (TypeManager.IsNullableType (type)) { + expr = Wrap.Create (expr, type); + if (expr == null) + return null; - null_value = LiftedNull.Create (type, loc); + null_value = LiftedNull.Create (type, loc); + } else { + null_value = new NullConstant (type, loc); + } eclass = ExprClass.Value; return this; @@ -437,12 +439,12 @@ namespace Mono.CSharp.Nullable unwrap.EmitCheck (ec); ig.Emit (OpCodes.Brfalse, is_null_label); - wrap.Emit (ec); - ig.Emit (OpCodes.Br, end_label); + expr.Emit (ec); + ig.Emit (OpCodes.Br, end_label); ig.MarkLabel (is_null_label); - null_value.Emit (ec); + null_value.Emit (ec); ig.MarkLabel (end_label); } @@ -478,11 +480,8 @@ namespace Mono.CSharp.Nullable return base.CreateExpressionTree (ec); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { - if (eclass != ExprClass.Invalid) - return this; - unwrap = Unwrap.Create (Expr, false); if (unwrap == null) return null; @@ -599,7 +598,7 @@ namespace Mono.CSharp.Nullable Expression CreateNullConstant (ResolveContext ec, Expression expr) { // FIXME: Handle side effect constants - Constant c = new BoolConstant (Oper == Operator.Inequality, loc); + Constant c = new BoolConstant (Oper == Operator.Inequality, loc).Resolve (ec); if ((Oper & Operator.EqualityMask) != 0) { ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is `{1}'", @@ -612,11 +611,8 @@ namespace Mono.CSharp.Nullable return ReducedExpression.Create (c, this); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { - if (eclass != ExprClass.Invalid) - return this; - if ((Oper & Operator.LogicalMask) != 0) { Error_OperatorCannotBeApplied (ec, left, right); return null; @@ -906,7 +902,7 @@ namespace Mono.CSharp.Nullable // Value types and null comparison // if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0) - return CreateNullConstant (ec, left_orig).Resolve (ec); + return CreateNullConstant (ec, left_orig); } return res_expr; @@ -1023,7 +1019,7 @@ namespace Mono.CSharp.Nullable // Reduce (left ?? null) to left OR (null-constant ?? right) to right // if (right.IsNull || lc != null) - return ReducedExpression.Create (lc != null ? right : left, this).Resolve (ec); + return ReducedExpression.Create (lc != null ? right : left, this); right = Convert.ImplicitConversion (ec, right, ltype, loc); type = left.Type; @@ -1041,18 +1037,15 @@ namespace Mono.CSharp.Nullable // Reduce (null ?? right) to right // if (left.IsNull) - return ReducedExpression.Create (right, this).Resolve (ec); + return ReducedExpression.Create (right, this); left = Convert.ImplicitConversion (ec, unwrap != null ? unwrap : left, rtype, loc); type = rtype; return this; } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { - if (eclass != ExprClass.Invalid) - return this; - left = left.Resolve (ec); right = right.Resolve (ec); @@ -1131,8 +1124,6 @@ namespace Mono.CSharp.Nullable this.expr = expr; this.Mode = mode; this.loc = loc; - - eclass = ExprClass.Value; } public override Expression CreateExpressionTree (ResolveContext ec) @@ -1140,7 +1131,7 @@ namespace Mono.CSharp.Nullable return new SimpleAssign (this, this).CreateExpressionTree (ec); } - public override Expression DoResolve (ResolveContext ec) + protected override Expression DoResolve (ResolveContext ec) { expr = expr.Resolve (ec); if (expr == null) @@ -1154,6 +1145,8 @@ namespace Mono.CSharp.Nullable if (underlying == null) return null; + + eclass = ExprClass.Value; type = expr.Type; return this; }