DiagnosticIncrementalAnalyzer.StateManager.HostStates.cs 3.7 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.
H
Heejae Chang 已提交
4

5 6
#nullable enable

7
using System;
H
Heejae Chang 已提交
8 9 10
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
11
using Roslyn.Utilities;
H
Heejae Chang 已提交
12 13 14 15 16 17 18

namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
    internal partial class DiagnosticIncrementalAnalyzer
    {
        private partial class StateManager
        {
19 20
            public IEnumerable<StateSet> GetAllHostStateSets()
                => _hostAnalyzerStateMap.Values.SelectMany(v => v.OrderedStateSets);
H
Heejae Chang 已提交
21

22 23 24
            private HostAnalyzerStateSets GetOrCreateHostStateSets(string language)
            {
                static HostAnalyzerStateSets CreateLanguageSpecificAnalyzerMap(string language, DiagnosticAnalyzerInfoCache analyzerInfoCache)
H
Heejae Chang 已提交
25
                {
26
                    var analyzersPerReference = analyzerInfoCache.GetOrCreateHostDiagnosticAnalyzersPerReference(language);
H
Heejae Chang 已提交
27

28
                    var analyzerMap = CreateStateSetMap(analyzerInfoCache, language, analyzersPerReference.Values, includeFileContentLoadAnalyzer: true);
29
                    VerifyUniqueStateNames(analyzerMap.Values);
H
Heejae Chang 已提交
30

31
                    return new HostAnalyzerStateSets(analyzerInfoCache, language, analyzerMap);
H
Heejae Chang 已提交
32 33
                }

34 35
                return ImmutableInterlocked.GetOrAdd(ref _hostAnalyzerStateMap, language, CreateLanguageSpecificAnalyzerMap, _analyzerInfoCache);
            }
H
Heejae Chang 已提交
36

37 38
            private sealed class HostAnalyzerStateSets
            {
39
                private const int FileContentLoadAnalyzerPriority = -3;
40 41
                private const int BuiltInCompilerPriority = -2;
                private const int RegularDiagnosticAnalyzerPriority = -1;
H
Heejae Chang 已提交
42

43
                private readonly DiagnosticAnalyzer? _compilerAnalyzer;
H
Heejae Chang 已提交
44

45 46
                // ordered by priority
                public readonly ImmutableArray<StateSet> OrderedStateSets;
H
Heejae Chang 已提交
47

48
                public readonly ImmutableDictionary<DiagnosticAnalyzer, StateSet> StateSetMap;
H
Heejae Chang 已提交
49

50
                public HostAnalyzerStateSets(DiagnosticAnalyzerInfoCache analyzerInfoCache, string language, ImmutableDictionary<DiagnosticAnalyzer, StateSet> analyzerMap)
H
Heejae Chang 已提交
51
                {
52
                    StateSetMap = analyzerMap;
H
Heejae Chang 已提交
53

54
                    _compilerAnalyzer = analyzerInfoCache.GetCompilerDiagnosticAnalyzer(language);
H
Heejae Chang 已提交
55

56 57 58 59 60
                    // order statesets
                    // order will be in this order
                    // BuiltIn Compiler Analyzer (C#/VB) < Regular DiagnosticAnalyzers < Document/ProjectDiagnosticAnalyzers
                    OrderedStateSets = StateSetMap.Values.OrderBy(PriorityComparison).ToImmutableArray();
                }
H
Heejae Chang 已提交
61

62 63 64 65
                private int PriorityComparison(StateSet state1, StateSet state2)
                {
                    return GetPriority(state1) - GetPriority(state2);
                }
H
Heejae Chang 已提交
66

67 68 69 70
                private int GetPriority(StateSet state)
                {
                    // compiler gets highest priority
                    if (state.Analyzer == _compilerAnalyzer)
H
Heejae Chang 已提交
71
                    {
72
                        return BuiltInCompilerPriority;
H
Heejae Chang 已提交
73 74
                    }

75
                    return state.Analyzer switch
H
Heejae Chang 已提交
76
                    {
77 78 79 80 81
                        FileContentLoadAnalyzer _ => FileContentLoadAnalyzerPriority,
                        DocumentDiagnosticAnalyzer analyzer => Math.Max(0, analyzer.Priority),
                        ProjectDiagnosticAnalyzer analyzer => Math.Max(0, analyzer.Priority),
                        _ => RegularDiagnosticAnalyzerPriority,
                    };
H
Heejae Chang 已提交
82 83 84 85 86
                }
            }
        }
    }
}