private static ImmutableDictionary <DiagnosticAnalyzer, StateSet> CreateStateSetMap( DiagnosticAnalyzerInfoCache analyzerInfoCache, string language, IEnumerable <ImmutableArray <DiagnosticAnalyzer> > analyzerCollection) { var compilerAnalyzer = analyzerInfoCache.GetCompilerDiagnosticAnalyzer(language); var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, StateSet>(); foreach (var analyzers in analyzerCollection) { foreach (var analyzer in analyzers) { // TODO: // #1, all de-duplication should move to DiagnosticAnalyzerInfoCache // #2, not sure whether de-duplication of analyzer itself makes sense. this can only happen // if user deliberately put same analyzer twice. if (builder.ContainsKey(analyzer)) { continue; } var buildToolName = analyzer == compilerAnalyzer ? PredefinedBuildTools.Live : GetBuildToolName(analyzerInfoCache, language, analyzer); builder.Add(analyzer, new StateSet(language, analyzer, buildToolName)); } } return(builder.ToImmutable()); }
private async Task <ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> > RemoveCompilerSemanticErrorsIfProjectNotLoadedAsync( ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> result, Project project, CancellationToken cancellationToken) { // see whether solution is loaded successfully var projectLoadedSuccessfully = await project.HasSuccessfullyLoadedAsync(cancellationToken).ConfigureAwait(false); if (projectLoadedSuccessfully) { return(result); } var compilerAnalyzer = DiagnosticAnalyzerInfoCache.GetCompilerDiagnosticAnalyzer(project.Language); if (compilerAnalyzer == null) { // this language doesn't support compiler analyzer return(result); } if (!result.TryGetValue(compilerAnalyzer, out var analysisResult)) { // no result from compiler analyzer return(result); } Logger.Log(FunctionId.Diagnostics_ProjectDiagnostic, p => $"Failed to Load Successfully ({p.FilePath ?? p.Name})", project); // get rid of any result except syntax from compiler analyzer result var newCompilerAnalysisResult = analysisResult.DropExceptSyntax(); // return new result return(result.SetItem(compilerAnalyzer, newCompilerAnalysisResult)); }
public HostAnalyzerStateSets(DiagnosticAnalyzerInfoCache analyzerInfoCache, string language, ImmutableDictionary <DiagnosticAnalyzer, StateSet> analyzerMap) { StateSetMap = analyzerMap; _compilerAnalyzer = analyzerInfoCache.GetCompilerDiagnosticAnalyzer(language); // order statesets // order will be in this order // BuiltIn Compiler Analyzer (C#/VB) < Regular DiagnosticAnalyzers < Document/ProjectDiagnosticAnalyzers OrderedStateSets = StateSetMap.Values.OrderBy(PriorityComparison).ToImmutableArray(); }
public ImmutableArray <StateSet> CreateBuildOnlyProjectStateSet(Project project) { var hostStateSets = GetOrCreateHostStateSets(project.Language).OrderedStateSets; if (!project.SupportsCompilation) { // languages which don't use our compilation model but diagnostic framework, // all their analyzer should be host analyzers. return all host analyzers // for the language return(hostStateSets); } // now create analyzer to host stateset map var hostStateSetMap = hostStateSets.ToDictionary(s => s.Analyzer, s => s); // create project analyzer reference identity map var referenceIdentities = project.AnalyzerReferences.Select(r => _analyzerInfoCache.GetAnalyzerReferenceIdentity(r)).ToSet(); // create build only stateSet array var stateSets = ImmutableArray.CreateBuilder <StateSet>(); // we always include compiler analyzer in build only state var compilerAnalyzer = _analyzerInfoCache.GetCompilerDiagnosticAnalyzer(project.Language); if (compilerAnalyzer == null) { // only way to get here is if MEF is corrupted. FailFast.OnFatalException(new Exception("How can this happen?")); } if (hostStateSetMap.TryGetValue(compilerAnalyzer, out var compilerStateSet)) { stateSets.Add(compilerStateSet); } // now add all project analyzers stateSets.AddRange(GetOrUpdateProjectAnalyzerMap(project).Values); // now add analyzers that exist in both host and project var analyzerMap = _analyzerInfoCache.GetOrCreateHostDiagnosticAnalyzersPerReference(project.Language); foreach (var(identity, analyzers) in analyzerMap) { 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 analyzers) { if (hostStateSetMap.TryGetValue(analyzer, out var stateSet) && stateSet != compilerStateSet) { stateSets.Add(stateSet); } } } return(stateSets.ToImmutable()); }