diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs index 8fb16d16d04..4d55fe98986 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs @@ -30,6 +30,27 @@ module InlineParameterNameHints = let private doesFieldNameExist (field: FSharpField) = not field.IsNameGenerated + let private getTupleRanges + (symbolUse: FSharpSymbolUse) + (parseResults: FSharpParseFileResults) = + + let position = Position.mkPos + (symbolUse.Range.End.Line) + (symbolUse.Range.End.Column + 1) + + parseResults.FindParameterLocations position + |> Option.map (fun locations -> locations.ArgumentLocations) + |> Option.map (Seq.map (fun location -> location.ArgumentRange)) + |> Option.defaultValue [] + |> Seq.toList + + let private getCurryRanges + (symbolUse: FSharpSymbolUse) + (parseResults: FSharpParseFileResults) = + + parseResults.GetAllArgumentsForFunctionApplicationAtPosition symbolUse.Range.Start + |> Option.defaultValue [] + let isMemberOrFunctionOrValueValidForHint (symbol: FSharpMemberOrFunctionOrValue) (symbolUse: FSharpSymbolUse) = if symbolUse.IsFromUse then let isNotBuiltInOperator = @@ -52,18 +73,16 @@ module InlineParameterNameHints = (symbolUse: FSharpSymbolUse) = let parameters = symbol.CurriedParameterGroups |> Seq.concat - let ranges = parseResults.GetAllArgumentsForFunctionApplicationAtPosition symbolUse.Range.Start - - match ranges with - | Some ranges -> - parameters - |> Seq.zip ranges - |> Seq.where (snd >> doesParameterNameExist) - |> Seq.map getParameterHint - |> Seq.toList - - // this is the case at least for custom operators - | None -> [] + + let tupleRanges = parseResults |> getTupleRanges symbolUse + let curryRanges = parseResults |> getCurryRanges symbolUse + let ranges = if tupleRanges |> (not << Seq.isEmpty) then tupleRanges else curryRanges + + parameters + |> Seq.zip ranges // Seq.zip is important as List.zip requires equal lengths + |> Seq.where (snd >> doesParameterNameExist) + |> Seq.map getParameterHint + |> Seq.toList let getHintsForUnionCase (parseResults: FSharpParseFileResults) diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs index 751d089720c..f009feba036 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs @@ -32,7 +32,9 @@ module HintTestFramework = let getFsDocument code = use project = SingleFileProject code let fileName = fst project.Files.Head - let document, _ = RoslynTestHelpers.CreateSingleDocumentSolution(fileName, code) + // I don't know, without this lib some symbols are just not loaded + let options = { project.Options with OtherOptions = [| "--targetprofile:netcore" |] } + let document, _ = RoslynTestHelpers.CreateSingleDocumentSolution(fileName, code, options) document let getFsiAndFsDocuments (fsiCode: string) (fsCode: string) = diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs index 532ce7adfe1..5a49830098a 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs @@ -381,3 +381,28 @@ type X = let actual = getParameterNameHints document Assert.IsEmpty(actual) + + [] + let ``Hints are not shown in front of indexes`` () = + let code = + """ +let x = "test".Split("").[0].Split(""); +""" + + let document = getFsDocument code + + let expected = + [ + { + Content = "separator = " + Location = (1, 22) + } + { + Content = "separator = " + Location = (1, 36) + } + ] + + let actual = getParameterNameHints document + + Assert.AreEqual(expected, actual)