From 3048b351f3e15afd91a7ab8d430303daf8ef0fcb Mon Sep 17 00:00:00 2001 From: Ross Kuehl <94796738+rosskuehl@users.noreply.github.com> Date: Wed, 21 Dec 2022 00:27:46 -0500 Subject: [PATCH 1/5] fix inline parameter hints for inner bindings --- .../src/FSharp.Editor/Hints/HintService.fs | 24 ++++++++------ .../Hints/InlineParameterNameHints.fs | 7 ++-- .../Hints/InlineParameterNameHintTests.fs | 32 +++++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/HintService.fs b/vsintegration/src/FSharp.Editor/Hints/HintService.fs index 6b23fe78506..b5de2cad557 100644 --- a/vsintegration/src/FSharp.Editor/Hints/HintService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/HintService.fs @@ -6,32 +6,36 @@ 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 + 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 + 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 + 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 { @@ -44,6 +48,8 @@ module HintService = return checkResults.GetAllUsesOfAllSymbolsInFile cancellationToken + |> Seq.mapFold (getHintsForSymbol parseResults hintKinds) [] + |> fst + |> Seq.concat |> Seq.toList - |> List.collect (getHintsForSymbol parseResults hintKinds) } diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs index 4d55fe98986..1948936abca 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs @@ -32,6 +32,7 @@ module InlineParameterNameHints = let private getTupleRanges (symbolUse: FSharpSymbolUse) + (longIdEndLocations: Position list) (parseResults: FSharpParseFileResults) = let position = Position.mkPos @@ -39,6 +40,7 @@ module InlineParameterNameHints = (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.map (Seq.map (fun location -> location.ArgumentRange)) |> Option.defaultValue [] @@ -70,11 +72,12 @@ module InlineParameterNameHints = let getHintsForMemberOrFunctionOrValue (parseResults: FSharpParseFileResults) (symbol: FSharpMemberOrFunctionOrValue) - (symbolUse: FSharpSymbolUse) = + (symbolUse: FSharpSymbolUse) + (longIdEndLocations: Position list) = let parameters = symbol.CurriedParameterGroups |> Seq.concat - let tupleRanges = parseResults |> getTupleRanges symbolUse + let tupleRanges = parseResults |> getTupleRanges symbolUse longIdEndLocations let curryRanges = parseResults |> getCurryRanges symbolUse let ranges = if tupleRanges |> (not << Seq.isEmpty) then tupleRanges else curryRanges diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs index 5a49830098a..d60bed04373 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs @@ -406,3 +406,35 @@ let x = "test".Split("").[0].Split(""); let actual = getParameterNameHints document Assert.AreEqual(expected, actual) + + [] + 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) + \ No newline at end of file From 5026148e439ed66e1b8198412fb955c08bfc353a Mon Sep 17 00:00:00 2001 From: Ross Kuehl <94796738+rosskuehl@users.noreply.github.com> Date: Wed, 21 Dec 2022 15:58:49 -0500 Subject: [PATCH 2/5] fix merge conflict --- .../src/FSharp.Editor/Hints/InlineParameterNameHints.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs index 46f62588efc..eb9ef6e9ff7 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs @@ -87,9 +87,9 @@ module InlineParameterNameHints = (longIdEndLocations: Position list) = let parameters = symbol.CurriedParameterGroups |> Seq.concat - let argumentLocations = getArgumentLocations symbolUse parseResults + let argumentLocations = getArgumentLocations symbolUse parseResults longIdEndLocations - let tupleRanges = parseResults |> getTupleRanges symbolUse longIdEndLocations + let tupleRanges = argumentLocations |> getTupleRanges let curryRanges = parseResults |> getCurryRanges symbolUse let ranges = From 84769c99136fca6ea54429c8ea4c28977d607f69 Mon Sep 17 00:00:00 2001 From: Ross Kuehl <94796738+rosskuehl@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:00:10 -0500 Subject: [PATCH 3/5] fix merge conflict --- .../src/FSharp.Editor/Hints/InlineParameterNameHints.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs index eb9ef6e9ff7..d4278188329 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs @@ -87,7 +87,7 @@ module InlineParameterNameHints = (longIdEndLocations: Position list) = let parameters = symbol.CurriedParameterGroups |> Seq.concat - let argumentLocations = getArgumentLocations symbolUse parseResults longIdEndLocations + let argumentLocations = parseResults |> getArgumentLocations symbolUse longIdEndLocations let tupleRanges = argumentLocations |> getTupleRanges let curryRanges = parseResults |> getCurryRanges symbolUse From de0af6c913d1f22f1291e29604f480605a9c70be Mon Sep 17 00:00:00 2001 From: Ross Kuehl <94796738+rosskuehl@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:04:56 -0500 Subject: [PATCH 4/5] fix merge conflict --- .../Hints/InlineParameterNameHintTests.fs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs index c28fc5f80ef..64f62426896 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs @@ -406,13 +406,15 @@ let x = "test".Split("").[0].Split(""); let actual = getParameterNameHints document Assert.AreEqual(expected, actual) - + [] let ``Hints are not shown for optional parameters with specified names`` () = let code = """ type MyType() = + member _.MyMethod(?beep: int, ?bap: int, ?boop: int) = () + member this.Foo = this.MyMethod(3, boop = 4) """ @@ -435,7 +437,9 @@ type MyType() = let code = """ type MyType() = + member _.MyMethod(?beep: int, ?bap : int, ?boop : int) = () + member this.Foo = this.MyMethod(bap = 3, beep = 4) """ @@ -471,3 +475,7 @@ let test sequences = Location = (3, 92) } ] + + let actual = getParameterNameHints document + + Assert.AreEqual(expected, actual) \ No newline at end of file From 8828d341a5bd94769fb71411a4072a3379d13810 Mon Sep 17 00:00:00 2001 From: Ross Kuehl <94796738+rosskuehl@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:07:30 -0500 Subject: [PATCH 5/5] fix whitespace --- vsintegration/src/FSharp.Editor/Hints/HintService.fs | 9 +++++---- .../Hints/InlineParameterNameHintTests.fs | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/HintService.fs b/vsintegration/src/FSharp.Editor/Hints/HintService.fs index b5de2cad557..da24834efcb 100644 --- a/vsintegration/src/FSharp.Editor/Hints/HintService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/HintService.fs @@ -13,21 +13,21 @@ module HintService = let private getHintsForSymbol parseResults hintKinds (longIdEndLocations: Position list) (symbolUse: FSharpSymbolUse) = match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as symbol - when hintKinds |> Set.contains HintKind.TypeHint + when hintKinds |> Set.contains HintKind.TypeHint && InlineTypeHints.isValidForHint parseResults symbol symbolUse -> InlineTypeHints.getHints symbol symbolUse, longIdEndLocations | :? FSharpMemberOrFunctionOrValue as symbol - when hintKinds |> Set.contains HintKind.ParameterNameHint + when hintKinds |> Set.contains HintKind.ParameterNameHint && InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol symbolUse -> InlineParameterNameHints.getHintsForMemberOrFunctionOrValue parseResults symbol symbolUse longIdEndLocations, symbolUse.Range.End :: longIdEndLocations | :? FSharpUnionCase as symbol - when hintKinds |> Set.contains HintKind.ParameterNameHint + when hintKinds |> Set.contains HintKind.ParameterNameHint && InlineParameterNameHints.isUnionCaseValidForHint symbol symbolUse -> InlineParameterNameHints.getHintsForUnionCase parseResults symbol symbolUse, @@ -35,7 +35,8 @@ module HintService = // we'll be adding other stuff gradually here | _ -> - [], longIdEndLocations + [], + longIdEndLocations let getHintsForDocument (document: Document) hintKinds userOpName cancellationToken = async { diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs index 64f62426896..998cb78bdce 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineParameterNameHintTests.fs @@ -414,7 +414,7 @@ let x = "test".Split("").[0].Split(""); type MyType() = member _.MyMethod(?beep: int, ?bap: int, ?boop: int) = () - + member this.Foo = this.MyMethod(3, boop = 4) """ @@ -439,7 +439,7 @@ type MyType() = type MyType() = member _.MyMethod(?beep: int, ?bap : int, ?boop : int) = () - + member this.Foo = this.MyMethod(bap = 3, beep = 4) """