public StateManager(HostAnalyzerManager analyzerManager)
            {
                _analyzerManager = analyzerManager;

                _hostStates = new HostStates(this);
                _projectStates = new ProjectStates(this);
            }
 public DiagnosticIncrementalAnalyzer(DiagnosticAnalyzerService owner, int correlationId, Workspace workspace, HostAnalyzerManager hostAnalyzerManager, AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
     : base(workspace, hostDiagnosticUpdateSource)
 {
     _correlationId       = correlationId;
     _owner               = owner;
     _hostAnalyzerManager = hostAnalyzerManager;
 }
        public override async Task SynchronizeWithBuildAsync(Project project, ImmutableArray <DiagnosticData> diagnostics)
        {
            if (!PreferBuildErrors(project.Solution.Workspace))
            {
                // prefer live errors over build errors
                return;
            }

            using (var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject())
            {
                var lookup = CreateDiagnosticIdLookup(diagnostics);

                foreach (var stateSet in _stateManager.GetStateSets(project))
                {
                    var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                    var liveDiagnostics = ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object);

                    // we are using Default so that things like LB can't use cached information
                    var projectTextVersion = VersionStamp.Default;
                    var semanticVersion    = await project.GetDependentSemanticVersionAsync(CancellationToken.None).ConfigureAwait(false);

                    var state = stateSet.GetState(StateType.Project);
                    var existingDiagnostics = await state.TryGetExistingDataAsync(project, CancellationToken.None).ConfigureAwait(false);

                    var mergedDiagnostics = MergeDiagnostics(liveDiagnostics, GetExistingDiagnostics(existingDiagnostics));
                    await state.PersistAsync(project, new AnalysisData(projectTextVersion, semanticVersion, mergedDiagnostics), CancellationToken.None).ConfigureAwait(false);

                    RaiseDiagnosticsUpdated(StateType.Project, project.Id, stateSet, new SolutionArgument(project), mergedDiagnostics);
                }
            }
        }
            private static ImmutableDictionary <DiagnosticAnalyzer, StateSet> CreateAnalyzerMap(
                HostAnalyzerManager analyzerManager, string language, IEnumerable <ImmutableArray <DiagnosticAnalyzer> > analyzerCollection)
            {
                var compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);

                var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, StateSet>();

                foreach (var analyzers in analyzerCollection)
                {
                    foreach (var analyzer in analyzers)
                    {
                        // TODO:
                        // #1, all de -duplication should move to HostAnalyzerManager
                        // #2, not sure whether de-duplication of analyzer itself makes sense. this can only happen
                        //     if user deliberately put same analyzer twice.
                        if (builder.ContainsKey(analyzer))
                        {
                            continue;
                        }

                        var buildToolName = analyzer == compilerAnalyzer ?
                                            PredefinedBuildTools.Live : GetBuildToolName(analyzerManager, language, analyzer);

                        builder.Add(analyzer, new StateSet(language, analyzer, buildToolName));
                    }
                }

                return(builder.ToImmutable());
            }
Пример #5
0
        private ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> CreateAnalysisResults(
            Project project, ImmutableArray <StateSet> stateSets, ProjectAnalysisData oldAnalysisData, ImmutableArray <DiagnosticData> diagnostics)
        {
            using (var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject())
            {
                // we can't distinguish locals and non locals from build diagnostics nor determine right snapshot version for the build.
                // so we put everything in as semantic local with default version. this lets us to replace those to live diagnostics when needed easily.
                var version = VersionStamp.Default;
                var lookup  = diagnostics.ToLookup(d => d.Id);

                var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResult>();
                foreach (var stateSet in stateSets)
                {
                    var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                    var liveDiagnostics = MergeDiagnostics(ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object), GetDiagnostics(oldAnalysisData.GetResult(stateSet.Analyzer)));

                    var group  = liveDiagnostics.GroupBy(d => d.DocumentId);
                    var result = new DiagnosticAnalysisResult(
                        project.Id,
                        version,
                        documentIds: group.Where(g => g.Key != null).Select(g => g.Key).ToImmutableHashSet(),
                        syntaxLocals: ImmutableDictionary <DocumentId, ImmutableArray <DiagnosticData> > .Empty,
                        semanticLocals: group.Where(g => g.Key != null).ToImmutableDictionary(g => g.Key, g => g.ToImmutableArray()),
                        nonLocals: ImmutableDictionary <DocumentId, ImmutableArray <DiagnosticData> > .Empty,
                        others: group.Where(g => g.Key == null).SelectMany(g => g).ToImmutableArrayOrEmpty(),
                        fromBuild: true);

                    builder.Add(stateSet.Analyzer, result);
                }

                return(builder.ToImmutable());
            }
        }
            public StateManager(HostAnalyzerManager analyzerManager)
            {
                _analyzerManager = analyzerManager;

                _hostStates    = new HostStates(this);
                _projectStates = new ProjectStates(this);
            }
Пример #7
0
        private bool ShouldRunForFullProject(DiagnosticAnalyzer analyzer, Project project)
        {
            // PERF: Don't query descriptors for compiler analyzer, always execute it.
            if (HostAnalyzerManager.IsCompilerDiagnosticAnalyzer(project.Language, analyzer))
            {
                return(true);
            }

            return(Owner.ShouldRunForFullProject(analyzer, project));
        }
        private bool ShouldRunForFullProject(DiagnosticAnalyzer analyzer, Project project)
        {
            // PERF: Don't query descriptors for compiler analyzer, always execute it.
            if (HostAnalyzerManager.IsCompilerDiagnosticAnalyzer(project.Language, analyzer))
            {
                return(true);
            }

            // most of analyzers, number of descriptor is quite small, so this should be cheap.
            return(Owner.GetDiagnosticDescriptors(analyzer).Any(d => GetEffectiveSeverity(d, project.CompilationOptions) != ReportDiagnostic.Hidden));
        }
            private static string GetErrorSourceName(HostAnalyzerManager analyzerManager, string language, DiagnosticAnalyzer analyzer)
            {
                var packageName = analyzerManager.GetDiagnosticAnalyzerPackageName(language, analyzer);

                if (packageName == null)
                {
                    return(null);
                }

                return($"{analyzer.GetAnalyzerAssemblyName()} [{packageName}]");
            }
        public DiagnosticIncrementalAnalyzer(
            DiagnosticAnalyzerService owner,
            int correlationId,
            Workspace workspace,
            HostAnalyzerManager analyzerManager,
            AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
            : base(owner, workspace, analyzerManager, hostDiagnosticUpdateSource)
        {
            _correlationId = correlationId;
            _memberRangeMap = new MemberRangeMap();
            _executor = new AnalyzerExecutor(this);

            _stateManager = new StateManager(analyzerManager);
            _stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;
        }
Пример #11
0
 public DiagnosticIncrementalAnalyzer(
     DiagnosticAnalyzerService owner,
     int correlationId,
     Workspace workspace,
     HostAnalyzerManager analyzerManager,
     AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
     : base(owner, workspace, analyzerManager, hostDiagnosticUpdateSource)
 {
     _correlationId  = correlationId;
     _memberRangeMap = new MemberRangeMap();
     _executor       = new AnalyzerExecutor(this);
     _eventQueue     = new SimpleTaskQueue(TaskScheduler.Default);
     _stateManager   = new StateManager(analyzerManager);
     _stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;
 }
 public DiagnosticIncrementalAnalyzer(
     DiagnosticAnalyzerService owner,
     int correlationId,
     Workspace workspace,
     HostAnalyzerManager analyzerManager,
     AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
     : base(owner, workspace, analyzerManager, hostDiagnosticUpdateSource)
 {
     _correlationId = correlationId;
     _memberRangeMap = new MemberRangeMap();
     _executor = new AnalyzerExecutor(this);
     _eventQueue = new SimpleTaskQueue(TaskScheduler.Default);
     _stateManager = new StateManager(analyzerManager);
     _stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;
     _solutionCrawlerAnalysisState = new SolutionCrawlerAnalysisState(analyzerManager);
 }
            private static string GetBuildToolName(HostAnalyzerManager analyzerManager, string language, DiagnosticAnalyzer analyzer)
            {
                var packageName = analyzerManager.GetDiagnosticAnalyzerPackageName(language, analyzer);

                if (packageName == null)
                {
                    return(null);
                }

                if (packageName == RoslynLanguageServices)
                {
                    return(PredefinedBuildTools.Live);
                }

                return($"{analyzer.GetAnalyzerAssemblyName()} [{packageName}]");
            }
        public DiagnosticIncrementalAnalyzer(
            DiagnosticAnalyzerService owner,
            int correlationId,
            Workspace workspace,
            HostAnalyzerManager hostAnalyzerManager,
            AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
            : base(owner, workspace, hostAnalyzerManager, hostDiagnosticUpdateSource)
        {
            _correlationId = correlationId;

            _stateManager = new StateManager(hostAnalyzerManager);
            _stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;

            _executor           = new Executor(this);
            _compilationManager = new CompilationManager(this);
        }
Пример #15
0
                    public DiagnosticAnalyzerMap(HostAnalyzerManager analyzerManager, string language, ImmutableDictionary <DiagnosticAnalyzer, StateSet> analyzerMap)
                    {
                        // hold directly on to compiler analyzer
                        _compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);

                        // in test case, we might not have the compiler analyzer.
                        if (_compilerAnalyzer == null)
                        {
                            _map = analyzerMap;
                            return;
                        }

                        _compilerStateSet = analyzerMap[_compilerAnalyzer];

                        // hold rest of analyzers
                        _map = analyzerMap.Remove(_compilerAnalyzer);
                    }
                    public DiagnosticAnalyzerMap(HostAnalyzerManager analyzerManager, string language, ImmutableDictionary<DiagnosticAnalyzer, StateSet> analyzerMap)
                    {
                        // hold directly on to compiler analyzer
                        _compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);

                        // in test case, we might not have the compiler analyzer.
                        if (_compilerAnalyzer == null)
                        {
                            _map = analyzerMap;
                            return;
                        }

                        _compilerStateSet = analyzerMap[_compilerAnalyzer];

                        // hold rest of analyzers
                        _map = analyzerMap.Remove(_compilerAnalyzer);
                    }
Пример #17
0
                    public DiagnosticAnalyzerMap(HostAnalyzerManager analyzerManager, string language, ImmutableDictionary <DiagnosticAnalyzer, StateSet> analyzerMap)
                    {
                        _map = analyzerMap;

                        var compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);

                        // in test case, we might not have the compiler analyzer.
                        if (compilerAnalyzer != null)
                        {
                            // hold onto stateSet for compiler analyzer
                            _compilerStateSet = analyzerMap[compilerAnalyzer];
                        }

                        // order statesets
                        // order will be in this order
                        // BuiltIn Compiler Analyzer (C#/VB) < Regular DiagnosticAnalyzers < Document/ProjectDiagnosticAnalyzers
                        _orderedSet = _map.Values.OrderBy(PriorityComparison).ToImmutableArray();
                    }
        public override async Task SynchronizeWithBuildAsync(Document document, ImmutableArray <DiagnosticData> diagnostics)
        {
            var workspace = document.Project.Solution.Workspace;

            if (!PreferBuildErrors(workspace))
            {
                // prefer live errors over build errors
                return;
            }

            // check whether, for opened documents, we want to prefer live diagnostics
            if (PreferLiveErrorsOnOpenedFiles(workspace) && workspace.IsDocumentOpen(document.Id))
            {
                // enqueue re-analysis of open documents.
                this.Owner.Reanalyze(workspace, documentIds: SpecializedCollections.SingletonEnumerable(document.Id));
                return;
            }

            using (var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject())
            {
                var lookup = CreateDiagnosticIdLookup(diagnostics);

                foreach (var stateSet in _stateManager.GetStateSets(document.Project))
                {
                    // we are using Default so that things like LB can't use cached information
                    var textVersion     = VersionStamp.Default;
                    var semanticVersion = await document.Project.GetDependentSemanticVersionAsync(CancellationToken.None).ConfigureAwait(false);

                    // clear document and project live errors
                    await PersistAndReportAsync(stateSet, StateType.Project, document, textVersion, semanticVersion, ImmutableArray <DiagnosticData> .Empty).ConfigureAwait(false);
                    await PersistAndReportAsync(stateSet, StateType.Syntax, document, textVersion, semanticVersion, ImmutableArray <DiagnosticData> .Empty).ConfigureAwait(false);

                    var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                    var liveDiagnostics = ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object);

                    // REVIEW: for now, we are putting build error in document state rather than creating its own state.
                    //         reason is so that live error can take over it as soon as possible
                    //         this also means there can be slight race where it will clean up eventually. if live analysis runs for syntax but didn't run
                    //         for document yet, then we can have duplicated entries in the error list until live analysis catch.
                    await PersistAndReportAsync(stateSet, StateType.Document, document, textVersion, semanticVersion, liveDiagnostics).ConfigureAwait(false);
                }
            }
        }
Пример #19
0
        private async Task <ImmutableArray <DiagnosticData> > GetProjectDiagnosticsAsync(Project project, CancellationToken cancellationToken)
        {
            if (project == null)
            {
                return(ImmutableArray <DiagnosticData> .Empty);
            }

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

            var analyzers = HostAnalyzerManager.CreateDiagnosticAnalyzers(project);

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

            // REVIEW: this API is a bit strange.
            //         if getting diagnostic is cancelled, it has to create new compilation and do everything from scretch again?
            var dxs = GetDiagnosticData(project, await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false)).ToImmutableArrayOrEmpty();

            return(dxs);
        }
        private bool SupportAnalysisKind(DiagnosticAnalyzer analyzer, string language, AnalysisKind kind)
        {
            // compiler diagnostic analyzer always support all kinds
            if (HostAnalyzerManager.IsCompilerDiagnosticAnalyzer(language, analyzer))
            {
                return(true);
            }

            switch (kind)
            {
            case AnalysisKind.Syntax:
                return(analyzer.SupportsSyntaxDiagnosticAnalysis());

            case AnalysisKind.Semantic:
                return(analyzer.SupportsSemanticDiagnosticAnalysis());

            default:
                return(Contract.FailWithReturn <bool>("shouldn't reach here"));
            }
        }
        private ImmutableDictionary <DiagnosticAnalyzer, DiagnosticAnalysisResult> CreateAnalysisResults(
            Project project, ImmutableArray <StateSet> stateSets, ProjectAnalysisData oldAnalysisData, ImmutableArray <DiagnosticData> diagnostics)
        {
            using var poolObject = SharedPools.Default <HashSet <string> >().GetPooledObject();

            var lookup = diagnostics.ToLookup(d => d.Id);

            var builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, DiagnosticAnalysisResult>();

            foreach (var stateSet in stateSets)
            {
                var descriptors     = HostAnalyzerManager.GetDiagnosticDescriptors(stateSet.Analyzer);
                var liveDiagnostics = MergeDiagnostics(ConvertToLiveDiagnostics(lookup, descriptors, poolObject.Object), GetDiagnostics(oldAnalysisData.GetResult(stateSet.Analyzer)));

                var result = DiagnosticAnalysisResult.CreateFromBuild(project, liveDiagnostics);

                builder.Add(stateSet.Analyzer, result);
            }

            return(builder.ToImmutable());
        }
Пример #22
0
        public DiagnosticIncrementalAnalyzer(
            DiagnosticAnalyzerService owner,
            int correlationId,
            Workspace workspace,
            HostAnalyzerManager hostAnalyzerManager,
            AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
        {
            Contract.ThrowIfNull(owner);

            Owner                      = owner;
            Workspace                  = workspace;
            HostAnalyzerManager        = hostAnalyzerManager;
            HostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
            DiagnosticLogAggregator    = new DiagnosticLogAggregator(owner);

            _correlationId = correlationId;

            _stateManager = new StateManager(hostAnalyzerManager);
            _stateManager.ProjectAnalyzerReferenceChanged += OnProjectAnalyzerReferenceChanged;

            _executor           = new Executor(this);
            _compilationManager = new CompilationManager(this);
        }
        private bool IsCandidateForFullSolutionAnalysis(DiagnosticAnalyzer analyzer, Project project)
        {
            // PERF: Don't query descriptors for compiler analyzer, always execute it.
            if (HostAnalyzerManager.IsCompilerDiagnosticAnalyzer(project.Language, analyzer))
            {
                return(true);
            }

            if (analyzer.IsBuiltInAnalyzer())
            {
                // always return true for builtin analyzer. we can't use
                // descriptor check since many builtin analyzer always return
                // hidden descriptor regardless what descriptor it actually
                // return on runtime. they do this so that they can control
                // severity through option page rather than rule set editor.
                // this is special behavior only ide analyzer can do. we hope
                // once we support editorconfig fully, third party can use this
                // ability as well and we can remove this kind special treatment on builtin
                // analyzer.
                return(true);
            }

            return(Owner.HasNonHiddenDescriptor(analyzer, project));
        }
            private static string GetBuildToolName(HostAnalyzerManager analyzerManager, string language, DiagnosticAnalyzer analyzer)
            {
                var packageName = analyzerManager.GetDiagnosticAnalyzerPackageName(language, analyzer);
                if (packageName == null)
                {
                    return null;
                }

                if (packageName == RoslynLanguageServices)
                {
                    return PredefinedBuildTools.Live;
                }

                return $"{analyzer.GetAnalyzerAssemblyName()} [{packageName}]";
            }
            private static ImmutableDictionary<DiagnosticAnalyzer, StateSet> CreateAnalyzerMap(
                HostAnalyzerManager analyzerManager, string language, IEnumerable<ImmutableArray<DiagnosticAnalyzer>> analyzerCollection)
            {
                var compilerAnalyzer = analyzerManager.GetCompilerDiagnosticAnalyzer(language);

                var builder = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, StateSet>();
                foreach (var analyzers in analyzerCollection)
                {
                    foreach (var analyzer in analyzers)
                    {
                        // TODO: 
                        // #1, all de -duplication should move to HostAnalyzerManager
                        // #2, not sure whether de-duplication of analyzer itself makes sense. this can only happen
                        //     if user deliberately put same analyzer twice.
                        if (builder.ContainsKey(analyzer))
                        {
                            continue;
                        }

                        var buildToolName = analyzer == compilerAnalyzer ?
                            PredefinedBuildTools.Live : GetBuildToolName(analyzerManager, language, analyzer);

                        builder.Add(analyzer, new StateSet(language, analyzer, buildToolName));
                    }
                }

                return builder.ToImmutable();
            }
 public SolutionCrawlerAnalysisState(HostAnalyzerManager hostAnalyzerManager)
 {
     _projectAnalysisStateCache = new ConditionalWeakTable <Project, ProjectAnalysisState>();
     _hostAnalyzerManager       = hostAnalyzerManager;
     _lastCacheCleanupTime      = DateTime.UtcNow;
 }
 public DiagnosticIncrementalAnalyzer(DiagnosticAnalyzerService owner, int correlationId, Workspace workspace, HostAnalyzerManager hostAnalyzerManager, AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource)
     : base(owner, workspace, hostAnalyzerManager, hostDiagnosticUpdateSource)
 {
     _correlationId = correlationId;
 }
            private static string GetErrorSourceName(HostAnalyzerManager analyzerManager, string language, DiagnosticAnalyzer analyzer)
            {
                var packageName = analyzerManager.GetDiagnosticAnalyzerPackageName(language, analyzer);
                if (packageName == null)
                {
                    return null;
                }

                return $"{analyzer.GetAnalyzerAssemblyName()} [{packageName}]";
            }
 public SolutionCrawlerAnalysisState(HostAnalyzerManager hostAnalyzerManager)
 {
     _projectAnalysisStateCache = new ConditionalWeakTable<Project, ProjectAnalysisState>();
     _hostAnalyzerManager = hostAnalyzerManager;
     _lastCacheCleanupTime = DateTime.UtcNow;
 }