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); }
// 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; }