Merge pull request #5082 from kumpera/fix-ro-fs-file-delete
[mono.git] / mcs / mcs / assign.cs
index 9481aef96edae4b6d66b28b161a9eeb43e0b5b44..43399ffc3ae105be93bdbe212052714c7f7cde95 100644 (file)
@@ -334,7 +334,7 @@ namespace Mono.CSharp {
                                                
                        if (source == null) {
                                ok = false;
-                               source = EmptyExpression.Null;
+                               source = ErrorExpression.Instance;
                        }
 
                        target = target.ResolveLValue (ec, source);
@@ -363,7 +363,6 @@ namespace Mono.CSharp {
                        return this;
                }
 
-#if NET_4_0 || MOBILE_DYNAMIC
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
                {
                        var tassign = target as IDynamicAssign;
@@ -391,7 +390,6 @@ namespace Mono.CSharp {
 
                        return System.Linq.Expressions.Expression.Assign (target_object, source_object);
                }
-#endif
                protected virtual Expression ResolveConversions (ResolveContext ec)
                {
                        source = Convert.ImplicitConversionRequired (ec, source, target.Type, source.Location);
@@ -421,7 +419,13 @@ namespace Mono.CSharp {
                {
                        source.FlowAnalysis (fc);
 
-                       if (target is ArrayAccess || target is IndexerExpr || target is PropertyExpr)
+                       if (target is ArrayAccess || target is IndexerExpr) {
+                               target.FlowAnalysis (fc);
+                               return;
+                       }
+
+                       var pe = target as PropertyExpr;
+                       if (pe != null && !pe.IsAutoPropertyAccess)
                                target.FlowAnalysis (fc);
                }
 
@@ -491,13 +495,17 @@ namespace Mono.CSharp {
                                fe.SetFieldAssigned (fc);
                                return;
                        }
+
+                       var pe = target as PropertyExpr;
+                       if (pe != null) {
+                               pe.SetBackingFieldAssigned (fc);
+                               return;
+                       }
                }
 
-               public override void MarkReachable (Reachability rc)
+               public override Reachability MarkReachable (Reachability rc)
                {
-                       var es = source as ExpressionStatement;
-                       if (es != null)
-                               es.MarkReachable (rc);
+                       return source.MarkReachable (rc);
                }
        }
 
@@ -564,6 +572,9 @@ namespace Mono.CSharp {
                        {
                                flags |= Options.FieldInitializerScope | Options.ConstructorScope;
                                this.ctor_block = constructorContext.CurrentBlock.Explicit;
+
+                               if (ctor_block.IsCompilerGenerated)
+                                       CurrentBlock = ctor_block;
                        }
 
                        public override ExplicitBlock ConstructorBlock {
@@ -589,6 +600,12 @@ namespace Mono.CSharp {
 
                public int AssignmentOffset { get; private set; }
 
+               public FieldBase Field {
+                       get {
+                               return mc;
+                       }
+               }
+
                public override Location StartLocation {
                        get {
                                return loc;
@@ -601,8 +618,8 @@ namespace Mono.CSharp {
                        if (source == null)
                                return null;
 
-                       var bc = (BlockContext) rc;
                        if (resolved == null) {
+                               var bc = (BlockContext) rc;
                                var ctx = new FieldInitializerContext (mc, bc);
                                resolved = base.DoResolve (ctx) as ExpressionStatement;
                                AssignmentOffset = ctx.AssignmentInfoOffset - bc.AssignmentInfoOffset;
@@ -636,6 +653,7 @@ namespace Mono.CSharp {
                public override void FlowAnalysis (FlowAnalysisContext fc)
                {
                        source.FlowAnalysis (fc);
+                       ((FieldExpr) target).SetFieldAssigned (fc);
                }
                
                public bool IsDefaultInitializer {
@@ -656,6 +674,33 @@ namespace Mono.CSharp {
                }
        }
 
+       class PrimaryConstructorAssign : SimpleAssign
+       {
+               readonly Field field;
+               readonly Parameter parameter;
+
+               public PrimaryConstructorAssign (Field field, Parameter parameter)
+                       : base (null, null, parameter.Location)
+               {
+                       this.field = field;
+                       this.parameter = parameter;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       target = new FieldExpr (field, loc);
+                       source = rc.CurrentBlock.ParametersBlock.GetParameterInfo (parameter).CreateReferenceExpression (rc, loc);
+                       return base.DoResolve (rc);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
+                               base.EmitStatement (ec);
+                       }
+               }
+       }
+
        //
        // This class is used for compound assignments.
        //
@@ -672,9 +717,11 @@ namespace Mono.CSharp {
                                this.loc = child.Location;
                        }
 
+                       public bool RequiresEmitWithAwait { get; set; }
+
                        public override bool ContainsEmitWithAwait ()
                        {
-                               return child.ContainsEmitWithAwait ();
+                               return RequiresEmitWithAwait || child.ContainsEmitWithAwait ();
                        }
 
                        public override Expression CreateExpressionTree (ResolveContext ec)