Skip to content

Commit

Permalink
Fix: Inline parameter hints for inner bindings (#14506)
Browse files Browse the repository at this point in the history
Fixes #14501
  • Loading branch information
rosskuehl authored Dec 27, 2022
1 parent 0adeca4 commit c3aacd0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
19 changes: 13 additions & 6 deletions vsintegration/src/FSharp.Editor/Hints/HintService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,37 @@ open Microsoft.CodeAnalysis
open Microsoft.VisualStudio.FSharp.Editor
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Symbols
open FSharp.Compiler.Text
open Hints

module HintService =
let private getHintsForSymbol parseResults hintKinds (symbolUse: FSharpSymbolUse) =
let private getHintsForSymbol parseResults hintKinds (longIdEndLocations: Position list) (symbolUse: FSharpSymbolUse) =
match symbolUse.Symbol with
| :? FSharpMemberOrFunctionOrValue as symbol
when hintKinds |> Set.contains HintKind.TypeHint
&& InlineTypeHints.isValidForHint parseResults symbol symbolUse ->

InlineTypeHints.getHints symbol symbolUse
InlineTypeHints.getHints symbol symbolUse,
longIdEndLocations

| :? FSharpMemberOrFunctionOrValue as symbol
when hintKinds |> Set.contains HintKind.ParameterNameHint
&& InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol symbolUse ->

InlineParameterNameHints.getHintsForMemberOrFunctionOrValue parseResults symbol symbolUse
InlineParameterNameHints.getHintsForMemberOrFunctionOrValue parseResults symbol symbolUse longIdEndLocations,
symbolUse.Range.End :: longIdEndLocations

| :? FSharpUnionCase as symbol
when hintKinds |> Set.contains HintKind.ParameterNameHint
&& InlineParameterNameHints.isUnionCaseValidForHint symbol symbolUse ->

InlineParameterNameHints.getHintsForUnionCase parseResults symbol symbolUse
InlineParameterNameHints.getHintsForUnionCase parseResults symbol symbolUse,
longIdEndLocations

// we'll be adding other stuff gradually here
| _ ->
[]
[],
longIdEndLocations

let getHintsForDocument (document: Document) hintKinds userOpName cancellationToken =
async {
Expand All @@ -44,6 +49,8 @@ module HintService =

return
checkResults.GetAllUsesOfAllSymbolsInFile cancellationToken
|> Seq.mapFold (getHintsForSymbol parseResults hintKinds) []
|> fst
|> Seq.concat
|> Seq.toList
|> List.collect (getHintsForSymbol parseResults hintKinds)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ module InlineParameterNameHints =

let private getArgumentLocations
(symbolUse: FSharpSymbolUse)
(longIdEndLocations: Position list)
(parseResults: FSharpParseFileResults) =

let position = Position.mkPos
(symbolUse.Range.End.Line)
(symbolUse.Range.End.Column + 1)

parseResults.FindParameterLocations position
|> Option.filter (fun locations -> longIdEndLocations |> List.contains locations.LongIdEndLocation |> not)
|> Option.map (fun locations -> locations.ArgumentLocations)
|> Option.defaultValue [||]

Expand Down Expand Up @@ -81,10 +83,11 @@ module InlineParameterNameHints =
let getHintsForMemberOrFunctionOrValue
(parseResults: FSharpParseFileResults)
(symbol: FSharpMemberOrFunctionOrValue)
(symbolUse: FSharpSymbolUse) =
(symbolUse: FSharpSymbolUse)
(longIdEndLocations: Position list) =

let parameters = symbol.CurriedParameterGroups |> Seq.concat
let argumentLocations = getArgumentLocations symbolUse parseResults
let argumentLocations = parseResults |> getArgumentLocations symbolUse longIdEndLocations

let tupleRanges = argumentLocations |> getTupleRanges
let curryRanges = parseResults |> getCurryRanges symbolUse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,3 +448,34 @@ type MyType() =
let actual = getParameterNameHints document

Assert.IsEmpty(actual)

[<Test>]
let ``Hints are shown correctly for inner bindings`` () =
let code =
"""
let test sequences =
sequences
|> Seq.map (fun sequence -> sequence |> Seq.map (fun sequence' -> sequence' |> Seq.map (fun item -> item)))
"""

let document = getFsDocument code

let expected =
[
{
Content = "mapping = "
Location = (3, 16)
}
{
Content = "mapping = "
Location = (3, 53)
}
{
Content = "mapping = "
Location = (3, 92)
}
]

let actual = getParameterNameHints document

Assert.AreEqual(expected, actual)

0 comments on commit c3aacd0

Please sign in to comment.