public bool ShouldIssueBeReported(SyntaxTree syntaxTree, Diagnostic diagnostic) { // This method is called for every analyzer issue that is raised so it should be fast. if (!diagnostic.Location.IsInSource && diagnostic.Location != Location.None) { return(true); } LiveIssue liveIssue = liveIssueFactory.Create(syntaxTree, diagnostic); if (liveIssue == null) { return(true); // Unable to get the data required to map a Roslyn issue to a SonarQube issue } // Issues match if: // 1. Same component, same file, same error code, same line hash // tolerant to line number changing // 2. Same component, same file, same error code, same line // tolerant to code on the line changing e.g. var rename // Retrieve all issues relating to this file (file level or precise location) or project (for module level issues) var potentialMatchingIssues = serverIssuesProvider.GetSuppressedIssues(liveIssue.ProjectGuid, liveIssue.FilePath); // Try to find an issue with the same ID and either the same line number or some line hash bool matchFound = potentialMatchingIssues .Where(i => StringComparer.OrdinalIgnoreCase.Equals(liveIssue.Diagnostic.Id, i.RuleId)) .Any(i => liveIssue.StartLine == i.Line || StringComparer.Ordinal.Equals(liveIssue.LineHash, i.Hash)); return(!matchFound); }
public bool SuppressionExists(IFilterableIssue issue) { if (issue == null) { throw new ArgumentNullException(nameof(issue)); } // File-level issues (i.e. line = null) match if: // 1. Same component, same file, same error code. // Non-file-level issues match if: // 1. Same component, same file, same error code, same line hash // tolerant to line number changing // 2. Same component, same file, same error code, same line // tolerant to code on the line changing e.g. var rename // File-level issues never match non-file-level issues. // Retrieve all issues relating to this file (file level or precise location) or project (for module level issues) var serverIssues = issuesProvider.GetSuppressedIssues(issue.ProjectGuid, issue.FilePath); // Try to find an issue with the same ID and either the same line number or some line hash bool matchFound = serverIssues.Any(s => IsMatch(issue, s)); return(matchFound); }
private bool ShouldIssueBeReported(SyntaxTree syntaxTree, Diagnostic diagnostic) { // This method is called for every analyzer issue that is raised so it should be fast. if (!diagnostic.Location.IsInSource && diagnostic.Location != Location.None) { return(true); } if (activeSolutionBoundTracker == null || !activeSolutionBoundTracker.IsActiveSolutionBound) { return(true); } LiveIssue liveIssue = liveIssueFactory.Create(syntaxTree, diagnostic); if (liveIssue == null) { return(true); // Unable to get the data required to map a Roslyn issue to a SonarQube issue } // Issues match if: // 1. Same component, same file, same error code, same line hash // tolerant to line number changing // 2. Same component, same file, same error code, same line // tolerant to code on the line changing e.g. var rename // TODO: ?need to make file path relative to the project file path // As a minimum, the project, file and rule id must match var issuesInFile = sonarqubeIssueProvider.GetSuppressedIssues(liveIssue.ProjectGuid, liveIssue.IssueFilePath); if (issuesInFile == null) { return(true); } // TODO: rule repository? issuesInFile = issuesInFile.Where(i => StringComparer.OrdinalIgnoreCase.Equals(liveIssue.Diagnostic.Id, i.RuleId)); bool matchFound = issuesInFile.Any(i => liveIssue.StartLine == i.Line || StringComparer.Ordinal.Equals(liveIssue.LineHash, i.Hash)); return(!matchFound); }
public IEnumerable <SonarQubeIssue> GetSuppressedIssues(string projectGuid, string filePath) { return(instance?.GetSuppressedIssues(projectGuid, filePath) ?? new List <SonarQubeIssue>()); }