[mcs] C#7 out variable declaration
[mono.git] / mcs / mcs / expression.cs
index 9042dcdabad8e5405cbbbc086953ade32d7dfc81..bb6255ce48740f0641084d38c0b30a7c82497e7f 100644 (file)
@@ -2562,12 +2562,18 @@ namespace Mono.CSharp
 
                public override Expression CreateExpressionTree (ResolveContext rc)
                {
-                       rc.Report.Error (8046, loc, "An expression tree cannot contain a declaration expression");
+                       rc.Report.Error (8198, loc, "An expression tree cannot contain out variable declaration");
                        return null;
                }
 
                bool DoResolveCommon (ResolveContext rc)
                {
+                       if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope)) {
+                               rc.Report.Error (8200, loc, "Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers");
+                       } else if (rc.HasSet (ResolveContext.Options.QueryClauseScope)) {
+                               rc.Report.Error (8201, loc, "Out variable and pattern variable declarations are not allowed within a query clause");
+                       }
+
                        var var_expr = VariableType as VarExpr;
                        if (var_expr != null) {
                                type = InternalType.VarOutType;
@@ -12735,4 +12741,68 @@ namespace Mono.CSharp
                        return value;
                }
        }
+
+       class ThrowExpression : ExpressionStatement
+       {
+               Expression expr;
+
+               public ThrowExpression (Expression expr, Location loc)
+               {
+                       this.expr = expr;
+                       this.loc = loc;
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       var target = (ThrowExpression)t;
+                       target.expr = expr.Clone (clonectx);
+               }
+
+               public override bool ContainsEmitWithAwait ()
+               {
+                       return expr.ContainsEmitWithAwait ();
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext rc)
+               {
+                       rc.Report.Error (8188, loc, "An expression tree cannot not contain a throw expression");
+                       return expr;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       expr = expr.Resolve (rc, ResolveFlags.Type | ResolveFlags.VariableOrValue);
+
+                       if (expr == null)
+                               return null;
+
+                       expr = Throw.ConvertType (rc, expr);
+
+                       eclass = ExprClass.Value;
+                       type = InternalType.ThrowExpr;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       EmitStatement (ec);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       expr.Emit (ec);
+
+                       ec.Emit (OpCodes.Throw);
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       return Reachability.CreateUnreachable ();
+               }
+       }
 }