Merge pull request #2698 from esdrubal/iosxmlarray
[mono.git] / mcs / mcs / expression.cs
index 67bffce8561e9365fc074ab11cfbecf64a70100b..bfba44fbb8c656079254fc346737ea8a4af5fd3e 100644 (file)
@@ -110,8 +110,9 @@ namespace Mono.CSharp
                protected override Expression DoResolve (ResolveContext rc)
                {
                        Expression res = null;
-
-                       res = expr.Resolve (rc);
+                       using (rc.With (ResolveContext.Options.DontSetConditionalAccessReceiver, false)) {
+                               res = expr.Resolve (rc);
+                       }
 
                        var constant = res as Constant;
                        if (constant != null && constant.IsLiteral) {
@@ -6013,16 +6014,19 @@ namespace Mono.CSharp
                                }
 
                                right.Emit (ec);
-                               switch (rtype.BuiltinType) {
-                               case BuiltinTypeSpec.Type.SByte:
-                               case BuiltinTypeSpec.Type.Byte:
-                               case BuiltinTypeSpec.Type.Short:
-                               case BuiltinTypeSpec.Type.UShort:
-                                       ec.Emit (OpCodes.Conv_I);
-                                       break;
-                               case BuiltinTypeSpec.Type.UInt:
-                                       ec.Emit (OpCodes.Conv_U);
-                                       break;
+                               if (right_const == null) {
+                                       switch (rtype.BuiltinType) {
+                                       case BuiltinTypeSpec.Type.SByte:
+                                       case BuiltinTypeSpec.Type.Byte:
+                                       case BuiltinTypeSpec.Type.Short:
+                                       case BuiltinTypeSpec.Type.UShort:
+                                       case BuiltinTypeSpec.Type.Int:
+                                               ec.Emit (OpCodes.Conv_I);
+                                               break;
+                                       case BuiltinTypeSpec.Type.UInt:
+                                               ec.Emit (OpCodes.Conv_U);
+                                               break;
+                                       }
                                }
 
                                if (right_const == null && size != 1){
@@ -6461,7 +6465,7 @@ namespace Mono.CSharp
                        }
 
                        New n_source = source as New;
-                       if (n_source != null) {
+                       if (n_source != null && n_source.CanEmitOptimizedLocalTarget (ec)) {
                                if (!n_source.Emit (ec, this)) {
                                        if (leave_copy) {
                                                EmitLoad (ec);
@@ -7177,7 +7181,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec);
+                       return new DynamicInvocation (expr as ATypeNameExpression, args, conditional_access_receiver, loc).Resolve (ec);
                }
 
                protected virtual MethodGroupExpr DoResolveOverload (ResolveContext ec)
@@ -7601,6 +7605,11 @@ namespace Mono.CSharp
                                ec.Emit (OpCodes.Pop);
                }
 
+               public virtual bool CanEmitOptimizedLocalTarget (EmitContext ec)
+               {
+                       return true;
+               }
+
                public override void FlowAnalysis (FlowAnalysisContext fc)
                {
                        if (arguments != null)
@@ -9715,6 +9724,8 @@ namespace Mono.CSharp
                                return retval;
                        }
 
+                       var cma = this as ConditionalMemberAccess;
+
                        MemberExpr me;
                        TypeSpec expr_type = expr.Type;
                        if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
@@ -9724,10 +9735,13 @@ namespace Mono.CSharp
 
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr));
+
+                               if (cma != null)
+                                       return new DynamicConditionalMemberBinder (Name, args, loc);
+
                                return new DynamicMemberBinder (Name, args, loc);
                        }
 
-                       var cma = this as ConditionalMemberAccess;
                        if (cma != null) {
                                if (!IsNullPropagatingValid (expr.Type)) {
                                        expr.Error_OperatorCannotBeApplied (rc, loc, "?", expr.Type);
@@ -10858,7 +10872,7 @@ namespace Mono.CSharp
                                args.AddRange (arguments);
 
                                best_candidate = null;
-                               return new DynamicIndexBinder (args, loc);
+                               return new DynamicIndexBinder (args, conditional_access_receiver, ConditionalAccess, loc);
                        }
 
                        //
@@ -11666,7 +11680,6 @@ namespace Mono.CSharp
                                args.Add (new Argument (rc.CurrentInitializerVariable));
                                target = new DynamicMemberBinder (Name, args, loc);
                        } else {
-
                                var member = MemberLookup (rc, false, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
                                if (member == null) {
                                        member = Expression.MemberLookup (rc, true, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
@@ -12129,7 +12142,7 @@ namespace Mono.CSharp
 
                public override void Emit (EmitContext ec)
                {
-                       if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) && initializers.ContainsEmitWithAwait ()) {
+                       if (!CanEmitOptimizedLocalTarget (ec)) {
                                var fe = ec.GetTemporaryField (type);
 
                                if (!Emit (ec, fe))
@@ -12217,6 +12230,13 @@ namespace Mono.CSharp
                        return true;
                }
 
+               public override bool CanEmitOptimizedLocalTarget (EmitContext ec)
+               {
+                       return !(method == null && TypeSpec.IsValueType (type) &&
+                                       initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) &&
+                                       initializers.ContainsEmitWithAwait ());
+               }
+
                protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
                {
                        instance = base.EmitAddressOf (ec, Mode);
@@ -12500,11 +12520,6 @@ namespace Mono.CSharp
                                str = start.Value;
                                arguments = new Arguments (1);
                        } else {
-                               for (int i = 0; i < interpolations.Count; i += 2) {
-                                       var ipi = (InterpolatedStringInsert)interpolations [i];
-                                       ipi.Resolve (rc);
-                               }
-       
                                arguments = new Arguments (interpolations.Count);
 
                                var sb = new StringBuilder (start.Value);
@@ -12525,7 +12540,7 @@ namespace Mono.CSharp
                                                }
 
                                                sb.Append ('}');
-                                               arguments.Add (new Argument (interpolations [i]));
+                                               arguments.Add (new Argument (isi.Resolve (rc)));
                                        } else {
                                                sb.Append (((StringLiteral)interpolations [i]).Value);
                                        }
@@ -12563,6 +12578,15 @@ namespace Mono.CSharp
                        ca.Emit (ec, best, arguments, loc);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (interpolations != null) {
+                               foreach (var expr in interpolations) {
+                                       expr.FlowAnalysis (fc);
+                               }
+                       }
+               }
+
                MethodSpec ResolveBestFormatOverload (ResolveContext rc)
                {
                        var members = MemberCache.FindMembers (rc.BuiltinTypes.String, "Format", true);
@@ -12602,6 +12626,11 @@ namespace Mono.CSharp
                        return Convert.ImplicitConversionRequired (rc, expr, rc.BuiltinTypes.Object, expr.Location);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Child.FlowAnalysis (fc);
+               }
+
                public int? ResolveAligment (ResolveContext rc)
                {
                        var c = Alignment.ResolveLabelConstant (rc);