DiagnosticAnalyzerService_IncrementalAnalyzer.cs 2.6 KB
Newer Older
J
Jonathon Marolf 已提交
1 2 3
// 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.
4 5

using System.Runtime.CompilerServices;
H
Heejae Chang 已提交
6
using Microsoft.CodeAnalysis.Diagnostics.EngineV2;
7 8 9 10 11 12 13
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Diagnostics
{
14
    [ExportIncrementalAnalyzerProvider(
H
Heejae Chang 已提交
15
        highPriorityForActiveFile: true, name: WellKnownSolutionCrawlerAnalyzers.Diagnostic,
16
        workspaceKinds: new string[] { WorkspaceKind.Host, WorkspaceKind.Interactive, WorkspaceKind.AnyCodeRoslynWorkspace })]
17 18
    internal partial class DiagnosticAnalyzerService : IIncrementalAnalyzerProvider
    {
19 20
        private readonly ConditionalWeakTable<Workspace, DiagnosticIncrementalAnalyzer> _map;
        private readonly ConditionalWeakTable<Workspace, DiagnosticIncrementalAnalyzer>.CreateValueCallback _createIncrementalAnalyzer;
21 22 23

        private DiagnosticAnalyzerService()
        {
24
            _map = new ConditionalWeakTable<Workspace, DiagnosticIncrementalAnalyzer>();
25
            _createIncrementalAnalyzer = CreateIncrementalAnalyzerCallback;
26 27 28 29
        }

        public IIncrementalAnalyzer CreateIncrementalAnalyzer(Workspace workspace)
        {
30
            if (!workspace.Options.GetOption(ServiceComponentOnOffOptions.DiagnosticProvider))
31 32 33 34
            {
                return null;
            }

35
            return _map.GetValue(workspace, _createIncrementalAnalyzer);
36 37
        }

H
Heejae Chang 已提交
38 39 40
        public void ShutdownAnalyzerFrom(Workspace workspace)
        {
            // this should be only called once analyzer associated with the workspace is done.
C
CyrusNajmabadi 已提交
41
            if (_map.TryGetValue(workspace, out var analyzer))
H
Heejae Chang 已提交
42 43 44 45 46
            {
                analyzer.Shutdown();
            }
        }

47
        private DiagnosticIncrementalAnalyzer CreateIncrementalAnalyzerCallback(Workspace workspace)
48 49 50
        {
            // subscribe to active context changed event for new workspace
            workspace.DocumentActiveContextChanged += OnDocumentActiveContextChanged;
H
Heejae Chang 已提交
51

52
            return new DiagnosticIncrementalAnalyzer(this, LogAggregator.GetNextId(), workspace, HostAnalyzers, AnalyzerInfoCache, _hostDiagnosticUpdateSource);
53
        }
54

55
        private void OnDocumentActiveContextChanged(object sender, DocumentActiveContextChangedEventArgs e)
56
        {
57
            Reanalyze(e.Solution.Workspace, documentIds: SpecializedCollections.SingletonEnumerable(e.NewActiveContextDocumentId), highPriority: true);
58
        }
59 60
    }
}