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) { }
        }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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));
        }
Beispiel #9
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);
            }
        }