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 )); } }
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)); }
private StatementIssueCollector(GatherVisitor visitor, ReachabilityAnalysis reachability) { collectedStatements = new HashSet <Statement> (); this.visitor = visitor; this.reachability = reachability; }
/// <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)); }
private StatementIssueCollector(GatherVisitor visitor, ReachabilityAnalysis reachability) { collectedStatements = new List <AstNode>(); this.visitor = visitor; this.reachability = reachability; }