public async void CheckForConflictsAsync() { try { ImmutableArray <AnalyzerDependencyConflict> conflicts = await GetConflictsAsync().ConfigureAwait(continueOnCapturedContext: true); var builder = ImmutableArray.CreateBuilder <DiagnosticData>(); foreach (var project in _workspace.ProjectTracker.Projects) { builder.Clear(); foreach (var conflict in conflicts) { if (project.CurrentProjectAnalyzersContains(conflict.AnalyzerFilePath1) || project.CurrentProjectAnalyzersContains(conflict.AnalyzerFilePath2)) { builder.Add(CreateDiagnostic(project.Id, conflict)); } } _updateSource.UpdateDiagnosticsForProject(project.Id, s_dependencyConflictErrorId, builder.ToImmutable()); } foreach (var conflict in conflicts) { LogConflict(conflict); } } catch (OperationCanceledException) { } }
private void RaiseAnalyzerChangedWarning(ProjectId projectId, string analyzerPath) { var messageArguments = new string[] { analyzerPath }; if (DiagnosticData.TryCreate(_analyzerChangedRule, messageArguments, projectId, _workspace, out var diagnostic)) { _updateSource.UpdateDiagnosticsForProject(projectId, Tuple.Create(s_analyzerChangedErrorId, analyzerPath), SpecializedCollections.SingletonEnumerable(diagnostic)); } }
private void OnAnalyzerLoadError(object sender, AnalyzerLoadFailureEventArgs e) { var data = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(_workspace, _projectId, _language, _fullPath, e); _analyzerLoadErrors = _analyzerLoadErrors ?? new List <DiagnosticData>(); _analyzerLoadErrors.Add(data); _hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(_projectId, this, _analyzerLoadErrors); }
private void OnAnalyzerLoadError(object sender, AnalyzerLoadFailureEventArgs e) { var data = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(e, FullPath, _projectId, _language); lock (_gate) { _analyzerLoadErrors = _analyzerLoadErrors.Add(data); _hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(_projectId, this, _analyzerLoadErrors); } }
private void Tracker_UpdatedOnDisk(object sender, EventArgs e) { FileChangeTracker tracker = (FileChangeTracker)sender; var filePath = tracker.FilePath; lock (_fileChangeTrackersLock) { // Once we've created a diagnostic for a given analyzer file, there's // no need to keep watching it. _fileChangeTrackers.Remove(filePath); } tracker.Dispose(); tracker.UpdatedOnDisk -= Tracker_UpdatedOnDisk; string id = ServicesVSResources.WRN_AnalyzerChangedId; string category = ServicesVSResources.ErrorCategory; string message = string.Format(ServicesVSResources.WRN_AnalyzerChangedMessage, filePath); // Traverse the chain of requesting assemblies to get back to the original analyzer // assembly. var assemblyPath = filePath; var requestingAssemblyPath = AnalyzerFileReference.TryGetRequestingAssemblyPath(filePath); while (requestingAssemblyPath != null) { assemblyPath = requestingAssemblyPath; requestingAssemblyPath = AnalyzerFileReference.TryGetRequestingAssemblyPath(assemblyPath); } var projectsWithAnalyzer = _workspace.ProjectTracker.Projects.Where(p => p.CurrentProjectAnalyzersContains(assemblyPath)).ToArray(); foreach (var project in projectsWithAnalyzer) { DiagnosticData data = new DiagnosticData( id, category, message, ServicesVSResources.WRN_AnalyzerChangedMessage, severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray <string> .Empty, workspace: _workspace, projectId: project.Id); _updateSource.UpdateDiagnosticsForProject(project.Id, Tuple.Create(s_analyzerChangedErrorId, filePath), SpecializedCollections.SingletonEnumerable(data)); } }
private void OnAnalyzerLoadError(object sender, AnalyzerLoadFailureEventArgs e) { string id; string message; string messageFormat; switch (e.ErrorCode) { case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToLoadAnalyzer: id = _language == LanguageNames.CSharp ? WRN_UnableToLoadAnalyzerIdCS : WRN_UnableToLoadAnalyzerIdVB; messageFormat = ServicesVSResources.WRN_UnableToLoadAnalyzer; message = string.Format(ServicesVSResources.WRN_UnableToLoadAnalyzer, _fullPath, e.Exception.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToCreateAnalyzer: id = _language == LanguageNames.CSharp ? WRN_AnalyzerCannotBeCreatedIdCS : WRN_AnalyzerCannotBeCreatedIdVB; messageFormat = ServicesVSResources.WRN_AnalyzerCannotBeCreated; message = string.Format(ServicesVSResources.WRN_AnalyzerCannotBeCreated, e.TypeName, _fullPath, e.Exception.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.NoAnalyzers: id = _language == LanguageNames.CSharp ? WRN_NoAnalyzerInAssemblyIdCS : WRN_NoAnalyzerInAssemblyIdVB; messageFormat = ServicesVSResources.WRN_NoAnalyzerInAssembly; message = string.Format(ServicesVSResources.WRN_NoAnalyzerInAssembly, _fullPath); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.None: default: return; } DiagnosticData data = new DiagnosticData( id, ServicesVSResources.ErrorCategory, message, messageFormat, severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray <string> .Empty, workspace: _workspace, projectId: _projectId); _analyzerLoadErrors = _analyzerLoadErrors ?? new List <DiagnosticData>(); _analyzerLoadErrors.Add(data); _hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(_projectId, this, _analyzerLoadErrors); }
private void RaiseAnalyzerChangedWarning(ProjectId projectId, string analyzerPath) { string message = string.Format(ServicesVSResources.WRN_AnalyzerChangedMessage, analyzerPath); DiagnosticData data = new DiagnosticData( IDEDiagnosticIds.AnalyzerChangedId, FeaturesResources.ErrorCategory, message, ServicesVSResources.WRN_AnalyzerChangedMessage, severity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, workspace: _workspace, projectId: projectId, title: ServicesVSResources.WRN_AnalyzerChangedTitle); _updateSource.UpdateDiagnosticsForProject(projectId, Tuple.Create(s_analyzerChangedErrorId, analyzerPath), SpecializedCollections.SingletonEnumerable(data)); }
private void RaiseAnalyzerChangedWarning(ProjectId projectId, string analyzerPath) { string id = ServicesVSResources.WRN_AnalyzerChangedId; string category = ServicesVSResources.ErrorCategory; string message = string.Format(ServicesVSResources.WRN_AnalyzerChangedMessage, analyzerPath); DiagnosticData data = new DiagnosticData( id, category, message, ServicesVSResources.WRN_AnalyzerChangedMessage, severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray <string> .Empty, workspace: _workspace, projectId: projectId); _updateSource.UpdateDiagnosticsForProject(projectId, Tuple.Create(s_analyzerChangedErrorId, analyzerPath), SpecializedCollections.SingletonEnumerable(data)); }
// 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); } }