Пример #1
0
        private ImmutableArray <Diagnostic> GetDiagnostics_NoLock(AnalysisScope analysisScope, bool getLocalDiagnostics, bool getNonLocalDiagnostics)
        {
            Debug.Assert(getLocalDiagnostics || getNonLocalDiagnostics);

            var builder = ImmutableArray.CreateBuilder <Diagnostic>();

            if (getLocalDiagnostics)
            {
                if (!analysisScope.IsTreeAnalysis)
                {
                    AddAllLocalDiagnostics_NoLock(_localSyntaxDiagnosticsOpt, analysisScope, builder);
                    AddAllLocalDiagnostics_NoLock(_localSemanticDiagnosticsOpt, analysisScope, builder);
                }
                else if (analysisScope.IsSyntaxOnlyTreeAnalysis)
                {
                    AddLocalDiagnosticsForPartialAnalysis_NoLock(_localSyntaxDiagnosticsOpt, analysisScope, builder);
                }
                else
                {
                    AddLocalDiagnosticsForPartialAnalysis_NoLock(_localSemanticDiagnosticsOpt, analysisScope, builder);
                }
            }

            if (getNonLocalDiagnostics && _nonLocalDiagnosticsOpt != null)
            {
                AddDiagnostics_NoLock(_nonLocalDiagnosticsOpt, analysisScope, builder);
            }

            return(builder.ToImmutableArray());
        }
Пример #2
0
 internal ImmutableArray <Diagnostic> GetDiagnostics(AnalysisScope analysisScope, bool getLocalDiagnostics, bool getNonLocalDiagnostics)
 {
     lock (_gate)
     {
         return(GetDiagnostics_NoLock(analysisScope, getLocalDiagnostics, getNonLocalDiagnostics));
     }
 }
            public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
            {
                lock (_gate)
                {
                    var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent;
                    if (symbolEvent != null)
                    {
                        var needsAnalysis      = false;
                        var symbol             = symbolEvent.Symbol;
                        var skipSymbolAnalysis = AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent);
                        if (!skipSymbolAnalysis && actionCounts.SymbolActionsCount > 0)
                        {
                            needsAnalysis           = true;
                            _pendingSymbols[symbol] = null;
                        }

                        var skipDeclarationAnalysis = AnalysisScope.ShouldSkipDeclarationAnalysis(symbol);
                        if (!skipDeclarationAnalysis &&
                            actionCounts.HasAnyExecutableCodeActions)
                        {
                            needsAnalysis = true;
                            _pendingDeclarations[symbol] = _currentlyAnalyzingDeclarationsMapPool.Allocate();
                        }

                        if (actionCounts.SymbolStartActionsCount > 0 && (!skipSymbolAnalysis || !skipDeclarationAnalysis))
                        {
                            needsAnalysis = true;
                            _lazyPendingSymbolEndAnalyses         = _lazyPendingSymbolEndAnalyses ?? new Dictionary <ISymbol, AnalyzerStateData>();
                            _lazyPendingSymbolEndAnalyses[symbol] = null;
                        }

                        if (!needsAnalysis)
                        {
                            return;
                        }
                    }
                    else if (compilationEvent is CompilationStartedEvent)
                    {
                        if (actionCounts.SyntaxTreeActionsCount > 0)
                        {
                            _lazySyntaxTreesWithAnalysisData = new Dictionary <SyntaxTree, AnalyzerStateData>();
                            _pendingSyntaxAnalysisTreesCount = compilationEvent.Compilation.SyntaxTrees.Count();
                        }

                        if (actionCounts.CompilationActionsCount == 0)
                        {
                            return;
                        }
                    }

                    _pendingEvents[compilationEvent] = null;
                }
            }
Пример #4
0
        private static void AddLocalDiagnosticsForPartialAnalysis_NoLock(
            Dictionary <SyntaxTree, Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> > localDiagnostics,
            AnalysisScope analysisScope,
            ImmutableArray <Diagnostic> .Builder builder)
        {
            Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> diagnosticsForTree;

            if (localDiagnostics != null && localDiagnostics.TryGetValue(analysisScope.FilterTreeOpt, out diagnosticsForTree))
            {
                AddDiagnostics_NoLock(diagnosticsForTree, analysisScope, builder);
            }
        }
Пример #5
0
 private static void AddAllLocalDiagnostics_NoLock(
     Dictionary <SyntaxTree, Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> > localDiagnostics,
     AnalysisScope analysisScope,
     ImmutableArray <Diagnostic> .Builder builder)
 {
     if (localDiagnostics != null)
     {
         foreach (var localDiagsByTree in localDiagnostics.Values)
         {
             AddDiagnostics_NoLock(localDiagsByTree, analysisScope, builder);
         }
     }
 }
            public bool ShouldExecuteOperationActions(AnalysisScope analysisScope)
            {
                if (!this.OperationActionsByAnalyzerAndKind.IsEmpty)
                {
                    foreach (var analyzer in analysisScope.Analyzers)
                    {
                        if (this.OperationActionsByAnalyzerAndKind.ContainsKey(analyzer))
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            }
Пример #7
0
        private static void AddDiagnostics_NoLock(
            Dictionary <DiagnosticAnalyzer, ImmutableArray <Diagnostic> .Builder> diagnostics,
            AnalysisScope analysisScope,
            ImmutableArray <Diagnostic> .Builder builder)
        {
            Debug.Assert(diagnostics != null);

            foreach (var analyzer in analysisScope.Analyzers)
            {
                ImmutableArray <Diagnostic> .Builder diagnosticsByAnalyzer;
                if (diagnostics.TryGetValue(analyzer, out diagnosticsByAnalyzer))
                {
                    builder.AddRange(diagnosticsByAnalyzer);
                }
            }
        }
Пример #8
0
        internal void StoreAnalysisResult(AnalysisScope analysisScope, AnalyzerDriver driver, Compilation compilation, Func <DiagnosticAnalyzer, AnalyzerActionCounts> getAnalyzerActionCounts, bool fullAnalysisResultForAnalyzersInScope)
        {
            Debug.Assert(!fullAnalysisResultForAnalyzersInScope || analysisScope.FilterTreeOpt == null, "Full analysis result cannot come from partial (tree) analysis.");

            foreach (var analyzer in analysisScope.Analyzers)
            {
                // Dequeue reported analyzer diagnostics from the driver and store them in our maps.
                var syntaxDiagnostics      = driver.DequeueLocalDiagnostics(analyzer, syntax: true, compilation: compilation);
                var semanticDiagnostics    = driver.DequeueLocalDiagnostics(analyzer, syntax: false, compilation: compilation);
                var compilationDiagnostics = driver.DequeueNonLocalDiagnostics(analyzer, compilation);

                lock (_gate)
                {
                    if (_completedAnalyzers.Contains(analyzer))
                    {
                        // Already stored full analysis result for this analyzer.
                        continue;
                    }

                    if (syntaxDiagnostics.Length > 0 || semanticDiagnostics.Length > 0 || compilationDiagnostics.Length > 0 || fullAnalysisResultForAnalyzersInScope)
                    {
                        UpdateLocalDiagnostics_NoLock(analyzer, syntaxDiagnostics, fullAnalysisResultForAnalyzersInScope, ref _localSyntaxDiagnosticsOpt);
                        UpdateLocalDiagnostics_NoLock(analyzer, semanticDiagnostics, fullAnalysisResultForAnalyzersInScope, ref _localSemanticDiagnosticsOpt);
                        UpdateNonLocalDiagnostics_NoLock(analyzer, compilationDiagnostics, fullAnalysisResultForAnalyzersInScope);
                    }

                    if (_analyzerExecutionTimeOpt != null)
                    {
                        var timeSpan = driver.ResetAnalyzerExecutionTime(analyzer);
                        _analyzerExecutionTimeOpt[analyzer] = fullAnalysisResultForAnalyzersInScope ?
                                                              timeSpan :
                                                              _analyzerExecutionTimeOpt[analyzer] + timeSpan;
                    }

                    if (!_analyzerActionCounts.ContainsKey(analyzer))
                    {
                        _analyzerActionCounts.Add(analyzer, getAnalyzerActionCounts(analyzer));
                    }

                    if (fullAnalysisResultForAnalyzersInScope)
                    {
                        _completedAnalyzers.Add(analyzer);
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Returns true if we have any pending syntax analysis for given analysis scope.
        /// </summary>
        public bool HasPendingSyntaxAnalysis(AnalysisScope analysisScope)
        {
            if (analysisScope.IsTreeAnalysis && !analysisScope.IsSyntaxOnlyTreeAnalysis)
            {
                return(false);
            }

            foreach (var analyzer in analysisScope.Analyzers)
            {
                var analyzerState = GetAnalyzerState(analyzer);
                if (analyzerState.HasPendingSyntaxAnalysis(analysisScope.FilterTreeOpt))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #10
0
        /// <summary>
        /// Returns true if we have any pending symbol analysis for given analysis scope.
        /// </summary>
        public bool HasPendingSymbolAnalysis(AnalysisScope analysisScope, CancellationToken cancellationToken)
        {
            Debug.Assert(analysisScope.FilterTreeOpt != null);

            var symbolDeclaredEvents = GetPendingSymbolDeclaredEvents(analysisScope.FilterTreeOpt, cancellationToken);

            foreach (var symbolDeclaredEvent in symbolDeclaredEvents)
            {
                if (analysisScope.ShouldAnalyze(symbolDeclaredEvent.Symbol))
                {
                    foreach (var analyzer in analysisScope.Analyzers)
                    {
                        var analyzerState = GetAnalyzerState(analyzer);
                        if (analyzerState.HasPendingSymbolAnalysis(symbolDeclaredEvent.Symbol))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Пример #11
0
        public async Task GenerateSimulatedCompilationEventsAsync(
            AnalysisScope analysisScope,
            Compilation compilation,
            Func <SyntaxTree, Compilation, CancellationToken, SemanticModel> getCachedSemanticModel,
            AnalyzerDriver driver,
            CancellationToken cancellationToken)
        {
            await EnsureAnalyzerActionCountsInitializedAsync(driver, cancellationToken).ConfigureAwait(false);

            // Compilation started event.
            GenerateSimulatedCompilationNonSourceEvent(compilation, driver, started: true, cancellationToken: cancellationToken);

            // Symbol declared and compilation unit completed events.
            foreach (var tree in analysisScope.SyntaxTrees)
            {
                GenerateSimulatedCompilationSourceEvents(tree, compilation, getCachedSemanticModel, driver, cancellationToken);
            }

            // Compilation ended event.
            if (analysisScope.FilterTreeOpt == null)
            {
                GenerateSimulatedCompilationNonSourceEvent(compilation, driver, started: false, cancellationToken: cancellationToken);
            }
        }
            public IEnumerable <CodeBlockAnalyzerActions> GetCodeBlockActions(AnalysisScope analysisScope)
            {
                if (_analyzerActions.IsEmpty)
                {
                    yield break;
                }

                foreach (var analyzer in analysisScope.Analyzers)
                {
                    ImmutableArray <CodeBlockStartAnalyzerAction <TLanguageKindEnum> > codeBlockStartActions;
                    if (!this.CodeBlockStartActionsByAnalyzer.TryGetValue(analyzer, out codeBlockStartActions))
                    {
                        codeBlockStartActions = ImmutableArray <CodeBlockStartAnalyzerAction <TLanguageKindEnum> > .Empty;
                    }

                    ImmutableArray <CodeBlockAnalyzerAction> codeBlockActions;
                    if (!this.CodeBlockActionsByAnalyzer.TryGetValue(analyzer, out codeBlockActions))
                    {
                        codeBlockActions = ImmutableArray <CodeBlockAnalyzerAction> .Empty;
                    }

                    ImmutableArray <CodeBlockAnalyzerAction> codeBlockEndActions;
                    if (!this.CodeBlockEndActionsByAnalyzer.TryGetValue(analyzer, out codeBlockEndActions))
                    {
                        codeBlockEndActions = ImmutableArray <CodeBlockAnalyzerAction> .Empty;
                    }

                    ImmutableArray <OperationBlockStartAnalyzerAction> operationBlockStartActions;
                    if (!this.OperationBlockStartActionsByAnalyzer.TryGetValue(analyzer, out operationBlockStartActions))
                    {
                        operationBlockStartActions = ImmutableArray <OperationBlockStartAnalyzerAction> .Empty;
                    }

                    ImmutableArray <OperationBlockAnalyzerAction> operationBlockActions;
                    if (!this.OperationBlockActionsByAnalyzer.TryGetValue(analyzer, out operationBlockActions))
                    {
                        operationBlockActions = ImmutableArray <OperationBlockAnalyzerAction> .Empty;
                    }

                    ImmutableArray <OperationBlockAnalyzerAction> operationBlockEndActions;
                    if (!this.OperationBlockEndActionsByAnalyzer.TryGetValue(analyzer, out operationBlockEndActions))
                    {
                        operationBlockEndActions = ImmutableArray <OperationBlockAnalyzerAction> .Empty;
                    }

                    if (!codeBlockStartActions.IsEmpty || !codeBlockActions.IsEmpty || !codeBlockEndActions.IsEmpty || !operationBlockStartActions.IsEmpty || !operationBlockActions.IsEmpty || !operationBlockEndActions.IsEmpty)
                    {
                        yield return
                            (new CodeBlockAnalyzerActions
                        {
                            Analyzer = analyzer,
                            CodeBlockStartActions = codeBlockStartActions,
                            CodeBlockActions = codeBlockActions,
                            CodeBlockEndActions = codeBlockEndActions,
                            OperationBlockStartActions = operationBlockStartActions,
                            OperationBlockActions = operationBlockActions,
                            OperationBlockEndActions = operationBlockEndActions
                        });
                    }
                }
            }
 public bool ShouldExecuteOperationBlockActions(AnalysisScope analysisScope, ISymbol symbol)
 {
     return(ShouldExecuteBlockActions(this.OperationBlockStartActionsByAnalyzer, this.OperationBlockActionsByAnalyzer, analysisScope, symbol));
 }
            public bool ShouldExecuteBlockActions <T0, T1>(ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <T0> > blockStartActions, ImmutableDictionary <DiagnosticAnalyzer, ImmutableArray <T1> > blockActions, AnalysisScope analysisScope, ISymbol symbol)
            {
                if ((!blockStartActions.IsEmpty || !blockActions.IsEmpty) &&
                    AnalyzerExecutor.CanHaveExecutableCodeBlock(symbol))
                {
                    foreach (var analyzer in analysisScope.Analyzers)
                    {
                        if (blockStartActions.ContainsKey(analyzer) ||
                            blockActions.ContainsKey(analyzer))
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            }