From 24687926eb5d40e03095b9919043aba701e3f0e0 Mon Sep 17 00:00:00 2001 From: Georgii Borovinskikh <117642191+georgii-borovinskikh-sonarsource@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:14:39 +0100 Subject: [PATCH] SLVS-1557 Fix analyzers being replaced rather than added (#5779) --- .../Roslyn/RoslynSolutionWrapperTests.cs | 33 ++++++++++++++----- .../SolutionRoslynAnalyzerManagerTests.cs | 16 ++++----- .../Roslyn/IRoslynSolutionWrapper.cs | 6 ++-- .../Roslyn/SolutionRoslynAnalyzerManager.cs | 2 +- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/Infrastructure.VS.UnitTests/Roslyn/RoslynSolutionWrapperTests.cs b/src/Infrastructure.VS.UnitTests/Roslyn/RoslynSolutionWrapperTests.cs index 44291f8730..3c4532b871 100644 --- a/src/Infrastructure.VS.UnitTests/Roslyn/RoslynSolutionWrapperTests.cs +++ b/src/Infrastructure.VS.UnitTests/Roslyn/RoslynSolutionWrapperTests.cs @@ -41,10 +41,27 @@ public void AddAnalyzer_CurrentSolutionContainsAnalyzer() var roslynWorkspaceWrapper = CreateWorkspaceWrapper(); var analyzers = ImmutableArray.Create(analyzerFileReference); - var solutionAfterAddition = roslynWorkspaceWrapper.CurrentSolution.WithAnalyzerReferences(analyzers); + var solutionAfterAddition = roslynWorkspaceWrapper.CurrentSolution.AddAnalyzerReferences(analyzers); roslynWorkspaceWrapper.TryApplyChanges(solutionAfterAddition).Should().BeTrue(); - roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Contains(analyzerFileReference).Should().BeTrue(); + roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Should().Contain(analyzerFileReference); + } + + [TestMethod] + public void AddExtraAnalyzer_CurrentSolutionContainsBothAnalyzers() + { + var analyzerFileReference = new AnalyzerFileReference(@"C:\abc", Substitute.For()); + var extraAnalyzerFileReference = new AnalyzerFileReference(@"C:\abc", Substitute.For()); + var roslynWorkspaceWrapper = CreateWorkspaceWrapper(); + var extraAnalyzers = ImmutableArray.Create(extraAnalyzerFileReference); + roslynWorkspaceWrapper.TryApplyChanges(roslynWorkspaceWrapper.CurrentSolution.AddAnalyzerReferences(ImmutableArray.Create(analyzerFileReference))).Should().BeTrue(); + + var solutionAfterAddition = roslynWorkspaceWrapper.CurrentSolution.AddAnalyzerReferences(extraAnalyzers); + roslynWorkspaceWrapper.TryApplyChanges(solutionAfterAddition).Should().BeTrue(); + + var solutionAnalyzers = roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences; + solutionAnalyzers.Should().Contain(analyzerFileReference); + solutionAnalyzers.Should().Contain(extraAnalyzerFileReference); } [TestMethod] @@ -54,13 +71,13 @@ public void AddAndRemoveAnalyzer_CurrentSolutionNoLongerContainsAnalyzer() var roslynWorkspaceWrapper = CreateWorkspaceWrapper(); var analyzers = ImmutableArray.Create(analyzerFileReference); - var solutionAfterAddition = roslynWorkspaceWrapper.CurrentSolution.WithAnalyzerReferences(analyzers); + var solutionAfterAddition = roslynWorkspaceWrapper.CurrentSolution.AddAnalyzerReferences(analyzers); roslynWorkspaceWrapper.TryApplyChanges(solutionAfterAddition).Should().BeTrue(); var solutionAfterRemoval = roslynWorkspaceWrapper.CurrentSolution.RemoveAnalyzerReferences(analyzers); roslynWorkspaceWrapper.TryApplyChanges(solutionAfterRemoval).Should().BeTrue(); - roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Contains(analyzerFileReference).Should().BeFalse(); + roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Should().NotContain(analyzerFileReference); } [TestMethod] @@ -73,7 +90,7 @@ public void RemoveAnalyzer_IsNotPresentInTheCurrentSolution_AppliesNoChange() var solutionAfterRemoval = roslynWorkspaceWrapper.CurrentSolution.RemoveAnalyzerReferences(analyzers); roslynWorkspaceWrapper.TryApplyChanges(solutionAfterRemoval).Should().BeTrue(); - roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Contains(analyzerFileReference).Should().BeFalse(); + roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Should().NotContain(analyzerFileReference); } [TestMethod] @@ -85,10 +102,10 @@ public void AddMultipleAndRemoveOneAnalyzer_CurrentSolutionContainsOneAnalyzer() var analyzersToRemove = ImmutableArray.Create(analyzerFileReference1); var roslynWorkspaceWrapper = CreateWorkspaceWrapper(); - roslynWorkspaceWrapper.TryApplyChanges(roslynWorkspaceWrapper.CurrentSolution.WithAnalyzerReferences(analyzersToAdd)).Should().BeTrue(); + roslynWorkspaceWrapper.TryApplyChanges(roslynWorkspaceWrapper.CurrentSolution.AddAnalyzerReferences(analyzersToAdd)).Should().BeTrue(); roslynWorkspaceWrapper.TryApplyChanges(roslynWorkspaceWrapper.CurrentSolution.RemoveAnalyzerReferences(analyzersToRemove)).Should().BeTrue(); - roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Contains(analyzerFileReference1).Should().BeFalse(); - roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Contains(analyzerFileReference2).Should().BeTrue(); + roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Should().NotContain(analyzerFileReference1); + roslynWorkspaceWrapper.CurrentSolution.GetRoslynSolution().AnalyzerReferences.Should().Contain(analyzerFileReference2); } private static IRoslynWorkspaceWrapper CreateWorkspaceWrapper() diff --git a/src/Infrastructure.VS.UnitTests/Roslyn/SolutionRoslynAnalyzerManagerTests.cs b/src/Infrastructure.VS.UnitTests/Roslyn/SolutionRoslynAnalyzerManagerTests.cs index 745be5078e..b7d5089e58 100644 --- a/src/Infrastructure.VS.UnitTests/Roslyn/SolutionRoslynAnalyzerManagerTests.cs +++ b/src/Infrastructure.VS.UnitTests/Roslyn/SolutionRoslynAnalyzerManagerTests.cs @@ -138,7 +138,7 @@ public void OnSolutionChanged_StandaloneSolution_BindingSet_RemovesStandaloneAnd analyzerComparer.Equals(embeddedAnalyzers, connectedAnalyzers); v1Solution.RemoveAnalyzerReferences(embeddedAnalyzers); roslynWorkspaceWrapper.TryApplyChanges(v2Solution); - v2Solution.WithAnalyzerReferences(connectedAnalyzers); + v2Solution.AddAnalyzerReferences(connectedAnalyzers); roslynWorkspaceWrapper.TryApplyChanges(v3Solution); }); embeddedRoslynAnalyzerProvider.DidNotReceiveWithAnyArgs().Get(); @@ -180,7 +180,7 @@ public void OnSolutionChanged_SolutionClosedAndReopened_RegistersAnalyzersAgain( testSubject.OnSolutionChanged(null, BindingConfiguration.Standalone); testSubject.OnSolutionChanged(solutionName, BindingConfiguration.Standalone); - v2Solution.Received().WithAnalyzerReferences(embeddedAnalyzers); + v2Solution.Received().AddAnalyzerReferences(embeddedAnalyzers); roslynWorkspaceWrapper.Received().TryApplyChanges(v3Solution); } @@ -200,7 +200,7 @@ public void OnSolutionChanged_SolutionClosedAndReopenedAsBound_RegistersConnecte roslynWorkspaceWrapper.CurrentSolution.Returns(v2Solution); // simulate solution closed and opened, so this is a different version now testSubject.OnSolutionChanged(solutionName, connectedModeConfiguration); - v2Solution.Received().WithAnalyzerReferences(connectedAnalyzers); + v2Solution.Received().AddAnalyzerReferences(connectedAnalyzers); roslynWorkspaceWrapper.Received().TryApplyChanges(v3Solution); } @@ -221,7 +221,7 @@ public void OnSolutionChanged_DifferentSolutionOpened_RegistersAnalyzers() Received.InOrder(() => { - v1Solution.WithAnalyzerReferences(connectedAnalyzers); + v1Solution.AddAnalyzerReferences(connectedAnalyzers); roslynWorkspaceWrapper.TryApplyChanges(v2Solution); }); } @@ -235,7 +235,7 @@ public void HandleConnectedModeAnalyzerUpdate_Standalone_Ignored() testSubject.HandleConnectedModeAnalyzerUpdate(null, new AnalyzerUpdatedForConnectionEventArgs(new ServerConnection.SonarCloud("someorg"), connectedAnalyzers)); - v1Solution.DidNotReceiveWithAnyArgs().WithAnalyzerReferences(default); + v1Solution.DidNotReceiveWithAnyArgs().AddAnalyzerReferences(default); v1Solution.DidNotReceiveWithAnyArgs().RemoveAnalyzerReferences(default); } @@ -248,7 +248,7 @@ public void HandleConnectedModeAnalyzerUpdate_Connected_DifferentConnection_Igno testSubject.HandleConnectedModeAnalyzerUpdate(null, new AnalyzerUpdatedForConnectionEventArgs(new ServerConnection.SonarCloud("some other org"), connectedAnalyzers)); - v1Solution.DidNotReceiveWithAnyArgs().WithAnalyzerReferences(default); + v1Solution.DidNotReceiveWithAnyArgs().AddAnalyzerReferences(default); v1Solution.DidNotReceiveWithAnyArgs().RemoveAnalyzerReferences(default); } @@ -274,7 +274,7 @@ public void HandleConnectedModeAnalyzerUpdate_Connected_NewAnalyzerSet() analyzerComparer.Equals(connectedAnalyzers, differentConnectedAnalyzers); v1Solution.RemoveAnalyzerReferences(connectedAnalyzers); roslynWorkspaceWrapper.TryApplyChanges(v2Solution); - v2Solution.WithAnalyzerReferences(differentConnectedAnalyzers); + v2Solution.AddAnalyzerReferences(differentConnectedAnalyzers); roslynWorkspaceWrapper.TryApplyChanges(v3Solution); }); } @@ -337,7 +337,7 @@ private void SetUpAnalyzerAddition(IRoslynSolutionWrapper originalSolution, IRoslynSolutionWrapper resultingSolution, ImmutableArray analyzers) { - originalSolution.WithAnalyzerReferences(analyzers).Returns(resultingSolution); + originalSolution.AddAnalyzerReferences(analyzers).Returns(resultingSolution); roslynWorkspaceWrapper.TryApplyChanges(resultingSolution).Returns(true); } diff --git a/src/Infrastructure.VS/Roslyn/IRoslynSolutionWrapper.cs b/src/Infrastructure.VS/Roslyn/IRoslynSolutionWrapper.cs index 228629037d..b492387386 100644 --- a/src/Infrastructure.VS/Roslyn/IRoslynSolutionWrapper.cs +++ b/src/Infrastructure.VS/Roslyn/IRoslynSolutionWrapper.cs @@ -27,7 +27,7 @@ namespace SonarLint.VisualStudio.Infrastructure.VS.Roslyn; internal interface IRoslynSolutionWrapper { IRoslynSolutionWrapper RemoveAnalyzerReferences(ImmutableArray analyzers); - IRoslynSolutionWrapper WithAnalyzerReferences(ImmutableArray analyzers); + IRoslynSolutionWrapper AddAnalyzerReferences(ImmutableArray analyzers); Solution GetRoslynSolution(); } @@ -43,8 +43,8 @@ public IRoslynSolutionWrapper RemoveAnalyzerReferences(ImmutableArray analyzers) => - new RoslynSolutionWrapper(solution.WithAnalyzerReferences(analyzers)); + public IRoslynSolutionWrapper AddAnalyzerReferences(ImmutableArray analyzers) => + new RoslynSolutionWrapper(solution.AddAnalyzerReferences(analyzers)); public Solution GetRoslynSolution() => solution; } diff --git a/src/Infrastructure.VS/Roslyn/SolutionRoslynAnalyzerManager.cs b/src/Infrastructure.VS/Roslyn/SolutionRoslynAnalyzerManager.cs index ab098984b3..aa58c1d1e1 100644 --- a/src/Infrastructure.VS/Roslyn/SolutionRoslynAnalyzerManager.cs +++ b/src/Infrastructure.VS/Roslyn/SolutionRoslynAnalyzerManager.cs @@ -184,7 +184,7 @@ private void UpdateAnalyzers(ImmutableArray analyzersToUs private void AddAnalyzer(ImmutableArray analyzerToUse) { - if (!roslynWorkspace.TryApplyChanges(roslynWorkspace.CurrentSolution.WithAnalyzerReferences(analyzerToUse))) + if (!roslynWorkspace.TryApplyChanges(roslynWorkspace.CurrentSolution.AddAnalyzerReferences(analyzerToUse))) { const string message = "Failed to add analyzer references while adding analyzers"; Debug.Assert(true, message);