void VisitBody(string entityType, SyntaxToken markerToken, StatementSyntax body, ISymbol symbol, SyntaxKind accessorKind = SyntaxKind.UnknownAccessorDeclaration)
            {
                if (body == null)
                {
                    return;
                }
                var  recursiveDetector  = new RecursiveDetector(semanticModel, symbol, accessorKind);
                var  reachability       = ReachabilityAnalysis.Create((StatementSyntax)body, this.semanticModel, recursiveDetector, context.CancellationToken);
                bool hasReachableReturn = false;

                foreach (var statement in reachability.ReachableStatements)
                {
                    if (statement.IsKind(SyntaxKind.ReturnStatement) || statement.IsKind(SyntaxKind.ThrowStatement) || statement.IsKind(SyntaxKind.YieldBreakStatement))
                    {
                        if (!recursiveDetector.Visit(statement))
                        {
                            hasReachableReturn = true;
                            break;
                        }
                    }
                }
                if (!hasReachableReturn && !reachability.IsEndpointReachable(body))
                {
                    context.ReportDiagnostic(Diagnostic.Create(
                                                 descriptor,
                                                 markerToken.GetLocation(),
                                                 entityType
                                                 ));
                }
            }
            void VisitBody(string entityType, AstNode node, BlockStatement body, IMember member, Role accessorRole)
            {
                var  recursiveDetector  = new RecursiveDetector(ctx, member, accessorRole);
                var  reachability       = ctx.CreateReachabilityAnalysis(body, recursiveDetector);
                bool hasReachableReturn = false;

                foreach (var statement in reachability.ReachableStatements)
                {
                    if (statement is ReturnStatement || statement is ThrowStatement || statement is YieldBreakStatement)
                    {
                        if (!statement.AcceptVisitor(recursiveDetector))
                        {
                            hasReachableReturn = true;
                            break;
                        }
                    }
                }
                if (!hasReachableReturn && !reachability.IsEndpointReachable(body))
                {
                    AddIssue(new CodeIssue(node, ctx.TranslateString(string.Format("{0} never reaches its end or a 'return' statement.", entityType))));
                }
            }
 void VisitBody(string entityType, SyntaxToken markerToken, StatementSyntax body, ISymbol symbol, SyntaxKind accessorKind = SyntaxKind.UnknownAccessorDeclaration)
 {
     if (body == null)
         return;
     var recursiveDetector = new RecursiveDetector(semanticModel, symbol, accessorKind);
     var reachability = ReachabilityAnalysis.Create((StatementSyntax)body, this.semanticModel, recursiveDetector, context.CancellationToken);
     bool hasReachableReturn = false;
     foreach (var statement in reachability.ReachableStatements)
     {
         if (statement.IsKind(SyntaxKind.ReturnStatement) || statement.IsKind(SyntaxKind.ThrowStatement) || statement.IsKind(SyntaxKind.YieldBreakStatement))
         {
             if (!recursiveDetector.Visit(statement))
             {
                 hasReachableReturn = true;
                 break;
             }
         }
     }
     if (!hasReachableReturn && !reachability.IsEndpointReachable(body))
     {
         context.ReportDiagnostic(Diagnostic.Create(
             descriptor,
             markerToken.GetLocation(),
             entityType
         ));
     }
 }