Example #1
0
            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();
                }
Example #4
0
            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());
            }