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>());
 }