private void RefreshWorkflow(BindingConfiguration configuration) { // There might be some race condition here if an analysis is triggered while the delegates are reset and set back // to the new workflow behavior. This race condition would lead to some issues being reported using the old mode // instead of the new one but everything will be fixed on the next analysis. ResetState(); switch (configuration?.Mode) { case SonarLintMode.Standalone: this.logger.WriteLine(Resources.Strings.AnalyzerManager_InStandaloneMode); this.currentWorklow = new SonarAnalyzerStandaloneWorkflow(this.workspace); break; case SonarLintMode.LegacyConnected: case SonarLintMode.Connected: this.logger.WriteLine(Resources.Strings.AnalyzerManager_InConnectedMode); var sonarQubeIssueProvider = new SonarQubeIssuesProvider(sonarQubeService, configuration.Project.ProjectKey, new TimerFactory(), this.logger); this.disposableObjects.Add(sonarQubeIssueProvider); var liveIssueFactory = new LiveIssueFactory(workspace, vsSolution); var suppressionHandler = new SuppressionHandler(liveIssueFactory, sonarQubeIssueProvider); if (configuration.Mode == SonarLintMode.Connected) { this.currentWorklow = new SonarAnalyzerConnectedWorkflow(this.workspace, suppressionHandler); } else // Legacy { this.currentWorklow = new SonarAnalyzerLegacyConnectedWorkflow(this.workspace, suppressionHandler, this.logger); } break; } }
public static void Verify(Compilation compilation, DiagnosticAnalyzer[] diagnosticAnalyzers, CompilationErrorBehavior checkMode) { try { SuppressionHandler.HookSuppression(); var diagnostics = GetDiagnostics(compilation, diagnosticAnalyzers, checkMode); var expectedIssues = new IssueLocationCollector() .GetExpectedIssueLocations(compilation.SyntaxTrees.Skip(1).First().GetText().Lines) .ToList(); CompareActualToExpected(diagnostics, expectedIssues, false); // When there are no diagnostics reported from the test (for example the FileLines analyzer // does not report in each call to Verifier.VerifyAnalyzer) we skip the check for the extension // method. if (diagnostics.Any()) { SuppressionHandler.ExtensionMethodsCalledForAllDiagnostics(diagnosticAnalyzers).Should() .BeTrue("The ReportDiagnosticWhenActive should be used instead of ReportDiagnostic"); } } finally { SuppressionHandler.UnHookSuppression(); } }
public static void Verify(Compilation compilation, DiagnosticAnalyzer diagnosticAnalyzer) { try { SuppressionHandler.HookSuppression(); var diagnostics = GetDiagnostics(compilation, diagnosticAnalyzer); var expectedIssues = new IssueLocationCollector() .GetExpectedIssueLocations(compilation.SyntaxTrees.Skip(1).First().GetText().Lines) .ToList(); foreach (var diagnostic in diagnostics) { VerifyIssue(expectedIssues, issue => issue.IsPrimary, diagnostic.Location, diagnostic.GetMessage(), out var issueId); var secondaryLocations = diagnostic.AdditionalLocations .Select((location, i) => diagnostic.GetSecondaryLocation(i)) .OrderBy(x => x.Location.GetLineNumberToReport()) .ThenBy(x => x.Location.GetLineSpan().StartLinePosition.Character); foreach (var secondaryLocation in secondaryLocations) { VerifyIssue(expectedIssues, issue => issue.IssueId == issueId && !issue.IsPrimary, secondaryLocation.Location, secondaryLocation.Message, out issueId); } } if (expectedIssues.Count != 0) { Execute.Assertion.FailWith($"Issue expected but not raised on line(s) " + $"{string.Join(",", expectedIssues.Select(i => i.LineNumber))}."); } // When there are no diagnostics reported from the test (for example the FileLines analyzer // does not report in each call to Verifier.VerifyAnalyzer) we skip the check for the extension // method. if (diagnostics.Any()) { SuppressionHandler.ExtensionMethodsCalledForAllDiagnostics(diagnosticAnalyzer).Should() .BeTrue("The ReportDiagnosticWhenActive should be used instead of ReportDiagnostic"); } } finally { SuppressionHandler.UnHookSuppression(); } }
public void ShouldReport_CannotCreateLiveIssue_ReturnsTrue() { // Arrange Diagnostic diag = CreateDiagnostic("dummy rule id", CreateSourceLocation()); SetLiveIssue(null); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(syntaxTreeMock.Object, diag); // Assert VerifyLiveIssueCreated(Times.Once()); VerifyServerIssuesRequested(Times.Never()); result.Should().BeTrue(); }
public void ShouldReport_LocationNotInSource_ReturnsTrue() { // Arrange Diagnostic diag = CreateDiagnostic("dummy rule ID", CreateNonSourceLocation()); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(new Mock <SyntaxTree>().Object, diag); // Assert result.Should().BeTrue(); // Should early-out VerifyLiveIssueCreated(Times.Never()); VerifyServerIssuesRequested(Times.Never()); }
public void ShouldReport_NoServerIssues_ReturnsTrue() { // Arrange Diagnostic diag = CreateDiagnostic("dummy rule id", CreateSourceLocation()); SetLiveIssue(diag, startLine: 1, wholeLineText: "text"); SetServerIssues(Array.Empty <SonarQubeIssue>()); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(syntaxTreeMock.Object, diag); // Assert VerifyLiveIssueCreated(Times.Once()); VerifyServerIssuesRequested(Times.Once()); result.Should().BeTrue(); }
public void ShouldReport_FileOrProjectIssue_MatchExists_ReturnsFalse() { // Arrange Diagnostic diag = CreateDiagnostic("RightRuleId", CreateSourceLocation()); SetLiveIssue(diag, startLine: 0, wholeLineText: ""); var serverIssue1 = CreateServerIssue("WrongRuleId", 0, ""); var serverIssue2 = CreateServerIssue("RightRuleId", 0, "wrong hash"); // wrong hash var serverIssue3 = CreateServerIssue("RightRuleId", 0, ""); SetServerIssues(serverIssue1, serverIssue2, serverIssue3); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(new Mock <SyntaxTree>().Object, diag); // Assert result.Should().BeFalse(); }
public void ShouldReport_ServerIssueMatchesOnLine_ReturnsFalse() { // Arrange string wholeLineText = "whole line text"; Diagnostic diag = CreateDiagnostic("RightRuleId", CreateSourceLocation()); SetLiveIssue(diag, startLine: 101, wholeLineText: wholeLineText); var serverIssue = CreateServerIssue("RightRuleId", 101, "wrong hash"); SetServerIssues(serverIssue); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(syntaxTreeMock.Object, diag); // Assert result.Should().BeFalse(); }
public void ShouldReport_ServerIssueMatchesOnLineHash_ReturnsFalse() { // Arrange string wholeLineText = "whole line text"; string lineHash = ChecksumCalculator.Calculate(wholeLineText); Diagnostic diag = CreateDiagnostic("RightRuleId", CreateSourceLocation()); SetLiveIssue(diag, startLine: 101, wholeLineText: wholeLineText); var serverIssue = CreateServerIssue("RIGHTRULEID", 999, lineHash); // rule id comparison is case-insensitive SetServerIssues(serverIssue); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(syntaxTreeMock.Object, diag); // Assert result.Should().BeFalse(); }
public static void Verify(Compilation compilation, DiagnosticAnalyzer[] diagnosticAnalyzers, CompilationErrorBehavior checkMode, SourceText source, string sonarProjectConfigPath = null) { SuppressionHandler.HookSuppression(); try { var diagnostics = GetDiagnostics(compilation, diagnosticAnalyzers, checkMode, sonarProjectConfigPath: sonarProjectConfigPath); var expectedIssues = IssueLocationCollector.GetExpectedIssueLocations(source.Lines).ToList(); CompareActualToExpected(compilation.LanguageVersionString(), diagnostics, expectedIssues, false); // When there are no diagnostics reported from the test (for example the FileLines analyzer // does not report in each call to Verifier.VerifyAnalyzer) we skip the check for the extension // method. if (diagnostics.Any()) { SuppressionHandler.ExtensionMethodsCalledForAllDiagnostics(diagnosticAnalyzers).Should().BeTrue("The ReportDiagnosticWhenActive should be used instead of ReportDiagnostic"); } } finally { SuppressionHandler.UnHookSuppression(); } }
public void ShouldReport_NoMatchingServerIssues_ReturnsTrue() { // Arrange string wholeLineText = "whole line text"; string lineHash = ChecksumCalculator.Calculate(wholeLineText); Diagnostic diag = CreateDiagnostic("RuleId 1", CreateSourceLocation()); SetLiveIssue(diag, startLine: 10, wholeLineText: wholeLineText); var serverIssue1 = CreateServerIssue("Wrong rule id", 10, lineHash); // wrong rule id var serverIssue2 = CreateServerIssue("RuleId 1", 999, "wrong hash"); // wrong line and hash var serverIssue3 = CreateServerIssue("RuleId 1", 999, lineHash.ToUpperInvariant()); // wrong line and wrong-case hash SetServerIssues(serverIssue1, serverIssue2, serverIssue3); SuppressionHandler handler = new SuppressionHandler(issueFactoryMock.Object, issueProviderMock.Object); // Act bool result = handler.ShouldIssueBeReported(syntaxTreeMock.Object, diag); // Assert result.Should().BeTrue(); }