diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AdditionalTextValueProvider.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AdditionalTextValueProvider.cs new file mode 100644 index 0000000000000..9fa4275c10bee --- /dev/null +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AdditionalTextValueProvider.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; + +namespace Microsoft.CodeAnalysis.Diagnostics +{ + /// + /// Provides custom values associated with instances using the given computeValue delegate. + /// + public sealed class AdditionalTextValueProvider + { + internal readonly AnalysisValueProvider CoreValueProvider; + + /// + /// Provides custom values associated with instances using the given . + /// + /// Delegate to compute the value associated with a given instance. + /// Optional equality comparer to determine equivalent instances that have the same value. + /// If no comparer is provided, then is used by default. + public AdditionalTextValueProvider(Func computeValue, IEqualityComparer? additionalTextComparer = null) + { + CoreValueProvider = new AnalysisValueProvider(computeValue, additionalTextComparer ?? EqualityComparer.Default); + } + } +} diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticAnalysisContext.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticAnalysisContext.cs index 2379863ff2f38..3fc8b712b033f 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticAnalysisContext.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DiagnosticAnalysisContext.cs @@ -236,6 +236,21 @@ public bool TryGetValue(SourceText text, SourceTextValueProvider return TryGetValue(text, valueProvider.CoreValueProvider, out value); } + /// + /// Attempts to compute or get the cached value provided by the given for the given . + /// Note that the pair {, } acts as the key. + /// Reusing the same instance across analyzer actions and/or analyzer instances can improve the overall analyzer performance by avoiding recomputation of the values. + /// + /// The type of the value associated with the key. + /// for which the value is queried. + /// Provider that computes the underlying value. + /// Value associated with the key. + /// Returns true on success, false otherwise. + public bool TryGetValue(AdditionalText text, AdditionalTextValueProvider valueProvider, [MaybeNullWhen(false)] out TValue value) + { + return TryGetValue(text, valueProvider.CoreValueProvider, out value); + } + private bool TryGetValue(TKey key, AnalysisValueProvider valueProvider, [MaybeNullWhen(false)] out TValue value) where TKey : class { @@ -485,6 +500,21 @@ public bool TryGetValue(SourceText text, SourceTextValueProvider return TryGetValue(text, valueProvider.CoreValueProvider, out value); } + /// + /// Attempts to compute or get the cached value provided by the given for the given . + /// Note that the pair {, } acts as the key. + /// Reusing the same instance across analyzer actions and/or analyzer instances can improve the overall analyzer performance by avoiding recomputation of the values. + /// + /// The type of the value associated with the key. + /// instance for which the value is queried. + /// Provider that computes the underlying value. + /// Value associated with the key. + /// Returns true on success, false otherwise. + public bool TryGetValue(AdditionalText text, AdditionalTextValueProvider valueProvider, [MaybeNullWhen(false)] out TValue value) + { + return TryGetValue(text, valueProvider.CoreValueProvider, out value); + } + /// /// Attempts to compute or get the cached value provided by the given for the given . /// Note that the pair {, } acts as the key. @@ -592,6 +622,21 @@ public bool TryGetValue(SourceText text, SourceTextValueProvider return TryGetValue(text, valueProvider.CoreValueProvider, out value); } + /// + /// Attempts to compute or get the cached value provided by the given for the given . + /// Note that the pair {, } acts as the key. + /// Reusing the same instance across analyzer actions and/or analyzer instances can improve the overall analyzer performance by avoiding recomputation of the values. + /// + /// The type of the value associated with the key. + /// for which the value is queried. + /// Provider that computes the underlying value. + /// Value associated with the key. + /// Returns true on success, false otherwise. + public bool TryGetValue(AdditionalText text, AdditionalTextValueProvider valueProvider, [MaybeNullWhen(false)] out TValue value) + { + return TryGetValue(text, valueProvider.CoreValueProvider, out value); + } + /// /// Attempts to compute or get the cached value provided by the given for the given . /// Note that the pair {, } acts as the key. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index f0fd12c283200..2ba3e6706113f 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -1,6 +1,11 @@ *REMOVED*static Microsoft.CodeAnalysis.SeparatedSyntaxList.implicit operator Microsoft.CodeAnalysis.SeparatedSyntaxList(Microsoft.CodeAnalysis.SeparatedSyntaxList nodes) -> Microsoft.CodeAnalysis.SeparatedSyntaxList *REMOVED*static Microsoft.CodeAnalysis.SyntaxList.implicit operator Microsoft.CodeAnalysis.SyntaxList(Microsoft.CodeAnalysis.SyntaxList nodes) -> Microsoft.CodeAnalysis.SyntaxList Microsoft.CodeAnalysis.Compilation.SupportsRuntimeCapability(Microsoft.CodeAnalysis.RuntimeCapability capability) -> bool +Microsoft.CodeAnalysis.Diagnostics.AdditionalTextValueProvider +Microsoft.CodeAnalysis.Diagnostics.AdditionalTextValueProvider.AdditionalTextValueProvider(System.Func! computeValue, System.Collections.Generic.IEqualityComparer? additionalTextComparer = null) -> void +Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.TryGetValue(Microsoft.CodeAnalysis.AdditionalText! text, Microsoft.CodeAnalysis.Diagnostics.AdditionalTextValueProvider! valueProvider, out TValue value) -> bool +Microsoft.CodeAnalysis.Diagnostics.CompilationAnalysisContext.TryGetValue(Microsoft.CodeAnalysis.AdditionalText! text, Microsoft.CodeAnalysis.Diagnostics.AdditionalTextValueProvider! valueProvider, out TValue value) -> bool +Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.TryGetValue(Microsoft.CodeAnalysis.AdditionalText! text, Microsoft.CodeAnalysis.Diagnostics.AdditionalTextValueProvider! valueProvider, out TValue value) -> bool Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(Microsoft.CodeAnalysis.SyntaxTree! tree, Microsoft.CodeAnalysis.Text.TextSpan? filterSpan, System.Collections.Immutable.ImmutableArray analyzers, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(Microsoft.CodeAnalysis.SyntaxTree! tree, Microsoft.CodeAnalysis.Text.TextSpan? filterSpan, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(Microsoft.CodeAnalysis.SyntaxTree! tree, Microsoft.CodeAnalysis.Text.TextSpan? filterSpan, System.Collections.Immutable.ImmutableArray analyzers, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task>!