private Task <AnalyzerDependencyResults> GetConflictsAsync()
        {
            ImmutableHashSet <string> currentAnalyzerPaths = _workspace.CurrentSolution
                                                             .Projects
                                                             .SelectMany(p => p.AnalyzerReferences)
                                                             .OfType <AnalyzerFileReference>()
                                                             .Select(a => a.FullPath)
                                                             .ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);

            if (currentAnalyzerPaths.SetEquals(_analyzerPaths))
            {
                return(_task);
            }

            _cancellationTokenSource.Cancel();
            _cancellationTokenSource = new CancellationTokenSource();
            _analyzerPaths           = currentAnalyzerPaths;

            _task = _task.SafeContinueWith(_ =>
            {
                IEnumerable <AssemblyIdentity> loadedAssemblies    = AppDomain.CurrentDomain.GetAssemblies().Select(assembly => AssemblyIdentity.FromAssemblyDefinition(assembly));
                IgnorableAssemblyIdentityList loadedAssembliesList = new IgnorableAssemblyIdentityList(loadedAssemblies);

                IIgnorableAssemblyList[] ignorableAssemblyLists = new[] { s_systemPrefixList, s_codeAnalysisPrefixList, s_explicitlyIgnoredAssemblyList, s_assembliesIgnoredByNameList, loadedAssembliesList };
                return(new AnalyzerDependencyChecker(currentAnalyzerPaths, ignorableAssemblyLists, _bindingRedirectionService).Run(_cancellationTokenSource.Token));
            },
                                           TaskScheduler.Default);

            return(_task);
        }
Exemple #2
0
        // Method is static to prevent accidental use of mutable state in this class
        private static void AnalyzeAndReportConflictsInSolution(
            Solution solution,
            ImmutableHashSet <string> currentAnalyzerPaths,
            HostDiagnosticUpdateSource hostDiagnosticUpdateSource,
            CancellationToken cancellationToken)
        {
            var loadedAssemblies     = AppDomain.CurrentDomain.GetAssemblies().Select(assembly => AssemblyIdentity.FromAssemblyDefinition(assembly));
            var loadedAssembliesList = new IgnorableAssemblyIdentityList(loadedAssemblies);

            var ignorableAssemblyLists = new[] { s_systemPrefixList, s_codeAnalysisPrefixList, s_explicitlyIgnoredAssemblyList, s_assembliesIgnoredByNameList, loadedAssembliesList };

            cancellationToken.ThrowIfCancellationRequested();

            var results = AnalyzerDependencyChecker.ComputeDependencyConflicts(currentAnalyzerPaths, ignorableAssemblyLists, s_bindingRedirectionService, cancellationToken);

            var builder = ImmutableArray.CreateBuilder <DiagnosticData>();

            var conflicts           = results.Conflicts;
            var missingDependencies = results.MissingDependencies;

            foreach (var project in solution.Projects)
            {
                builder.Clear();

                // If our analysis has been cancelled, it means another request has been queued behind us; thus it's OK to stop
                // doing the analysis now and let that other one fix up any stale results.
                cancellationToken.ThrowIfCancellationRequested();

                var analyzerFilePaths = new HashSet <string>(
                    project.AnalyzerReferences
                    .OfType <AnalyzerFileReference>()
                    .Select(f => f.FullPath),
                    StringComparer.OrdinalIgnoreCase);

                foreach (var conflict in conflicts)
                {
                    if (analyzerFilePaths.Contains(conflict.AnalyzerFilePath1) ||
                        analyzerFilePaths.Contains(conflict.AnalyzerFilePath2))
                    {
                        var messageArguments = new string[] { conflict.AnalyzerFilePath1, conflict.AnalyzerFilePath2, conflict.Identity.ToString() };
                        if (DiagnosticData.TryCreate(s_analyzerDependencyConflictRule, messageArguments, project.Id, solution.Workspace, out var diagnostic))
                        {
                            builder.Add(diagnostic);
                        }
                    }
                }

                foreach (var missingDependency in missingDependencies)
                {
                    if (analyzerFilePaths.Contains(missingDependency.AnalyzerPath))
                    {
                        var messageArguments = new string[] { missingDependency.AnalyzerPath, missingDependency.DependencyIdentity.ToString() };
                        if (DiagnosticData.TryCreate(s_missingAnalyzerReferenceRule, messageArguments, project.Id, solution.Workspace, out var diagnostic))
                        {
                            builder.Add(diagnostic);
                        }
                    }
                }

                hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(project.Id, s_dependencyConflictErrorId, builder.ToImmutable());
            }

            foreach (var conflict in conflicts)
            {
                LogConflict(conflict);
            }

            foreach (var missingDependency in missingDependencies)
            {
                LogMissingDependency(missingDependency);
            }
        }
        private Task<AnalyzerDependencyResults> GetConflictsAsync()
        {
            ImmutableHashSet<string> currentAnalyzerPaths = _workspace.CurrentSolution
                .Projects
                .SelectMany(p => p.AnalyzerReferences)
                .OfType<AnalyzerFileReference>()
                .Select(a => a.FullPath)
                .ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);

            if (currentAnalyzerPaths.SetEquals(_analyzerPaths))
            {
                return _task;
            }

            _cancellationTokenSource.Cancel();
            _cancellationTokenSource = new CancellationTokenSource();
            _analyzerPaths = currentAnalyzerPaths;

            _task = _task.SafeContinueWith(_ =>
            {
                IEnumerable<AssemblyIdentity> loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(assembly => AssemblyIdentity.FromAssemblyDefinition(assembly));
                IgnorableAssemblyIdentityList loadedAssembliesList = new IgnorableAssemblyIdentityList(loadedAssemblies);
                IIgnorableAssemblyList[] ignorableAssemblyLists = new[] { s_systemPrefixList, loadedAssembliesList };

                return new AnalyzerDependencyChecker(currentAnalyzerPaths, ignorableAssemblyLists, _bindingRedirectionService).Run(_cancellationTokenSource.Token);
            },
            TaskScheduler.Default);

            return _task;
        }