DiagnosticIncrementalAnalyzer.cs 4.4 KB
Newer Older
1 2 3 4
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Immutable;
5
using System.Linq;
6 7
using System.Threading;
using System.Threading.Tasks;
8 9
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Options;
10 11 12 13
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
14
    // TODO: implement correct events and etc.
H
Heejae Chang 已提交
15
    internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
16 17
    {
        private readonly int _correlationId;
18

H
Heejae Chang 已提交
19 20 21 22 23 24
        public DiagnosticIncrementalAnalyzer(
            DiagnosticAnalyzerService owner,
            int correlationId,
            Workspace workspace,
            HostAnalyzerManager hostAnalyzerManager,
            AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
25
            : base(owner, workspace, hostAnalyzerManager, hostDiagnosticUpdateSource)
26 27 28 29
        {
            _correlationId = correlationId;
        }

30 31 32 33 34 35 36 37 38 39 40 41 42
        private static bool AnalysisEnabled(Document document)
        {
            // change it to check active file (or visible files), not open files if active file tracking is enabled.
            // otherwise, use open file.
            return document.IsOpen();
        }

        private bool FullAnalysisEnabled(Workspace workspace, string language)
        {
            return workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, language) &&
                   workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis);
        }

43
        private async Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsAsync(Project project, bool includeSuppressedDiagnostics, CancellationToken cancellationToken)
44 45 46 47 48 49 50 51
        {
            if (project == null)
            {
                return ImmutableArray<DiagnosticData>.Empty;
            }

            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

52
            var analyzers = HostAnalyzerManager.CreateDiagnosticAnalyzers(project);
53

54
            var compilationWithAnalyzer = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, cancellationToken);
55 56

            // REVIEW: this API is a bit strange. 
C
Charles Stoner 已提交
57
            //         if getting diagnostic is cancelled, it has to create new compilation and do everything from scratch again?
58
            var dxs = GetDiagnosticData(project, await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false)).ToImmutableArrayOrEmpty();
B
beep boop 已提交
59

60 61 62
            return dxs;
        }

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
        private IEnumerable<DiagnosticData> GetDiagnosticData(Project project, ImmutableArray<Diagnostic> diagnostics)
        {
            foreach (var diagnostic in diagnostics)
            {
                if (diagnostic.Location == Location.None)
                {
                    yield return DiagnosticData.Create(project, diagnostic);
                    continue;
                }

                var document = project.GetDocument(diagnostic.Location.SourceTree);
                if (document == null)
                {
                    continue;
                }

                yield return DiagnosticData.Create(document, diagnostic);
            }
        }

H
Heejae Chang 已提交
83
        private void RaiseEvents(Project project, ImmutableArray<DiagnosticData> diagnostics)
84 85 86 87 88 89 90 91 92 93
        {
            var groups = diagnostics.GroupBy(d => d.DocumentId);

            var solution = project.Solution;
            var workspace = solution.Workspace;

            foreach (var kv in groups)
            {
                if (kv.Key == null)
                {
94
                    Owner.RaiseDiagnosticsUpdated(
95 96
                        this, DiagnosticsUpdatedArgs.DiagnosticsCreated(
                            ValueTuple.Create(this, project.Id), workspace, solution, project.Id, null, kv.ToImmutableArrayOrEmpty()));
97 98 99
                    continue;
                }

100
                Owner.RaiseDiagnosticsUpdated(
101 102
                    this, DiagnosticsUpdatedArgs.DiagnosticsCreated(
                        ValueTuple.Create(this, kv.Key), workspace, solution, project.Id, kv.Key, kv.ToImmutableArrayOrEmpty()));
103
            }
104
        }
105 106 107 108 109 110

        public override bool ContainsDiagnostics(Workspace workspace, ProjectId projectId)
        {
            // for now, it always return false;
            return false;
        }
111 112
    }
}