Skip to content

Commit

Permalink
Merge pull request #49574 from jasonmalinowski/fix-broken-analyzer-list
Browse files Browse the repository at this point in the history
Fix the ability to expand the list of analyzers in a reference
  • Loading branch information
msftbot[bot] authored Nov 23, 2020
2 parents 6a62cf5 + 2fffa6d commit 4262935
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
Expand All @@ -14,10 +12,13 @@ internal class TestAnalyzerReferenceByLanguage : AnalyzerReference
{
private readonly IReadOnlyDictionary<string, ImmutableArray<DiagnosticAnalyzer>> _analyzersMap;

public TestAnalyzerReferenceByLanguage(IReadOnlyDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzersMap)
=> _analyzersMap = analyzersMap;
public TestAnalyzerReferenceByLanguage(IReadOnlyDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzersMap, string? fullPath = null)
{
_analyzersMap = analyzersMap;
FullPath = fullPath;
}

public override string FullPath => null;
public override string? FullPath { get; }
public override string Display => nameof(TestAnalyzerReferenceByLanguage);
public override object Id => Display;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ public IEnumerable Items
_specificDiagnosticOptions = project.CompilationOptions!.SpecificDiagnosticOptions;
_analyzerConfigOptions = project.GetAnalyzerConfigOptions();

_diagnosticItems = new BulkObservableCollection<BaseDiagnosticItem>();
_diagnosticItems.AddRange(GetDiagnosticItems(project.Language, project.CompilationOptions, _analyzerConfigOptions));
_diagnosticItems = CreateDiagnosticItems(project.Language, project.CompilationOptions, _analyzerConfigOptions);

Workspace.WorkspaceChanged += OnWorkspaceChangedLookForOptionsChanges;
}
Expand All @@ -97,7 +96,7 @@ public IEnumerable Items
}
}

private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, CompilationOptions options, AnalyzerConfigOptionsResult? analyzerConfigOptions)
private BulkObservableCollection<BaseDiagnosticItem> CreateDiagnosticItems(string language, CompilationOptions options, AnalyzerConfigOptionsResult? analyzerConfigOptions)
{
// Within an analyzer assembly, an individual analyzer may report multiple different diagnostics
// with the same ID. Or, multiple analyzers may report diagnostics with the same ID. Or a
Expand All @@ -110,7 +109,9 @@ private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, Comp

Contract.ThrowIfFalse(HasItems);

return AnalyzerReference.GetAnalyzers(language)
var collection = new BulkObservableCollection<BaseDiagnosticItem>();
collection.AddRange(
AnalyzerReference.GetAnalyzers(language)
.SelectMany(a => _diagnosticAnalyzerService.AnalyzerInfoCache.GetDiagnosticDescriptors(a))
.GroupBy(d => d.Id)
.OrderBy(g => g.Key, StringComparer.CurrentCulture)
Expand All @@ -119,7 +120,9 @@ private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, Comp
var selectedDiagnostic = g.OrderBy(d => d, s_comparer).First();
var effectiveSeverity = selectedDiagnostic.GetEffectiveSeverity(options, analyzerConfigOptions);
return CreateItem(selectedDiagnostic, effectiveSeverity, language);
});
}));

return collection;
}

private void OnWorkspaceChangedLookForOptionsChanges(object sender, WorkspaceChangeEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.Internal.VisualStudio.PlatformUI
Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework
Imports Microsoft.VisualStudio.Shell

Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer
<UseExportProvider>
Public Class CpsDiagnosticItemSourceTests
<Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)>
Public Sub AnalyzerHasDiagnostics()
Dim workspaceXml =
<Workspace>
<Project Language="Visual Basic" CommonReferences="true">
</Project>
</Workspace>

Using workspace = TestWorkspace.Create(workspaceXml)
Dim project = workspace.Projects.Single()

Dim analyzers = New Dictionary(Of String, ImmutableArray(Of DiagnosticAnalyzer))

' The choice here of this analyzer to test with is arbitray -- there's nothing special about this
' analyzer versus any other one.
analyzers.Add(LanguageNames.VisualBasic, ImmutableArray.Create(Of DiagnosticAnalyzer)(New Microsoft.CodeAnalysis.VisualBasic.UseAutoProperty.VisualBasicUseAutoPropertyAnalyzer()))

Const analyzerPath = "C:\Analyzer.dll"
workspace.OnAnalyzerReferenceAdded(project.Id, New TestAnalyzerReferenceByLanguage(analyzers, analyzerPath))

Dim source As IAttachedCollectionSource = New CpsDiagnosticItemSource(
workspace,
project.FilePath,
project.Id,
New MockHierarchyItem() With {.CanonicalName = "\net472\analyzerdependency\" + analyzerPath},
New FakeAnalyzersCommandHandler, workspace.GetService(Of IDiagnosticAnalyzerService))

Assert.True(source.HasItems)
Dim diagnostic = Assert.IsAssignableFrom(Of ITreeDisplayItem)(Assert.Single(source.Items))
Assert.Contains(IDEDiagnosticIds.UseAutoPropertyDiagnosticId, diagnostic.Text)
End Using
End Sub
End Class
End Namespace

0 comments on commit 4262935

Please sign in to comment.