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>!