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
                                                 ));
                }
            }
Beispiel #2
0
        public void DoEmitBlock()
        {
            if (this.BlockStatement.Parent is MethodDeclaration)
            {
                this.IsMethodBlock = true;
                var methodDeclaration = (MethodDeclaration)this.BlockStatement.Parent;
                if (!methodDeclaration.ReturnType.IsNull)
                {
                    var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter);
                    this.ReturnType = rr.Type;
                }
                this.ConvertParamsToReferences(methodDeclaration.Parameters);
            }
            else if (this.BlockStatement.Parent is AnonymousMethodExpression)
            {
                this.IsMethodBlock = true;
                var methodDeclaration = (AnonymousMethodExpression)this.BlockStatement.Parent;
                var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter);
                this.ReturnType = rr.Type;
                this.ConvertParamsToReferences(methodDeclaration.Parameters);
            }
            else if (this.BlockStatement.Parent is LambdaExpression)
            {
                this.IsMethodBlock = true;
                var methodDeclaration = (LambdaExpression)this.BlockStatement.Parent;
                var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter);
                this.ReturnType = rr.Type;
                this.ConvertParamsToReferences(methodDeclaration.Parameters);
            }
            else if (this.BlockStatement.Parent is ConstructorDeclaration)
            {
                this.IsMethodBlock = true;
                this.ConvertParamsToReferences(((ConstructorDeclaration)this.BlockStatement.Parent).Parameters);
            }
            else if (this.BlockStatement.Parent is OperatorDeclaration)
            {
                this.IsMethodBlock = true;
                this.ConvertParamsToReferences(((OperatorDeclaration)this.BlockStatement.Parent).Parameters);
            }
            else if (this.BlockStatement.Parent is Accessor)
            {
                this.IsMethodBlock = true;
                var role = this.BlockStatement.Parent.Role.ToString();

                if (role == "Setter")
                {
                    this.ConvertParamsToReferences(new ParameterDeclaration[] { new ParameterDeclaration {
                                                                                    Name = "value"
                                                                                } });
                }
                else if (role == "Getter")
                {
                    var methodDeclaration = (Accessor)this.BlockStatement.Parent;
                    if (!methodDeclaration.ReturnType.IsNull)
                    {
                        var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter);
                        this.ReturnType = rr.Type;
                    }
                }
            }

            if (this.IsMethodBlock && YieldBlock.HasYield(this.BlockStatement))
            {
                this.IsYield = true;
            }

            if (this.IsMethodBlock)
            {
                this.OldReturnType      = this.Emitter.ReturnType;
                this.Emitter.ReturnType = this.ReturnType;
            }

            if (this.Emitter.BeforeBlock != null)
            {
                this.Emitter.BeforeBlock();
                this.Emitter.BeforeBlock = null;
            }

            var ra = ReachabilityAnalysis.Create(this.BlockStatement, this.Emitter.Resolver.Resolver);

            this.BlockStatement.Children.ToList().ForEach(child =>
            {
                var statement = child as Statement;
                if (statement != null && !ra.IsReachable(statement))
                {
                    return;
                }

                child.AcceptVisitor(this.Emitter);
            });
        }
 /// <summary>
 /// Creates a new reachability analysis object with a given statement.
 /// </summary>
 /// <param name="statement">
 /// The statement to start the analysis.
 /// </param>
 /// <param name="recursiveDetectorVisitor">
 /// TODO.
 /// </param>
 /// <returns>
 /// The reachability analysis object.
 /// </returns>
 public ReachabilityAnalysis CreateReachabilityAnalysis(Statement statement, ReachabilityAnalysis.RecursiveDetectorVisitor recursiveDetectorVisitor = null)
 {
     return(ReachabilityAnalysis.Create(statement, resolver, recursiveDetectorVisitor, CancellationToken));
 }
Beispiel #4
0
 /// <summary>
 /// Creates a new reachability analysis object with a given statement.
 /// </summary>
 /// <param name="statement">
 /// The statement to start the analysis.
 /// </param>
 /// <returns>
 /// The reachability analysis object.
 /// </returns>
 public ReachabilityAnalysis CreateReachabilityAnalysis(Statement statement)
 {
     return(ReachabilityAnalysis.Create(statement, resolver, CancellationToken));
 }