/// <summary> /// Return <see cref="StateSet"/>s that are added as the given <see cref="Project"/>'s AnalyzerReferences. /// This will never create new <see cref="StateSet"/> but will return ones already created. /// </summary> public ImmutableArray <StateSet> CreateBuildOnlyProjectStateSet(Project project) { // create project analyzer reference identity map var referenceIdentities = project.AnalyzerReferences.Select(r => _analyzerManager.GetAnalyzerReferenceIdentity(r)).ToSet(); // now create analyzer to host stateset map var hostStateSetMap = _hostStates.GetOrCreateStateSets(project.Language).ToDictionary(s => s.Analyzer, s => s); // create build only stateSet array var stateSets = ImmutableArray.CreateBuilder <StateSet>(); // we always include compiler analyzer in build only state var compilerAnalyzer = _analyzerManager.GetCompilerDiagnosticAnalyzer(project.Language); if (compilerAnalyzer == null) { // only way to get here is if MEF is corrupted. FailFast.OnFatalException(new Exception("How can this happen?")); } StateSet compilerStateSet; if (hostStateSetMap.TryGetValue(compilerAnalyzer, out compilerStateSet)) { stateSets.Add(compilerStateSet); } // now add all project analyzers stateSets.AddRange(_projectStates.GetOrUpdateStateSets(project)); // now add analyzers that exist in both host and project var analyzerMap = _analyzerManager.GetHostDiagnosticAnalyzersPerReference(project.Language); foreach (var kv in analyzerMap) { var identity = kv.Key; if (!referenceIdentities.Contains(identity)) { // it is from host analyzer package rather than project analyzer reference // which build doesn't have continue; } // if same analyzer exists both in host (vsix) and in analyzer reference, // we include it in build only analyzer. foreach (var analyzer in kv.Value) { StateSet stateSet; if (hostStateSetMap.TryGetValue(analyzer, out stateSet) && stateSet != compilerStateSet) { stateSets.Add(stateSet); } } } return(stateSets.ToImmutable()); }
/// <summary> /// Return <see cref="StateSet"/>s that are added as the given <see cref="Project"/>'s AnalyzerReferences. /// This will never create new <see cref="StateSet"/> but will return ones already created. /// </summary> public ImmutableArray <StateSet> CreateBuildOnlyProjectStateSet(Project project) { var referenceIdentities = project.AnalyzerReferences.Select(r => _analyzerManager.GetAnalyzerReferenceIdentity(r)).ToSet(); var stateSetMap = GetStateSets(project).ToDictionary(s => s.Analyzer, s => s); var stateSets = ImmutableArray.CreateBuilder <StateSet>(); // we always include compiler analyzer in build only state var compilerAnalyzer = _analyzerManager.GetCompilerDiagnosticAnalyzer(project.Language); StateSet compilerStateSet; if (stateSetMap.TryGetValue(compilerAnalyzer, out compilerStateSet)) { stateSets.Add(compilerStateSet); } var analyzerMap = _analyzerManager.GetHostDiagnosticAnalyzersPerReference(project.Language); foreach (var kv in analyzerMap) { var identity = kv.Key; if (!referenceIdentities.Contains(identity)) { // it is from host analyzer package rather than project analyzer reference // which build doesn't have continue; } // if same analyzer exists both in host (vsix) and in analyzer reference, // we include it in build only analyzer. foreach (var analyzer in kv.Value) { StateSet stateSet; if (stateSetMap.TryGetValue(analyzer, out stateSet) && stateSet != compilerStateSet) { stateSets.Add(stateSet); } } } return(stateSets.ToImmutable()); }