Skip to content

Commit 1f096ee

Browse files
Filter out inline hint spans out of hte bounds of hte span we are querying for (#76493)
2 parents 7edae94 + f87368f commit 1f096ee

File tree

7 files changed

+114
-21
lines changed

7 files changed

+114
-21
lines changed

src/EditorFeatures/Test2/InlineHints/AbstractInlineHintsTests.vb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44

55
Imports System.Collections.Immutable
66
Imports System.Threading
7-
Imports Microsoft.CodeAnalysis.Editor.InlineHints
8-
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
97
Imports Microsoft.CodeAnalysis.InlineHints
108
Imports Microsoft.CodeAnalysis.LanguageService
11-
Imports Microsoft.CodeAnalysis.Options
12-
Imports Microsoft.CodeAnalysis.[Shared].Utilities
139
Imports Microsoft.CodeAnalysis.Text
1410

1511
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints
@@ -30,8 +26,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints
3026
Dim snapshot = hostDocument.GetTextBuffer().CurrentSnapshot
3127
Dim document = workspace.CurrentSolution.GetDocument(hostDocument.Id)
3228
Dim tagService = document.GetRequiredLanguageService(Of IInlineParameterNameHintsService)
29+
30+
Dim span = If(hostDocument.SelectedSpans.Any(), hostDocument.SelectedSpans.Single(), New TextSpan(0, snapshot.Length))
3331
Dim inlineHints = Await tagService.GetInlineHintsAsync(
34-
document, New Text.TextSpan(0, snapshot.Length), options, displayOptions, displayAllOverride:=False, CancellationToken.None)
32+
document, span, options, displayOptions, displayAllOverride:=False, CancellationToken.None)
3533

3634
Dim producedTags = From hint In inlineHints
3735
Select hint.DisplayParts.GetFullText().TrimEnd() + hint.Span.ToString
@@ -88,8 +86,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.InlineHints
8886
Dim snapshot = hostDocument.GetTextBuffer().CurrentSnapshot
8987
Dim document = workspace.CurrentSolution.GetDocument(hostDocument.Id)
9088
Dim tagService = document.GetRequiredLanguageService(Of IInlineTypeHintsService)
89+
90+
Dim span = If(hostDocument.SelectedSpans.Any(), hostDocument.SelectedSpans.Single(), New TextSpan(0, snapshot.Length))
9191
Dim typeHints = Await tagService.GetInlineHintsAsync(
92-
document, New Text.TextSpan(0, snapshot.Length), options, displayOptions, displayAllOverride:=ephemeral, CancellationToken.None)
92+
document, span, options, displayOptions, displayAllOverride:=ephemeral, CancellationToken.None)
9393

9494
Dim producedTags = From hint In typeHints
9595
Select hint.DisplayParts.GetFullText() + ":" + hint.Span.ToString()

src/EditorFeatures/Test2/InlineHints/CSharpInlineParameterNameHintsTests.vb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,5 +1255,48 @@ class C
12551255

12561256
Await VerifyParamHints(input, output)
12571257
End Function
1258+
1259+
<WpfFact>
1260+
Public Async Function TestOnlyProduceTagsWithinSelection() As Task
1261+
Dim input =
1262+
<Workspace>
1263+
<Project Language="C#" CommonReferences="true">
1264+
<Document>
1265+
class A
1266+
{
1267+
int testMethod(int a, int b, int c, int d, int e)
1268+
{
1269+
return x;
1270+
}
1271+
void Main()
1272+
{
1273+
testMethod(1, [|{|b:|}2, {|c:|}3, {|d:|}4|], 5);
1274+
}
1275+
}
1276+
</Document>
1277+
</Project>
1278+
</Workspace>
1279+
1280+
Dim output =
1281+
<Workspace>
1282+
<Project Language="C#" CommonReferences="true">
1283+
<Document>
1284+
class A
1285+
{
1286+
int testMethod(int a, int b, int c, int d, int e)
1287+
{
1288+
return x;
1289+
}
1290+
void Main()
1291+
{
1292+
testMethod(1, b: 2, c: 3, d: 4, 5);
1293+
}
1294+
}
1295+
</Document>
1296+
</Project>
1297+
</Workspace>
1298+
1299+
Await VerifyParamHints(input, output)
1300+
End Function
12581301
End Class
12591302
End Namespace

src/EditorFeatures/Test2/InlineHints/CSharpInlineTypeHintsTests.vb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,5 +848,46 @@ class A
848848

849849
Await VerifyTypeHints(input, output)
850850
End Function
851+
852+
<WpfFact>
853+
Public Async Function TestOnlyProduceTagsWithinSelection() As Task
854+
Dim input =
855+
<Workspace>
856+
<Project Language="C#" CommonReferences="true">
857+
<Document>
858+
class A
859+
{
860+
void Main()
861+
{
862+
var a = 0;
863+
[|var {|int :|}b = 0;
864+
var {|int :|}c = 0;|]
865+
var d = 0;
866+
}
867+
}
868+
</Document>
869+
</Project>
870+
</Workspace>
871+
872+
Dim output =
873+
<Workspace>
874+
<Project Language="C#" CommonReferences="true">
875+
<Document>
876+
class A
877+
{
878+
void Main()
879+
{
880+
var a = 0;
881+
int b = 0;
882+
int c = 0;
883+
var d = 0;
884+
}
885+
}
886+
</Document>
887+
</Project>
888+
</Workspace>
889+
890+
Await VerifyTypeHints(input, output)
891+
End Function
851892
End Class
852893
End Namespace

src/Features/CSharp/Portable/InlineHints/CSharpInlineHintsService.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ namespace Microsoft.CodeAnalysis.CSharp.InlineHints;
1313
/// The service to locate all positions where inline hints should be placed.
1414
/// </summary>
1515
[ExportLanguageService(typeof(IInlineHintsService), LanguageNames.CSharp), Shared]
16-
internal class CSharpInlineHintsService : AbstractInlineHintsService
17-
{
18-
[ImportingConstructor]
19-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
20-
public CSharpInlineHintsService()
21-
{
22-
}
23-
}
16+
[method: ImportingConstructor]
17+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
18+
internal sealed class CSharpInlineHintsService() : AbstractInlineHintsService;

src/Features/Core/Portable/InlineHints/AbstractInlineParameterNameHintsService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ void AddHintsIfAppropriate(SyntaxNode node)
8484

8585
foreach (var (position, argument, parameter, kind) in buffer)
8686
{
87+
// We get hints on *nodes* that intersect the passed in text span. However, while the full node may
88+
// intersect the span, the positions of the all the sub-nodes in it that we make hints for (like the
89+
// positions of the arguments in an invocation) may not. So, filter out any hints that aren't actually
90+
// in the span we care about here.
91+
if (!textSpan.IntersectsWith(position))
92+
continue;
93+
8794
if (string.IsNullOrEmpty(parameter?.Name))
8895
continue;
8996

src/Features/Core/Portable/InlineHints/AbstractInlineTypeHintsService.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.InlineHints;
1515

1616
internal abstract class AbstractInlineTypeHintsService : IInlineTypeHintsService
1717
{
18-
protected static readonly SymbolDisplayFormat s_minimalTypeStyle = new SymbolDisplayFormat(
18+
protected static readonly SymbolDisplayFormat s_minimalTypeStyle = new(
1919
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
2020
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier | SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
2121

@@ -55,24 +55,31 @@ public async Task<ImmutableArray<InlineHint>> GetInlineHintsAsync(
5555

5656
foreach (var node in root.DescendantNodes(n => n.Span.IntersectsWith(textSpan)))
5757
{
58-
var hintOpt = TryGetTypeHint(
58+
var hint = TryGetTypeHint(
5959
semanticModel, node,
6060
displayAllOverride,
6161
forImplicitVariableTypes,
6262
forLambdaParameterTypes,
6363
forImplicitObjectCreation,
6464
forCollectionExpressions,
6565
cancellationToken);
66-
if (hintOpt == null)
66+
if (hint is not var (type, span, textChange, prefix, suffix))
6767
continue;
6868

69-
var (type, span, textChange, prefix, suffix) = hintOpt.Value;
69+
var spanStart = span.Start;
70+
71+
// We get hints on *nodes* that intersect the passed in text span. However, while the full node may
72+
// intersect the span, the positions of the all the sub-nodes in it that we make hints for (like the
73+
// positions of the arguments in an invocation) may not. So, filter out any hints that aren't actually
74+
// in the span we care about here.
75+
if (!textSpan.IntersectsWith(spanStart))
76+
continue;
7077

7178
using var _2 = ArrayBuilder<SymbolDisplayPart>.GetInstance(out var finalParts);
7279
finalParts.AddRange(prefix);
7380

7481
var parts = type.ToDisplayParts(s_minimalTypeStyle);
75-
AddParts(anonymousTypeService, finalParts, parts, semanticModel, span.Start);
82+
AddParts(anonymousTypeService, finalParts, parts, semanticModel, spanStart);
7683

7784
// If we have nothing to show, then don't bother adding this hint.
7885
if (finalParts.All(p => string.IsNullOrWhiteSpace(p.ToString())))
@@ -83,7 +90,7 @@ public async Task<ImmutableArray<InlineHint>> GetInlineHintsAsync(
8390

8491
result.Add(new InlineHint(
8592
span, taggedText, textChange, ranking: InlineHintsConstants.TypeRanking,
86-
InlineHintHelpers.GetDescriptionFunction(span.Start, type.GetSymbolKey(cancellationToken: cancellationToken), displayOptions)));
93+
InlineHintHelpers.GetDescriptionFunction(spanStart, type.GetSymbolKey(cancellationToken), displayOptions)));
8794
}
8895

8996
return result.ToImmutableAndClear();

src/Features/VisualBasic/Portable/InlineHints/VisualBasicInlineHintsService.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InlineHints
1111
''' The service to locate all positions where inline hints should be placed.
1212
''' </summary>
1313
<ExportLanguageService(GetType(IInlineHintsService), LanguageNames.VisualBasic), [Shared]>
14-
Friend Class VisualBasicInlineHintsService
14+
Friend NotInheritable Class VisualBasicInlineHintsService
1515
Inherits AbstractInlineHintsService
1616

1717
<ImportingConstructor>

0 commit comments

Comments
 (0)