[mono-api-html] Print string fields with no (or null) value without an NRE.
[mono.git] / mcs / mcs / dynamic.cs
index ade105cb00a9b30f30f107a02243f99e59fcde64..939984e5c6b41e972d3ce4e8facebc77bf89b276 100644 (file)
@@ -13,7 +13,7 @@ using System;
 using System.Linq;
 using SLE = System.Linq.Expressions;
 
-#if NET_4_0
+#if NET_4_0 || MOBILE_DYNAMIC
 using System.Dynamic;
 #endif
 
@@ -63,7 +63,7 @@ namespace Mono.CSharp
        //
        public class RuntimeValueExpression : Expression, IDynamicAssign, IMemoryLocation
        {
-#if !NET_4_0
+#if !NET_4_0 && !MOBILE_DYNAMIC
                public class DynamicMetaObject
                {
                        public TypeSpec RuntimeType;
@@ -146,7 +146,7 @@ namespace Mono.CSharp
                        return base.MakeExpression (ctx);
 #else
 
-       #if NET_4_0             
+#if NET_4_0 || MOBILE_DYNAMIC
                                if (type.IsStruct && !obj.Expression.Type.IsValueType)
                                        return SLE.Expression.Unbox (obj.Expression, type.GetMetaInfo ());
 
@@ -181,7 +181,7 @@ namespace Mono.CSharp
                        return this;
                }
 
-#if NET_4_0
+#if NET_4_0 || MOBILE_DYNAMIC
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
 #if STATIC
@@ -224,8 +224,8 @@ namespace Mono.CSharp
                //
                protected class BinderFlags : EnumConstant
                {
-                       DynamicExpressionStatement statement;
-                       CSharpBinderFlags flags;
+                       readonly DynamicExpressionStatement statement;
+                       readonly CSharpBinderFlags flags;
 
                        public BinderFlags (CSharpBinderFlags flags, DynamicExpressionStatement statement)
                                : base (statement.loc)
@@ -391,7 +391,7 @@ namespace Mono.CSharp
                        if (!has_ref_out_argument) {
                                string d_name = isStatement ? "Action" : "Func";
 
-                               TypeExpr te = null;
+                               TypeSpec te = null;
                                Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
                                if (type_ns != null) {
                                        te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
@@ -412,9 +412,9 @@ namespace Mono.CSharp
                                                targs[targs.Length - 1] = new TypeExpression (t, loc);
                                        }
 
-                                       del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc);
+                                       del_type = new GenericTypeExpr (te, new TypeArguments (targs), loc);
                                        if (targs_for_instance != null)
-                                               del_type_instance_access = new GenericTypeExpr (te.Type, new TypeArguments (targs_for_instance), loc);
+                                               del_type_instance_access = new GenericTypeExpr (te, new TypeArguments (targs_for_instance), loc);
                                        else
                                                del_type_instance_access = del_type;
                                }
@@ -447,8 +447,17 @@ namespace Mono.CSharp
                                d.CreateContainer ();
                                d.DefineContainer ();
                                d.Define ();
+                               d.PrepareEmit ();
 
                                site.AddTypeContainer (d);
+
+                               //
+                               // Add new container to inflated site container when the
+                               // member cache already exists
+                               //
+                               if (site.CurrentType is InflatedTypeSpec && index > 0)
+                                       site.CurrentType.MemberCache.AddMember (d.CurrentType);
+
                                del_type = new TypeExpression (d.CurrentType, loc);
                                if (targs_for_instance != null) {
                                        del_type_instance_access = null;
@@ -495,41 +504,45 @@ namespace Mono.CSharp
                        FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);
 
                        BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);
-                       SymbolWriter.OpenCompilerGeneratedBlock (ec);
 
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (binder));
                        StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args)));
-                       
-                       if (s.Resolve (bc)) {
-                               Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc), loc), s, loc);
-                               init.Emit (ec);
-                       }
 
-                       args = new Arguments (1 + dyn_args_count);
-                       args.Add (new Argument (site_field_expr));
-                       if (arguments != null) {
-                               int arg_pos = 1;
-                               foreach (Argument a in arguments) {
-                                       if (a is NamedArgument) {
-                                               // Name is not valid in this context
-                                               args.Add (new Argument (a.Expr, a.ArgType));
-                                       } else {
-                                               args.Add (a);
-                                       }
-
-                                       if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
-                                               a.Expr.Type = targs[arg_pos].Type;
+                       using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
+                               if (s.Resolve (bc)) {
+                                       Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
+                                       init.Emit (ec);
+                               }
 
-                                       ++arg_pos;
+                               args = new Arguments (1 + dyn_args_count);
+                               args.Add (new Argument (site_field_expr));
+                               if (arguments != null) {
+                                       int arg_pos = 1;
+                                       foreach (Argument a in arguments) {
+                                               if (a is NamedArgument) {
+                                                       // Name is not valid in this context
+                                                       args.Add (new Argument (a.Expr, a.ArgType));
+                                               } else {
+                                                       args.Add (a);
+                                               }
+
+                                               if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
+                                                       a.Expr.Type = targs[arg_pos].Type;
+
+                                               ++arg_pos;
+                                       }
                                }
-                       }
 
-                       Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
-                       if (target != null)
-                               target.Emit (ec);
+                               Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
+                               if (target != null)
+                                       target.Emit (ec);
+                       }
+               }
 
-                       SymbolWriter.CloseCompilerGeneratedBlock (ec);
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       arguments.FlowAnalysis (fc);
                }
 
                public static MemberAccess GetBinderNamespace (Location loc)
@@ -608,7 +621,14 @@ namespace Mono.CSharp
                public override void EmitStatement (EmitContext ec)
                {
                        var stmt = new If (condition, new StatementExpression (invoke), new StatementExpression (assign), loc);
-                       stmt.Emit (ec);
+                       using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
+                               stmt.Emit (ec);
+                       }
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       invoke.FlowAnalysis (fc);
                }
        }
 
@@ -733,15 +753,6 @@ namespace Mono.CSharp
                        this.member = member;
                }
 
-               //
-               // When a return type is known not to be dynamic
-               //
-               public DynamicInvocation (ATypeNameExpression member, Arguments args, TypeSpec type, Location loc)
-                       : this (member, args, loc)
-               {
-                       this.type = type;
-               }
-
                public static DynamicInvocation CreateSpecialNameInvoke (ATypeNameExpression member, Arguments args, Location loc)
                {
                        return new DynamicInvocation (member, args, loc) {
@@ -957,7 +968,7 @@ namespace Mono.CSharp
        sealed class DynamicSiteClass : HoistedStoreyClass
        {
                public DynamicSiteClass (TypeDefinition parent, MemberBase host, TypeParameters tparams)
-                       : base (parent, MakeMemberName (host, "DynamicSite", parent.DynamicSitesCounter, tparams, Location.Null), tparams, Modifiers.STATIC)
+                       : base (parent, MakeMemberName (host, "DynamicSite", parent.DynamicSitesCounter, tparams, Location.Null), tparams, Modifiers.STATIC, MemberKind.Class)
                {
                        parent.DynamicSitesCounter++;
                }