public override bool Resolve(BlockContext bc) { if (!CheckContext(bc, loc)) { return(false); } if (bc.HasAny(ResolveContext.Options.TryWithCatchScope)) { bc.Report.Error(1626, loc, "Cannot yield a value in the body of a try block with a catch clause"); } if (bc.HasSet(ResolveContext.Options.CatchScope)) { bc.Report.Error(1631, loc, "Cannot yield a value in the body of a catch clause"); } if (!base.Resolve(bc)) { return(false); } var otype = bc.CurrentIterator.OriginalIteratorType; if (expr.Type != otype) { expr = Convert.ImplicitConversionRequired(bc, expr, otype, loc); if (expr == null) { return(false); } } return(true); }
public static bool CheckContext(BlockContext bc, Location loc) { if (!bc.CurrentAnonymousMethod.IsIterator) { bc.Report.Error(1621, loc, "The yield statement cannot be used inside anonymous method blocks"); return(false); } if (bc.HasSet(ResolveContext.Options.FinallyScope)) { bc.Report.Error(1625, loc, "Cannot yield in the body of a finally clause"); return(false); } return(true); }
public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md) { if (resolved) return true; resolved = true; if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= Flags.IsExpressionTree; try { ResolveMeta (rc); using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) { FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent); if (!Resolve (rc)) return false; unreachable = top_level.End (); } } catch (Exception e) { if (e is CompletionResult || rc.Report.IsDisabled) throw; if (rc.CurrentBlock != null) { rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message); } else { rc.Report.Error (587, "Internal compiler error: {0}", e.Message); } if (Report.DebugFlags > 0) throw; } if (rc.ReturnType != TypeManager.void_type && !unreachable) { if (rc.CurrentAnonymousMethod == null) { // FIXME: Missing FlowAnalysis for generated iterator MoveNext method if (md is IteratorMethod) { unreachable = true; } else { rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); return false; } } else { rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'", rc.CurrentAnonymousMethod.GetSignatureForError ()); return false; } } return true; }
public override bool Resolve(BlockContext bc) { if (bc.CurrentBlock is Linq.QueryBlock) { bc.Report.Error(1995, loc, "The `await' operator may only be used in a query expression within the first collection expression of the initial `from' clause or within the collection expression of a `join' clause"); return(false); } if (bc.HasSet(ResolveContext.Options.CatchScope)) { bc.Report.Error(1985, loc, "The `await' operator cannot be used in the body of a catch clause"); } if (!base.Resolve(bc)) { return(false); } type = expr.Type; Arguments args = new Arguments(0); // // The await expression is of dynamic type // if (type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { result_type = type; expr = new Invocation(new MemberAccess(expr, "GetAwaiter"), args).Resolve(bc); return(true); } // // Check whether the expression is awaitable // Expression ama = new AwaitableMemberAccess(expr).Resolve(bc); if (ama == null) { return(false); } var errors_printer = new SessionReportPrinter(); var old = bc.Report.SetPrinter(errors_printer); ama = new Invocation(ama, args).Resolve(bc); bc.Report.SetPrinter(old); if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression(ama.Type)) { bc.Report.Error(1986, expr.Location, "The `await' operand type `{0}' must have suitable GetAwaiter method", expr.Type.GetSignatureForError()); return(false); } var awaiter_type = ama.Type; awaiter_definition = bc.Module.GetAwaiter(awaiter_type); if (!awaiter_definition.IsValidPattern) { Error_WrongAwaiterPattern(bc, awaiter_type); return(false); } if (!awaiter_definition.INotifyCompletion) { bc.Report.Error(4027, loc, "The awaiter type `{0}' must implement interface `{1}'", awaiter_type.GetSignatureForError(), bc.Module.PredefinedTypes.INotifyCompletion.GetSignatureForError()); return(false); } expr = ama; result_type = awaiter_definition.GetResult.ReturnType; return(true); }
protected override bool DoResolve (BlockContext ec) { if (Expr == null) { if (ec.ReturnType == TypeManager.void_type) return true; ec.Report.Error (126, loc, "An object of a type convertible to `{0}' is required for the return statement", TypeManager.CSharpName (ec.ReturnType)); return false; } if (ec.CurrentBlock.Toplevel.IsIterator) { ec.Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " + "statement to return a value, or yield break to end the iteration"); } AnonymousExpression am = ec.CurrentAnonymousMethod; if (am == null && ec.ReturnType == TypeManager.void_type) { ec.Report.Error (127, loc, "`{0}': A return keyword must not be followed by any expression when method returns void", ec.GetSignatureForError ()); } Expr = Expr.Resolve (ec); if (Expr == null) return false; if (ec.HasSet (ResolveContext.Options.InferReturnType)) { ec.ReturnTypeInference.AddCommonTypeBound (Expr.Type); return true; } if (Expr.Type != ec.ReturnType) { Expr = Convert.ImplicitConversionRequired (ec, Expr, ec.ReturnType, loc); if (Expr == null) { if (am != null) { ec.Report.Error (1662, loc, "Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type", am.ContainerType, am.GetSignatureForError ()); } return false; } } return true; }