Beispiel #1
0
        private void OnCompilationEventsGenerated_NoLock(ImmutableArray <CompilationEvent> compilationEvents, SyntaxTree filterTreeOpt, AnalyzerDriver driver, CancellationToken cancellationToken)
        {
            Debug.Assert(_lazyAnalyzerActionCountsMap != null);

            // Add the events to our global pending events map.
            AddToEventsMap_NoLock(compilationEvents, filterTreeOpt);

            // Mark the events for analysis for each analyzer.
            ArrayBuilder <ISymbol> newPartialSymbols = null;

            Debug.Assert(_pooledEventsWithAnyActionsSet.Count == 0);
            foreach (KeyValuePair <DiagnosticAnalyzer, int> kvp in _analyzerStateMap)
            {
                DiagnosticAnalyzer   analyzer      = kvp.Key;
                PerAnalyzerState     analyzerState = _analyzerStates[kvp.Value];
                AnalyzerActionCounts actionCounts  = _lazyAnalyzerActionCountsMap[analyzer];

                foreach (CompilationEvent compilationEvent in compilationEvents)
                {
                    if (HasActionsForEvent(compilationEvent, actionCounts))
                    {
                        _pooledEventsWithAnyActionsSet.Add(compilationEvent);

                        SymbolDeclaredCompilationEvent symbolDeclaredEvent = compilationEvent as SymbolDeclaredCompilationEvent;
                        if (symbolDeclaredEvent?.DeclaringSyntaxReferences.Length > 1)
                        {
                            if (_partialSymbolsWithGeneratedSourceEvents.Contains(symbolDeclaredEvent.Symbol))
                            {
                                // already processed.
                                continue;
                            }
                            else
                            {
                                newPartialSymbols = newPartialSymbols ?? ArrayBuilder <ISymbol> .GetInstance();

                                newPartialSymbols.Add(symbolDeclaredEvent.Symbol);
                            }
                        }

                        analyzerState.OnCompilationEventGenerated(compilationEvent, actionCounts);
                    }
                }
            }

            foreach (CompilationEvent compilationEvent in compilationEvents)
            {
                if (!_pooledEventsWithAnyActionsSet.Remove(compilationEvent))
                {
                    // Event has no relevant actions to execute, so mark it as complete.
                    UpdateEventsMap_NoLock(compilationEvent, add: false);
                }
            }

            if (newPartialSymbols != null)
            {
                _partialSymbolsWithGeneratedSourceEvents.AddAll(newPartialSymbols);
                newPartialSymbols.Free();
            }
        }
Beispiel #2
0
 private static bool HasActionsForEvent(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
 {
     return(compilationEvent switch
     {
         CompilationStartedEvent => actionCounts.CompilationActionsCount > 0 || actionCounts.SyntaxTreeActionsCount > 0 || actionCounts.AdditionalFileActionsCount > 0,
         CompilationCompletedEvent => actionCounts.CompilationEndActionsCount > 0,
         SymbolDeclaredCompilationEvent => actionCounts.SymbolActionsCount > 0 || actionCounts.HasAnyExecutableCodeActions,
         _ => actionCounts.SemanticModelActionsCount > 0
     });
Beispiel #3
0
        private async Task EnsureAnalyzerActionCountsInitializedAsync(AnalyzerDriver driver, CancellationToken cancellationToken)
        {
            if (_lazyAnalyzerActionCountsMap == null)
            {
                ImmutableDictionary <DiagnosticAnalyzer, AnalyzerActionCounts> .Builder builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, AnalyzerActionCounts>();
                foreach (DiagnosticAnalyzer analyzer in _analyzerStateMap.Keys)
                {
                    AnalyzerActionCounts actionCounts = await driver.GetAnalyzerActionCountsAsync(analyzer, _compilationOptions, cancellationToken).ConfigureAwait(false);

                    builder.Add(analyzer, actionCounts);
                }

                Interlocked.CompareExchange(ref _lazyAnalyzerActionCountsMap, builder.ToImmutable(), null);
            }
        }
Beispiel #4
0
        private ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> GetTelemetryInfo(
            ImmutableArray <DiagnosticAnalyzer> analyzers,
            CancellationToken cancellationToken)
        {
            ImmutableDictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> .Builder builder = ImmutableDictionary.CreateBuilder <DiagnosticAnalyzer, AnalyzerTelemetryInfo>();

            lock (_gate)
            {
                foreach (DiagnosticAnalyzer analyzer in analyzers)
                {
                    AnalyzerActionCounts  actionCounts  = _analyzerActionCounts[analyzer];
                    TimeSpan              executionTime = _analyzerExecutionTimeOpt != null ? _analyzerExecutionTimeOpt[analyzer] : default(TimeSpan);
                    AnalyzerTelemetryInfo telemetryInfo = new AnalyzerTelemetryInfo(actionCounts, executionTime);
                    builder.Add(analyzer, telemetryInfo);
                }
            }

            return(builder.ToImmutable());
        }
Beispiel #5
0
 private static bool HasActionsForEvent(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
 {
     if (compilationEvent is CompilationStartedEvent)
     {
         return(actionCounts.CompilationActionsCount > 0 ||
                actionCounts.SyntaxTreeActionsCount > 0);
     }
     else if (compilationEvent is CompilationCompletedEvent)
     {
         return(actionCounts.CompilationEndActionsCount > 0);
     }
     else if (compilationEvent is SymbolDeclaredCompilationEvent)
     {
         return(actionCounts.SymbolActionsCount > 0 || actionCounts.HasAnyExecutableCodeActions);
     }
     else
     {
         return(actionCounts.SemanticModelActionsCount > 0);
     }
 }
            public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
            {
                lock (_gate)
                {
                    var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent;
                    if (symbolEvent != null)
                    {
                        var needsAnalysis = false;
                        var symbol        = symbolEvent.Symbol;
                        if (!AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent) && actionCounts.SymbolActionsCount > 0)
                        {
                            needsAnalysis           = true;
                            _pendingSymbols[symbol] = null;
                        }

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

                        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;
                }
            }
Beispiel #7
0
            public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
            {
                lock (_gate)
                {
                    if (compilationEvent is SymbolDeclaredCompilationEvent symbolEvent)
                    {
                        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] = null;
                        }

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

                        if (!needsAnalysis)
                        {
                            return;
                        }
                    }
                    else if (compilationEvent is CompilationStartedEvent compilationStartedEvent)
                    {
                        var fileCount = actionCounts.SyntaxTreeActionsCount > 0 ? compilationEvent.Compilation.SyntaxTrees.Count() : 0;
                        fileCount += actionCounts.AdditionalFileActionsCount > 0 ? compilationStartedEvent.AdditionalFiles.Length : 0;
                        if (fileCount > 0)
                        {
                            _lazyFilesWithAnalysisData       = new Dictionary <SourceOrAdditionalFile, AnalyzerStateData>();
                            _pendingSyntaxAnalysisFilesCount = fileCount;
                        }

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

                    _pendingEvents[compilationEvent] = null;
                }
            }
            public void OnCompilationEventGenerated(CompilationEvent compilationEvent, AnalyzerActionCounts actionCounts)
            {
                lock (_gate)
                {
                    var symbolEvent = compilationEvent as SymbolDeclaredCompilationEvent;
                    if (symbolEvent != null)
                    {
                        var needsAnalysis = false;
                        var symbol        = symbolEvent.Symbol;
                        if (!AnalysisScope.ShouldSkipSymbolAnalysis(symbolEvent) && actionCounts.SymbolActionsCount > 0)
                        {
                            needsAnalysis           = true;
                            _pendingSymbols[symbol] = null;
                        }

                        if (!AnalysisScope.ShouldSkipDeclarationAnalysis(symbol) &&
                            (actionCounts.SyntaxNodeActionsCount > 0 ||
                             actionCounts.CodeBlockActionsCount > 0 ||
                             actionCounts.CodeBlockStartActionsCount > 0))
                        {
                            foreach (var syntaxRef in symbolEvent.DeclaringSyntaxReferences)
                            {
                                needsAnalysis = true;
                                _pendingDeclarations[syntaxRef.GetSyntax()] = null;
                            }
                        }

                        if (!needsAnalysis)
                        {
                            return;
                        }
                    }
                    else if (compilationEvent is CompilationStartedEvent)
                    {
                        if (actionCounts.SyntaxTreeActionsCount > 0)
                        {
                            var trees = compilationEvent.Compilation.SyntaxTrees;
                            var map   = new Dictionary <SyntaxTree, AnalyzerStateData>(trees.Count());
                            foreach (var tree in trees)
                            {
                                map[tree] = null;
                            }

                            _lazyPendingSyntaxAnalysisTrees = map;
                        }

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

                    _pendingEvents[compilationEvent] = null;
                }
            }