From af178ee2e1d20558557288fa62862c023770e433 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 28 Nov 2017 12:58:56 -0800 Subject: [PATCH] Reduce Location allocations while running analyzers. --- .../DiagnosticAnalyzer/AnalyzerDriver.cs | 20 +++++++++---------- .../DiagnosticAnalyzer/AnalyzerExecutor.cs | 14 +++++++------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs index a748d69fe21..8e0158c3946 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerDriver.cs @@ -8,9 +8,10 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Diagnostics.Telemetry; +using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics @@ -613,7 +614,7 @@ private bool IsInGeneratedCode(Location location, Compilation compilation, Cance } // Check if this is a generated code location. - if (IsGeneratedOrHiddenCodeLocation(location)) + if (IsGeneratedOrHiddenCodeLocation(location.SourceTree, location.SourceSpan)) { return true; } @@ -1275,7 +1276,7 @@ private bool IsGeneratedCodeSymbol(ISymbol symbol) foreach (var declaringRef in symbol.DeclaringSyntaxReferences) { - if (!IsGeneratedOrHiddenCodeLocation(declaringRef.GetLocation())) + if (!IsGeneratedOrHiddenCodeLocation(declaringRef.SyntaxTree, declaringRef.Span)) { return false; } @@ -1309,13 +1310,12 @@ protected bool IsGeneratedCode(SyntaxTree tree) protected bool DoNotAnalyzeGeneratedCode => _doNotAnalyzeGeneratedCode; // Location is in generated code if either the containing tree is a generated code file OR if it is a hidden source location. - protected bool IsGeneratedOrHiddenCodeLocation(Location location) => - IsGeneratedCode(location.SourceTree) || IsHiddenSourceLocation(location); + protected bool IsGeneratedOrHiddenCodeLocation(SyntaxTree syntaxTree, TextSpan span) + => IsGeneratedCode(syntaxTree) || IsHiddenSourceLocation(syntaxTree, span); - protected bool IsHiddenSourceLocation(Location location) => - location.IsInSource && - HasHiddenRegions(location.SourceTree) && - location.SourceTree.IsHiddenPosition(location.SourceSpan.Start); + protected bool IsHiddenSourceLocation(SyntaxTree syntaxTree, TextSpan span) + => HasHiddenRegions(syntaxTree) && + syntaxTree.IsHiddenPosition(span.Start); private bool HasHiddenRegions(SyntaxTree tree) { @@ -1630,7 +1630,7 @@ private bool ShouldExecuteOperationBlockActions(AnalysisScope analysisScope, ISy continue; } - var isInGeneratedCode = isGeneratedCodeSymbol || IsGeneratedOrHiddenCodeLocation(decl.GetLocation()); + var isInGeneratedCode = isGeneratedCodeSymbol || IsGeneratedOrHiddenCodeLocation(decl.SyntaxTree, decl.Span); if (isInGeneratedCode && DoNotAnalyzeGeneratedCode) { analysisStateOpt?.MarkDeclarationComplete(symbol, i, analysisScope.Analyzers); diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs index 5aadc103919..9ac20ffb5f9 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerExecutor.cs @@ -42,7 +42,7 @@ internal class AnalyzerExecutor private readonly Func _getAnalyzerGateOpt; private readonly Func _shouldSkipAnalysisOnGeneratedCode; private readonly Func _shouldSuppressGeneratedCodeDiagnostic; - private readonly Func _isGeneratedCodeLocation; + private readonly Func _isGeneratedCodeLocation; private readonly ConcurrentDictionary _analyzerExecutionTimeMapOpt; private readonly CompilationAnalysisValueProviderFactory _compilationAnalysisValueProviderFactory; private readonly CancellationToken _cancellationToken; @@ -86,7 +86,7 @@ internal class AnalyzerExecutor AnalyzerManager analyzerManager, Func shouldSkipAnalysisOnGeneratedCode, Func shouldSuppressGeneratedCodeDiagnostic, - Func isGeneratedCodeLocation, + Func isGeneratedCodeLocation, Func getAnalyzerGate, bool logExecutionTime = false, Action addCategorizedLocalDiagnosticOpt = null, @@ -125,7 +125,7 @@ internal class AnalyzerExecutor isCompilerAnalyzer: null, shouldSkipAnalysisOnGeneratedCode: _ => false, shouldSuppressGeneratedCodeDiagnostic: (diagnostic, analyzer, compilation, ct) => false, - isGeneratedCodeLocation: _ => false, + isGeneratedCodeLocation: (_1, _2) => false, getAnalyzerGateOpt: null, onAnalyzerException: onAnalyzerException, analyzerExceptionFilter: null, @@ -146,7 +146,7 @@ internal class AnalyzerExecutor AnalyzerManager analyzerManager, Func shouldSkipAnalysisOnGeneratedCode, Func shouldSuppressGeneratedCodeDiagnostic, - Func isGeneratedCodeLocation, + Func isGeneratedCodeLocation, Func getAnalyzerGateOpt, ConcurrentDictionary analyzerExecutionTimeMapOpt, Action addCategorizedLocalDiagnosticOpt, @@ -1488,7 +1488,8 @@ private bool ShouldExecuteNode(SyntaxNodeAnalyzerStateData analyzerStateOpt, Syn } // Check if the node is generated code that must be skipped. - if (_shouldSkipAnalysisOnGeneratedCode(analyzer) && _isGeneratedCodeLocation(node.GetLocation())) + if (_shouldSkipAnalysisOnGeneratedCode(analyzer) && + _isGeneratedCodeLocation(node.SyntaxTree, node.Span)) { return false; } @@ -1505,7 +1506,8 @@ private bool ShouldExecuteOperation(OperationAnalyzerStateData analyzerStateOpt, } // Check if the operation syntax is generated code that must be skipped. - if (operation.Syntax != null && _shouldSkipAnalysisOnGeneratedCode(analyzer) && _isGeneratedCodeLocation(operation.Syntax.GetLocation())) + if (operation.Syntax != null && _shouldSkipAnalysisOnGeneratedCode(analyzer) && + _isGeneratedCodeLocation(operation.Syntax.SyntaxTree, operation.Syntax.Span)) { return false; } -- GitLab