提交 0dcce2f5 编写于 作者: H Heejae Chang

make compiler diagnostic analyzer to always run first in IDE.

上级 5e5452b1
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Roslyn.Utilities;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
......@@ -17,51 +18,90 @@ private class HostStates
{
private readonly StateManager _owner;
private ImmutableDictionary<string, ImmutableDictionary<DiagnosticAnalyzer, StateSet>> _stateMap;
private ImmutableDictionary<string, DiagnosticAnalyzerMap> _stateMap;
public HostStates(StateManager owner)
{
_owner = owner;
_stateMap = ImmutableDictionary<string, ImmutableDictionary<DiagnosticAnalyzer, StateSet>>.Empty;
_stateMap = ImmutableDictionary<string, DiagnosticAnalyzerMap>.Empty;
}
public IEnumerable<StateSet> GetStateSets()
{
return _stateMap.Values.SelectMany(v => v.Values);
return _stateMap.Values.SelectMany(v => v.GetStateSets());
}
public IEnumerable<StateSet> GetOrCreateStateSets(string language)
{
var map = GetAnalyzerMap(language);
return map.Values;
return GetAnalyzerMap(language).GetStateSets();
}
public StateSet GetOrCreateStateSet(string language, DiagnosticAnalyzer analyzer)
{
var map = GetAnalyzerMap(language);
StateSet set;
if (map.TryGetValue(analyzer, out set))
{
return set;
}
return null;
return GetAnalyzerMap(language).GetStateSet(analyzer);
}
private ImmutableDictionary<DiagnosticAnalyzer, StateSet> GetAnalyzerMap(string language)
private DiagnosticAnalyzerMap GetAnalyzerMap(string language)
{
return ImmutableInterlocked.GetOrAdd(ref _stateMap, language, CreateLanguageSpecificAnalyzerMap, this);
}
private ImmutableDictionary<DiagnosticAnalyzer, StateSet> CreateLanguageSpecificAnalyzerMap(string language, HostStates @this)
private DiagnosticAnalyzerMap CreateLanguageSpecificAnalyzerMap(string language, HostStates @this)
{
var analyzersPerReference = _owner.AnalyzerManager.GetHostDiagnosticAnalyzersPerReference(language);
var analyzerMap = CreateAnalyzerMap(_owner.AnalyzerManager, language, analyzersPerReference.Values);
VerifyDiagnosticStates(analyzerMap.Values);
return analyzerMap;
return new DiagnosticAnalyzerMap(_owner.AnalyzerManager, language, analyzerMap);
}
private class DiagnosticAnalyzerMap
{
private readonly DiagnosticAnalyzer _compilerAnalyzer;
private readonly StateSet _compilerStateSet;
private readonly ImmutableDictionary<DiagnosticAnalyzer, StateSet> _map;
public DiagnosticAnalyzerMap(HostAnalyzerManager analyzerManager, string language, ImmutableDictionary<DiagnosticAnalyzer, StateSet> analyzerMap)
{
// hold directly on to compiler analyzer
_compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);
Contract.ThrowIfNull(_compilerAnalyzer);
_compilerStateSet = analyzerMap[_compilerAnalyzer];
// hold rest of analyzers
_map = analyzerMap.Remove(_compilerAnalyzer);
}
public IEnumerable<StateSet> GetStateSets()
{
// always return compiler one first
yield return _compilerStateSet;
// TODO: for now, this is static, but in future, we might consider making this a dynamic so that we process cheaper analyzer first.
foreach (var set in _map.Values)
{
yield return set;
}
}
public StateSet GetStateSet(DiagnosticAnalyzer analyzer)
{
if (_compilerAnalyzer == analyzer)
{
return _compilerStateSet;
}
StateSet set;
if (_map.TryGetValue(analyzer, out set))
{
return set;
}
return null;
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册