diff --git a/src/EditorFeatures/Test2/InlineHints/AbstractInlineHintsTests.vb b/src/EditorFeatures/Test2/InlineHints/AbstractInlineHintsTests.vb index 65b0fff2670fb..66bc299f1985d 100644 --- a/src/EditorFeatures/Test2/InlineHints/AbstractInlineHintsTests.vb +++ b/src/EditorFeatures/Test2/InlineHints/AbstractInlineHintsTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis.InlineHints Imports Microsoft.CodeAnalysis.LanguageService +Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Text Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints @@ -28,8 +29,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints Dim tagService = document.GetRequiredLanguageService(Of IInlineParameterNameHintsService) Dim span = If(hostDocument.SelectedSpans.Any(), hostDocument.SelectedSpans.Single(), New TextSpan(0, snapshot.Length)) - Dim inlineHints = Await tagService.GetInlineHintsAsync( - document, span, options, displayOptions, displayAllOverride:=False, CancellationToken.None) + Dim inlineHints = ArrayBuilder(Of InlineHint).GetInstance() + + Await tagService.AddInlineHintsAsync( + document, span, options, displayOptions, displayAllOverride:=False, inlineHints, CancellationToken.None) Dim producedTags = From hint In inlineHints Select hint.DisplayParts.GetFullText().TrimEnd() + hint.Span.ToString @@ -56,7 +59,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints AssertEx.Equal(expectedTags, producedTags) End Sub - Private Shared Async Function ValidateDoubleClick(document As Document, expectedDocument As Document, inlineHints As ImmutableArray(Of InlineHint)) As Task + Private Shared Async Function ValidateDoubleClick(document As Document, expectedDocument As Document, inlineHints As ArrayBuilder(Of InlineHint)) As Task Dim textChanges = New List(Of TextChange) For Each inlineHint In inlineHints If inlineHint.ReplacementTextChange IsNot Nothing Then @@ -88,8 +91,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints Dim tagService = document.GetRequiredLanguageService(Of IInlineTypeHintsService) Dim span = If(hostDocument.SelectedSpans.Any(), hostDocument.SelectedSpans.Single(), New TextSpan(0, snapshot.Length)) - Dim typeHints = Await tagService.GetInlineHintsAsync( - document, span, options, displayOptions, displayAllOverride:=ephemeral, CancellationToken.None) + Dim typeHints = ArrayBuilder(Of InlineHint).GetInstance() + + Await tagService.AddInlineHintsAsync( + document, span, options, displayOptions, displayAllOverride:=ephemeral, typeHints, CancellationToken.None) Dim producedTags = From hint In typeHints Select hint.DisplayParts.GetFullText() + ":" + hint.Span.ToString() diff --git a/src/Features/Core/Portable/InlineHints/AbstractInlineHintsService.cs b/src/Features/Core/Portable/InlineHints/AbstractInlineHintsService.cs index c42d65e701c76..945605cedb7b8 100644 --- a/src/Features/Core/Portable/InlineHints/AbstractInlineHintsService.cs +++ b/src/Features/Core/Portable/InlineHints/AbstractInlineHintsService.cs @@ -3,10 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -20,14 +20,19 @@ public async Task> GetInlineHintsAsync( var inlineParameterService = document.GetLanguageService(); var inlineTypeService = document.GetLanguageService(); - var parameters = inlineParameterService == null - ? [] - : await inlineParameterService.GetInlineHintsAsync(document, textSpan, options.ParameterOptions, options.DisplayOptions, displayAllOverride, cancellationToken).ConfigureAwait(false); + // Allow large array instances in the pool, as these arrays often exceed the ArrayBuilder reuse size threshold + using var _ = ArrayBuilder.GetInstance(discardLargeInstances: false, out var result); - var types = inlineTypeService == null - ? [] - : await inlineTypeService.GetInlineHintsAsync(document, textSpan, options.TypeOptions, options.DisplayOptions, displayAllOverride, cancellationToken).ConfigureAwait(false); + if (inlineParameterService is not null) + { + await inlineParameterService.AddInlineHintsAsync(document, textSpan, options.ParameterOptions, options.DisplayOptions, displayAllOverride, result, cancellationToken).ConfigureAwait(false); + } - return [.. parameters, .. types]; + if (inlineTypeService is not null) + { + await inlineTypeService.AddInlineHintsAsync(document, textSpan, options.TypeOptions, options.DisplayOptions, displayAllOverride, result, cancellationToken).ConfigureAwait(false); + } + + return result.ToImmutableAndClear(); } } diff --git a/src/Features/Core/Portable/InlineHints/AbstractInlineParameterNameHintsService.cs b/src/Features/Core/Portable/InlineHints/AbstractInlineParameterNameHintsService.cs index f6190e6cba552..e1719337135ac 100644 --- a/src/Features/Core/Portable/InlineHints/AbstractInlineParameterNameHintsService.cs +++ b/src/Features/Core/Portable/InlineHints/AbstractInlineParameterNameHintsService.cs @@ -32,23 +32,24 @@ protected abstract void AddAllParameterNameHintLocations( protected abstract bool IsIndexer(SyntaxNode node, IParameterSymbol parameter); protected abstract string GetReplacementText(string parameterName); - public async Task> GetInlineHintsAsync( + public async Task AddInlineHintsAsync( Document document, TextSpan textSpan, InlineParameterHintsOptions options, SymbolDescriptionOptions displayOptions, bool displayAllOverride, + ArrayBuilder result, CancellationToken cancellationToken) { var enabledForParameters = displayAllOverride || options.EnabledForParameters; if (!enabledForParameters) - return []; + return; var literalParameters = displayAllOverride || options.ForLiteralParameters; var objectCreationParameters = displayAllOverride || options.ForObjectCreationParameters; var otherParameters = displayAllOverride || options.ForOtherParameters; if (!literalParameters && !objectCreationParameters && !otherParameters) - return []; + return; var indexerParameters = displayAllOverride || options.ForIndexerParameters; var suppressForParametersThatDifferOnlyBySuffix = !displayAllOverride && options.SuppressForParametersThatDifferOnlyBySuffix; @@ -59,9 +60,7 @@ public async Task> GetInlineHintsAsync( var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); - // Allow large array instances in the pool, as these arrays often exceed the ArrayBuilder reuse size threshold - using var _1 = ArrayBuilder.GetInstance(discardLargeInstances: false, out var result); - using var _2 = ArrayBuilder<(int position, SyntaxNode argument, IParameterSymbol? parameter, HintKind kind)>.GetInstance(out var buffer); + using var _ = ArrayBuilder<(int position, SyntaxNode argument, IParameterSymbol? parameter, HintKind kind)>.GetInstance(out var buffer); foreach (var node in root.DescendantNodes(textSpan, n => n.Span.IntersectsWith(textSpan))) { @@ -75,7 +74,7 @@ public async Task> GetInlineHintsAsync( } } - return result.ToImmutableAndClear(); + return; void AddHintsIfAppropriate(SyntaxNode node) { diff --git a/src/Features/Core/Portable/InlineHints/AbstractInlineTypeHintsService.cs b/src/Features/Core/Portable/InlineHints/AbstractInlineTypeHintsService.cs index 3a3744256ba59..c184b2262612d 100644 --- a/src/Features/Core/Portable/InlineHints/AbstractInlineTypeHintsService.cs +++ b/src/Features/Core/Portable/InlineHints/AbstractInlineTypeHintsService.cs @@ -28,31 +28,30 @@ internal abstract class AbstractInlineTypeHintsService : IInlineTypeHintsService bool forCollectionExpressions, CancellationToken cancellationToken); - public async Task> GetInlineHintsAsync( + public async Task AddInlineHintsAsync( Document document, TextSpan textSpan, InlineTypeHintsOptions options, SymbolDescriptionOptions displayOptions, bool displayAllOverride, + ArrayBuilder result, CancellationToken cancellationToken) { var enabledForTypes = options.EnabledForTypes; if (!enabledForTypes && !displayAllOverride) - return []; + return; var forImplicitVariableTypes = enabledForTypes && options.ForImplicitVariableTypes; var forLambdaParameterTypes = enabledForTypes && options.ForLambdaParameterTypes; var forImplicitObjectCreation = enabledForTypes && options.ForImplicitObjectCreation; var forCollectionExpressions = enabledForTypes && options.ForCollectionExpressions; if (!forImplicitVariableTypes && !forLambdaParameterTypes && !forImplicitObjectCreation && !forCollectionExpressions && !displayAllOverride) - return []; + return; var anonymousTypeService = document.GetRequiredLanguageService(); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); - using var _1 = ArrayBuilder.GetInstance(out var result); - foreach (var node in root.DescendantNodes(n => n.Span.IntersectsWith(textSpan))) { var hint = TryGetTypeHint( @@ -97,8 +96,6 @@ public async Task> GetInlineHintsAsync( span, taggedText, textChange, ranking: InlineHintsConstants.TypeRanking, InlineHintHelpers.GetDescriptionFunction(spanStart, type, displayOptions))); } - - return result.ToImmutableAndClear(); } private static void AddParts( diff --git a/src/Features/Core/Portable/InlineHints/IInlineParameterNameHintsService.cs b/src/Features/Core/Portable/InlineHints/IInlineParameterNameHintsService.cs index 11c6455c1623c..f6c4118e94d26 100644 --- a/src/Features/Core/Portable/InlineHints/IInlineParameterNameHintsService.cs +++ b/src/Features/Core/Portable/InlineHints/IInlineParameterNameHintsService.cs @@ -2,11 +2,11 @@ // 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.Collections.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.InlineHints; @@ -17,11 +17,12 @@ namespace Microsoft.CodeAnalysis.InlineHints; /// internal interface IInlineParameterNameHintsService : ILanguageService { - Task> GetInlineHintsAsync( + Task AddInlineHintsAsync( Document document, TextSpan textSpan, InlineParameterHintsOptions options, SymbolDescriptionOptions displayOptions, bool displayAllOverride, + ArrayBuilder result, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/InlineHints/IInlineTypeHintsService.cs b/src/Features/Core/Portable/InlineHints/IInlineTypeHintsService.cs index 714a61da6feab..53093fa7bdf22 100644 --- a/src/Features/Core/Portable/InlineHints/IInlineTypeHintsService.cs +++ b/src/Features/Core/Portable/InlineHints/IInlineTypeHintsService.cs @@ -2,11 +2,11 @@ // 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.Collections.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.InlineHints; @@ -17,11 +17,12 @@ namespace Microsoft.CodeAnalysis.InlineHints; /// internal interface IInlineTypeHintsService : ILanguageService { - Task> GetInlineHintsAsync( + Task AddInlineHintsAsync( Document document, TextSpan textSpan, InlineTypeHintsOptions options, SymbolDescriptionOptions displayOptions, bool displayAllOverride, + ArrayBuilder result, CancellationToken cancellationToken); }