File: SolutionExplorer\AnalyzerReferenceManager.cs
Web Access
Project: src\src\VisualStudio\Core\Impl\Microsoft.VisualStudio.LanguageServices.Implementation.csproj (Microsoft.VisualStudio.LanguageServices.Implementation)
// 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.
 
using System;
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using VSLangProj140;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer;
 
/// <summary>
/// This class is responsible for showing an add analyzer dialog to the user and adding the analyzer
/// that is selected by the user in the dialog.
/// </summary>
[Export]
internal sealed class AnalyzerReferenceManager : IVsReferenceManagerUser
{
    private readonly IServiceProvider _serviceProvider;
    private IVsReferenceManager? _referenceManager;
    private readonly AnalyzerItemsTracker _tracker;
 
    [ImportingConstructor]
    [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
    public AnalyzerReferenceManager(
        [Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
        AnalyzerItemsTracker analyzerItemsTracker)
    {
        _serviceProvider = serviceProvider;
        _tracker = analyzerItemsTracker;
    }
 
    /// <summary>
    /// Show the add analyzer dialog.
    /// </summary>
    public void ShowDialog()
    {
        var referenceManager = GetReferenceManager();
        if (referenceManager != null &&
            _tracker.SelectedHierarchy != null)
        {
            referenceManager.ShowReferenceManager(this,
                                                  SolutionExplorerShim.Add_Analyzer,
                                                  null,
                                                  VSConstants.FileReferenceProvider_Guid,
                                                  fForceShowDefaultProvider: false);
        }
    }
 
    /// <summary>
    /// Called by the ReferenceManagerDialog to apply the user selection of references.
    /// </summary>
    public void ChangeReferences(uint operation, IVsReferenceProviderContext changedContext)
    {
        var referenceOperation = (__VSREFERENCECHANGEOPERATION)operation;
 
        // The items selected in Solution Explorer should correspond to exactly one
        // IVsHierarchy, otherwise we shouldn't have even tried to show the dialog.
        Contract.ThrowIfNull(_tracker.SelectedHierarchy);
        if (_tracker.SelectedHierarchy.TryGetProject(out var project))
        {
 
            if (project.Object is VSProject3 vsproject)
            {
                foreach (IVsReference reference in changedContext.References)
                {
                    var path = reference.FullPath;
 
                    switch (referenceOperation)
                    {
                        case __VSREFERENCECHANGEOPERATION.VSREFERENCECHANGEOPERATION_ADD:
                            vsproject.AnalyzerReferences.Add(path);
                            break;
                        case __VSREFERENCECHANGEOPERATION.VSREFERENCECHANGEOPERATION_REMOVE:
                            vsproject.AnalyzerReferences.Remove(path);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
 
    /// <summary>
    /// Called by the ReferenceManagerDialog to determine what contexts to show in the UI.
    /// </summary>
    public Array GetProviderContexts()
    {
        // Return just the File provider context so that just the browse tab shows up.
        var context = (IVsFileReferenceProviderContext)GetReferenceManager().CreateProviderContext(VSConstants.FileReferenceProvider_Guid);
        context.BrowseFilter = string.Format("{0} (*.dll)\0*.dll\0", SolutionExplorerShim.Analyzer_Files);
        return new[] { context };
    }
 
    private IVsReferenceManager GetReferenceManager()
    {
        if (_referenceManager == null)
        {
            _referenceManager = _serviceProvider.GetService(typeof(SVsReferenceManager)) as IVsReferenceManager;
            Assumes.Present(_referenceManager);
        }
 
        return _referenceManager;
    }
}