From 0a9c65b49dbd2043d479133450dbaad1171e2abf Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Tue, 28 Mar 2023 12:10:52 +0200 Subject: [PATCH 01/12] wip --- .../src/FSharp.Editor/FSharp.Editor.fsproj | 1 + .../src/FSharp.Editor/Hints/HintService.fs | 9 +- .../src/FSharp.Editor/Hints/Hints.fs | 2 + .../src/FSharp.Editor/Hints/OptionParser.fs | 3 + .../FSharp.Editor/Hints/ReturnTypeHints.fs | 91 +++++++++++++++++++ .../src/FSharp.Editor/Hints/RoslynAdapter.fs | 4 +- .../Hints/HintTestFramework.fs | 3 + .../Hints/InlineTypeHintTests.fs | 15 +++ 8 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj index e14959f62a6..80a90a90c2a 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj @@ -137,6 +137,7 @@ + diff --git a/vsintegration/src/FSharp.Editor/Hints/HintService.fs b/vsintegration/src/FSharp.Editor/Hints/HintService.fs index ee6b6ac6c1f..68fb91fd130 100644 --- a/vsintegration/src/FSharp.Editor/Hints/HintService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/HintService.fs @@ -17,6 +17,9 @@ module HintService = Seq.filter (InlineTypeHints.isValidForHint parseResults symbol) >> Seq.collect (InlineTypeHints.getHints symbol) + let inline private getReturnTypeHints parseResults symbol = + Seq.collect (ReturnTypeHints(parseResults, symbol).getHints) + let inline private getHintsForMemberOrFunctionOrValue (sourceText: SourceText) parseResults symbol : NativeHintResolver = Seq.filter (InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol) >> Seq.collect (InlineParameterNameHints.getHintsForMemberOrFunctionOrValue sourceText parseResults symbol) @@ -35,6 +38,10 @@ module HintService = match symbol with | :? FSharpMemberOrFunctionOrValue as symbol -> getTypeHints parseResults symbol |> Some | _ -> None + | HintKind.ReturnTypeHint -> + match symbol with + | :? FSharpMemberOrFunctionOrValue as symbol -> getReturnTypeHints parseResults symbol |> Some + | _ -> None | HintKind.ParameterNameHint -> match symbol with | :? FSharpMemberOrFunctionOrValue as symbol -> @@ -45,7 +52,7 @@ module HintService = :: resolvers |> resolve hintKinds - in resolve hintKinds [] + resolve hintKinds [] let private getHintsForSymbol (sourceText: SourceText) parseResults hintKinds (symbol: FSharpSymbol, symbolUses: FSharpSymbolUse seq) = symbol diff --git a/vsintegration/src/FSharp.Editor/Hints/Hints.fs b/vsintegration/src/FSharp.Editor/Hints/Hints.fs index 428f1fa54ed..dcdb17e5eee 100644 --- a/vsintegration/src/FSharp.Editor/Hints/Hints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/Hints.fs @@ -9,6 +9,7 @@ module Hints = type HintKind = | TypeHint | ParameterNameHint + | ReturnTypeHint // Relatively convenient for testing type NativeHint = @@ -22,3 +23,4 @@ module Hints = match kind with | TypeHint -> "type" | ParameterNameHint -> "parameterName" + | ReturnTypeHint -> "returnType" diff --git a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs index 181bc2b7c61..8cefb78f4a3 100644 --- a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs +++ b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs @@ -15,4 +15,7 @@ module OptionParser = if options.IsInlineParameterNameHintsEnabled then HintKind.ParameterNameHint + + // TODO: options + HintKind.ReturnTypeHint ] diff --git a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs new file mode 100644 index 00000000000..877984debc5 --- /dev/null +++ b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor.Hints + +open Microsoft.VisualStudio.FSharp.Editor +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text +open FSharp.Compiler.Text.Position +open Hints +open FSharp.Compiler.Syntax + + +type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMemberOrFunctionOrValue) = + + + let getHintParts (symbolUse: FSharpSymbolUse) = + + match symbol.GetReturnTypeLayout symbolUse.DisplayContext with + | Some typeInfo -> + let colon = TaggedText(TextTag.Text, ": ") + colon :: (typeInfo |> Array.toList) + + // not sure when this can happen + | None -> [] + + + let getHint (symbolUse: FSharpSymbolUse) = + { + Kind = HintKind.TypeHint + Range = symbolUse.Range.EndRange + Parts = getHintParts symbolUse + } + + let isSolved = + if symbol.GenericParameters.Count > 0 then + symbol.GenericParameters |> Seq.forall (fun p -> p.IsSolveAtCompileTime) + + elif symbol.FullType.IsGenericParameter then + symbol.FullType.GenericParameter.DisplayNameCore <> "?" + + else + true + + let findBindingEqualsPosition (symbolUse: FSharpSymbolUse) = + let visitor = + { new SyntaxVisitorBase<_>() with + + override _.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr + + override _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding (trivia = trivia; range = range) when range = symbolUse.Range -> + trivia.EqualsRange + | _ -> defaultTraverse binding + } + SyntaxTraversal.Traverse(symbolUse.Range.End, parseFileResults.ParseTree, visitor) + + + member _.isValidForReturnTypeHint (symbolUse: FSharpSymbolUse) = + + + let adjustedRangeStart = + + symbolUse.Range.Start + + let isNotAnnotatedManually = + not (parseFileResults.IsTypeAnnotationGivenAtPosition adjustedRangeStart) + + let isNotAfterDot = symbolUse.IsFromDefinition && not symbol.IsMemberThisValue + + let isNotTypeAlias = not symbol.IsConstructorThisValue + + symbol.IsValue // we'll be adding other stuff gradually here + && isSolved + && isNotAnnotatedManually + && isNotAfterDot + && isNotTypeAlias + + member _.getHints (symbolUse: FSharpSymbolUse) = [ + if symbol.IsFunction && isSolved then + + match findBindingEqualsPosition symbolUse with + | Some equalsRange -> + + let _adjustedRangeStart = equalsRange.Start + + getHint symbolUse + | None -> () + + ] \ No newline at end of file diff --git a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs index 53820400d94..82969d335b0 100644 --- a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs +++ b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs @@ -33,7 +33,9 @@ type internal RoslynAdapter [] (settings: EditorOptions) = let! nativeHints = HintService.getHintsForDocument sourceText document hintKinds userOpName cancellationToken let roslynHints = - nativeHints |> Seq.map (NativeToRoslynHintConverter.convert sourceText) + nativeHints + |> Seq.filter (fun hint -> not hint.Parts.IsEmpty) + |> Seq.map (NativeToRoslynHintConverter.convert sourceText) return roslynHints.ToImmutableArray() } diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs index 70f06bb0940..6be45304e24 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs @@ -66,6 +66,9 @@ module HintTestFramework = let getTypeHints document = getHints document (Set.empty.Add(HintKind.TypeHint)) + let getReturnTypeHints document = + getHints document (Set.empty.Add(HintKind.ReturnTypeHint)) + let getParameterNameHints document = getHints document (Set.empty.Add(HintKind.ParameterNameHint)) diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs index d995223fbd3..19fb12ccb19 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs @@ -185,6 +185,21 @@ let zip4 (l1: 'a list) (l2: 'b list) (l3: 'c list) (l4: 'd list) = actual |> Assert.shouldBeEquivalentTo expected + [] + let ``Hints are shown for let-bound function return types`` () = + let code = + """ + let func () = 3 + let func2 x = x + 1 + let setConsoleOut = System.Console.SetOut + """ + + let document = getFsDocument code + + let result = getReturnTypeHints document + + Assert.Empty(result) + [] let ``Hints are not shown for lambda return types`` () = let code = From 0d122173f8aa5f81b1d47a4b770e911d6274c47e Mon Sep 17 00:00:00 2001 From: Petr Pokorny Date: Wed, 29 Mar 2023 16:51:39 +0200 Subject: [PATCH 02/12] working return hints --- src/Compiler/Symbols/Symbols.fs | 32 ++--- .../FSharp.Editor/Hints/InlineTypeHints.fs | 2 +- .../src/FSharp.Editor/Hints/OptionParser.fs | 4 +- .../FSharp.Editor/Hints/ReturnTypeHints.fs | 122 ++++++++---------- .../FSharp.Editor/Options/EditorOptions.fs | 2 + .../FSharp.Editor/xlf/FSharp.Editor.cs.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.de.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.es.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.fr.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.it.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.ja.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.ko.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.pl.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.ru.xlf | 6 +- .../FSharp.Editor/xlf/FSharp.Editor.tr.xlf | 6 +- .../xlf/FSharp.Editor.zh-Hans.xlf | 6 +- .../xlf/FSharp.Editor.zh-Hant.xlf | 6 +- .../AdvancedOptionsControl.xaml | 2 + .../FSharp.UIResources/Strings.Designer.cs | 9 ++ .../src/FSharp.UIResources/Strings.resx | 3 + .../src/FSharp.UIResources/xlf/Strings.cs.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.de.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.es.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.fr.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.it.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.ja.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.ko.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.pl.xlf | 5 + .../FSharp.UIResources/xlf/Strings.pt-BR.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.ru.xlf | 5 + .../src/FSharp.UIResources/xlf/Strings.tr.xlf | 5 + .../xlf/Strings.zh-Hans.xlf | 5 + .../xlf/Strings.zh-Hant.xlf | 5 + .../FSharp.Editor.Tests.fsproj | 1 + .../Hints/HintTestFramework.fs | 10 +- .../Hints/InlineTypeHintTests.fs | 15 --- .../Hints/OverallHintExperienceTests.fs | 10 +- .../Hints/ReturnTypeHintTests.fs | 80 ++++++++++++ 39 files changed, 297 insertions(+), 138 deletions(-) create mode 100644 vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 69ab4da96e1..2c799cdcbca 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -2331,24 +2331,20 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = |> LayoutRender.toArray member x.GetReturnTypeLayout (displayContext: FSharpDisplayContext) = - match x.IsMember, d with - | true, _ -> - None - | false, _ -> - checkIsResolved() - match d with - | E _ - | P _ - | C _ -> None - | M m -> - let retTy = m.GetFSharpReturnType(cenv.amap, range0, m.FormalMethodInst) - NicePrint.layoutType (displayContext.Contents cenv.g) retTy - |> LayoutRender.toArray - |> Some - | V v -> - NicePrint.layoutOfValReturnType (displayContext.Contents cenv.g) v - |> LayoutRender.toArray - |> Some + checkIsResolved() + match d with + | E _ + | P _ + | C _ -> None + | M m -> + let retTy = m.GetFSharpReturnType(cenv.amap, range0, m.FormalMethodInst) + NicePrint.layoutType (displayContext.Contents cenv.g) retTy + |> LayoutRender.toArray + |> Some + | V v -> + NicePrint.layoutOfValReturnType (displayContext.Contents cenv.g) v + |> LayoutRender.toArray + |> Some member x.GetWitnessPassingInfo() = let witnessInfos = diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs index 94aba509bc5..707a25cfb35 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs @@ -28,7 +28,7 @@ module InlineTypeHints = Parts = getHintParts symbol symbolUse } - let private isSolved (symbol: FSharpMemberOrFunctionOrValue) = + let isSolved (symbol: FSharpMemberOrFunctionOrValue) = if symbol.GenericParameters.Count > 0 then symbol.GenericParameters |> Seq.forall (fun p -> p.IsSolveAtCompileTime) diff --git a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs index 8cefb78f4a3..28858627bf3 100644 --- a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs +++ b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs @@ -16,6 +16,6 @@ module OptionParser = if options.IsInlineParameterNameHintsEnabled then HintKind.ParameterNameHint - // TODO: options - HintKind.ReturnTypeHint + if options.IsReturnTypeHintsEnabled then + HintKind.ReturnTypeHint ] diff --git a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs index 877984debc5..209e4563975 100644 --- a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs @@ -5,87 +5,67 @@ namespace Microsoft.VisualStudio.FSharp.Editor.Hints open Microsoft.VisualStudio.FSharp.Editor open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.Text.Position open Hints -open FSharp.Compiler.Syntax - +open InlineTypeHints type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMemberOrFunctionOrValue) = - let getHintParts (symbolUse: FSharpSymbolUse) = - - match symbol.GetReturnTypeLayout symbolUse.DisplayContext with - | Some typeInfo -> - let colon = TaggedText(TextTag.Text, ": ") - colon :: (typeInfo |> Array.toList) - - // not sure when this can happen - | None -> [] - - - let getHint (symbolUse: FSharpSymbolUse) = - { - Kind = HintKind.TypeHint - Range = symbolUse.Range.EndRange - Parts = getHintParts symbolUse - } - - let isSolved = - if symbol.GenericParameters.Count > 0 then - symbol.GenericParameters |> Seq.forall (fun p -> p.IsSolveAtCompileTime) - - elif symbol.FullType.IsGenericParameter then - symbol.FullType.GenericParameter.DisplayNameCore <> "?" - - else - true - - let findBindingEqualsPosition (symbolUse: FSharpSymbolUse) = - let visitor = + symbol.GetReturnTypeLayout symbolUse.DisplayContext + |> Option.map (fun typeInfo -> + [ + TaggedText(TextTag.Text, ": ") + yield! typeInfo |> Array.toList + TaggedText(TextTag.Space, " ") + ]) + + let getHint symbolUse range = + getHintParts symbolUse + |> Option.map (fun parts -> + { + Kind = HintKind.ReturnTypeHint + Range = range + Parts = parts + }) + + let isSolved = isSolved symbol + + let findEqualsPositionIfValid (symbolUse: FSharpSymbolUse) = + SyntaxTraversal.Traverse( + symbolUse.Range.End, + parseFileResults.ParseTree, { new SyntaxVisitorBase<_>() with - - override _.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr - override _.VisitBinding(_path, defaultTraverse, binding) = match binding with - | SynBinding (trivia = trivia; range = range) when range = symbolUse.Range -> - trivia.EqualsRange - | _ -> defaultTraverse binding - } - SyntaxTraversal.Traverse(symbolUse.Range.End, parseFileResults.ParseTree, visitor) - - - member _.isValidForReturnTypeHint (symbolUse: FSharpSymbolUse) = - - - let adjustedRangeStart = - - symbolUse.Range.Start + // Skip lambdas + | SynBinding(expr = SynExpr.Lambda _) -> defaultTraverse binding - let isNotAnnotatedManually = - not (parseFileResults.IsTypeAnnotationGivenAtPosition adjustedRangeStart) + // Let binding + | SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range; returnInfo = None) when + range.Start = symbolUse.Range.Start + -> + Some equalsRange.StartRange - let isNotAfterDot = symbolUse.IsFromDefinition && not symbol.IsMemberThisValue + // Member binding + | SynBinding (headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = _ :: ident :: _)) + trivia = { EqualsRange = Some equalsRange } + returnInfo = None) when - let isNotTypeAlias = not symbol.IsConstructorThisValue + ident.idRange.Start = symbolUse.Range.Start + -> + Some equalsRange.StartRange - symbol.IsValue // we'll be adding other stuff gradually here - && isSolved - && isNotAnnotatedManually - && isNotAfterDot - && isNotTypeAlias - - member _.getHints (symbolUse: FSharpSymbolUse) = [ - if symbol.IsFunction && isSolved then - - match findBindingEqualsPosition symbolUse with - | Some equalsRange -> - - let _adjustedRangeStart = equalsRange.Start - - getHint symbolUse - | None -> () - - ] \ No newline at end of file + | _ -> defaultTraverse binding + } + ) + + member _.getHints symbolUse = + [ + if symbol.IsFunction && isSolved then + yield! + findEqualsPositionIfValid symbolUse + |> Option.bind (getHint symbolUse) + |> Option.toList + ] diff --git a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs index 1a99870b730..2a980b3eea9 100644 --- a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs +++ b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs @@ -105,6 +105,7 @@ type AdvancedOptions = IsOutliningEnabled: bool IsInlineTypeHintsEnabled: bool IsInlineParameterNameHintsEnabled: bool + IsReturnTypeHintsEnabled: bool IsLiveBuffersEnabled: bool } @@ -114,6 +115,7 @@ type AdvancedOptions = IsOutliningEnabled = true IsInlineTypeHintsEnabled = false IsInlineParameterNameHintsEnabled = false + IsReturnTypeHintsEnabled = false IsLiveBuffersEnabled = FSharpExperimentalFeaturesEnabledAutomatically } diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf index 0135d1c95ad..a831bef879f 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf index d12cfa34972..f93b21f57af 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf index 759070b96e7..433fe605418 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf index 1094b4529c3..bd0c4c69881 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf index 0081e0ab572..ece82b76af6 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf index 4dbe03a075b..688ad3123f0 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf index e2d8d933197..a01fcb2e77f 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf index 355dbae447f..39618f26945 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf index 794f33d932f..940c53b43a5 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf index 2759af321cf..0a5b668279e 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf index 69dec9a44ff..eb8a524241d 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf index 75fce885f81..aa70f9bf92c 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf index 3a689f3b68f..0002b466f32 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf @@ -182,14 +182,16 @@ Cache parsing results (experimental) Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; Dot underline; Dash underline; Formatting; -Maximum description width in characters; +Preferred description width in characters; +Format signature to the given width by adding line breaks conforming with F# syntax rules; Navigation links; Show navigation links as; Solid underline; diff --git a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml index ad43ae05717..941da20c080 100644 --- a/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml +++ b/vsintegration/src/FSharp.UIResources/AdvancedOptionsControl.xaml @@ -28,6 +28,8 @@ + diff --git a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs index c4712eb66bd..1cafe38a4f0 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs +++ b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs @@ -402,6 +402,15 @@ public static string Show_Outlining { } } + /// + /// Looks up a localized string similar to Display return type hints (preview). + /// + public static string Show_Return_Type_Hints { + get { + return ResourceManager.GetString("Show_Return_Type_Hints", resourceCulture); + } + } + /// /// Looks up a localized string similar to Simplify names (remove unnecessary qualifiers). /// diff --git a/vsintegration/src/FSharp.UIResources/Strings.resx b/vsintegration/src/FSharp.UIResources/Strings.resx index 1140a72b7ed..8036c30d271 100644 --- a/vsintegration/src/FSharp.UIResources/Strings.resx +++ b/vsintegration/src/FSharp.UIResources/Strings.resx @@ -261,4 +261,7 @@ Format signature to the given width by adding line breaks conforming with F# syntax rules. + + Display return type hints (preview) + \ No newline at end of file diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf index 89780f6d6b6..2dfde6a2550 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf @@ -107,6 +107,11 @@ Zobrazení tipů pro vložený typ (experimentální) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Zobrazit s_ymboly v neotevřených oborech názvů diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf index 7451bd7fe2c..cdf2b9f5c09 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf @@ -107,6 +107,11 @@ Hinweise für Inlinetypen anzeigen (experimentell) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces S_ymbole in nicht geöffneten Namespaces anzeigen diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf index f2e1721854a..44ad67c73ba 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf @@ -107,6 +107,11 @@ Mostrar sugerencias de tipo insertadas (experimental) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Mostrar sím_bolos en espacios de nombres sin abrir diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf index e78bbcf8d1c..d3b296e2819 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf @@ -107,6 +107,11 @@ Afficher les indicateurs de type inline (expérimental) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Afficher les sym_boles dans les espaces de noms non ouverts diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf index 0f34e28dd06..d84dafc3a4e 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf @@ -107,6 +107,11 @@ Visualizzare suggerimenti di tipo inline (sperimentale) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Mostra si_mboli in spazi dei nomi non aperti diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf index 7e1eb91b4ea..562f2cdc5c2 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf @@ -107,6 +107,11 @@ インライン型のヒントを表示する (試験段階) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces 開かれていない名前空間の記号を表示する(_Y) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf index 67a4dacb312..1683801a804 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf @@ -107,6 +107,11 @@ 인라인 유형 힌트 표시(실험적) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces 열려 있지 않은 네임스페이스에 기호 표시(_Y) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf index 7ca1c623135..e9675edcebb 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf @@ -107,6 +107,11 @@ Wyświetl wskazówki typu wbudowanego (eksperymentalne) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Pokaż s_ymbole w nieotwartych przestrzeniach nazw diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf index 5ded3335b0e..f73b5f2db4b 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf @@ -107,6 +107,11 @@ Exibir as dicas de tipo embutido (experimental) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Mostrar s_ímbolos em namespaces não abertos diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf index a7f235c094e..3a3446d4e37 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf @@ -107,6 +107,11 @@ Отображать подсказки для встроенных типов (экспериментальная версия) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces По_казать символы в неоткрытых пространствах имен diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf index 9ed15c7345b..7ec9e13dc70 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf @@ -107,6 +107,11 @@ Satır içi tür ipuçlarını göster (deneysel) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces Açılmamış ad alanlarında s_embolleri göster diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf index 88c45e47255..b86ac50201d 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf @@ -107,6 +107,11 @@ 显示内联类型提示(实验性) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces 显示未打开的命名空间中的符号(_Y) diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf index a6a50c29ded..59099520d0e 100644 --- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf +++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf @@ -107,6 +107,11 @@ 顯示內嵌類型提示 (實驗性) + + Display return type hints (preview) + Display return type hints (preview) + + Show s_ymbols in unopened namespaces 顯示未開啟之命名空間中的符號(_Y) diff --git a/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj b/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj index 889ede04813..a33516f185c 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj +++ b/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj @@ -34,6 +34,7 @@ + diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs index 6be45304e24..4717e0f9e65 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/HintTestFramework.fs @@ -64,14 +64,16 @@ module HintTestFramework = |> Async.RunSynchronously let getTypeHints document = - getHints document (Set.empty.Add(HintKind.TypeHint)) + getHints document (set [ HintKind.TypeHint ]) let getReturnTypeHints document = - getHints document (Set.empty.Add(HintKind.ReturnTypeHint)) + getHints document (set [ HintKind.ReturnTypeHint ]) let getParameterNameHints document = - getHints document (Set.empty.Add(HintKind.ParameterNameHint)) + getHints document (set [ HintKind.ParameterNameHint ]) let getAllHints document = - let hintKinds = Set.empty.Add(HintKind.TypeHint).Add(HintKind.ParameterNameHint) + let hintKinds = + set [ HintKind.TypeHint; HintKind.ParameterNameHint; HintKind.ReturnTypeHint ] + getHints document hintKinds diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs index 19fb12ccb19..d995223fbd3 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineTypeHintTests.fs @@ -185,21 +185,6 @@ let zip4 (l1: 'a list) (l2: 'b list) (l3: 'c list) (l4: 'd list) = actual |> Assert.shouldBeEquivalentTo expected - [] - let ``Hints are shown for let-bound function return types`` () = - let code = - """ - let func () = 3 - let func2 x = x + 1 - let setConsoleOut = System.Console.SetOut - """ - - let document = getFsDocument code - - let result = getReturnTypeHints document - - Assert.Empty(result) - [] let ``Hints are not shown for lambda return types`` () = let code = diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/OverallHintExperienceTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/OverallHintExperienceTests.fs index 187cf1c89e9..c6c85d9decc 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/OverallHintExperienceTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/OverallHintExperienceTests.fs @@ -26,7 +26,7 @@ let a = Square 1 let b = Rectangle (1, 2) type C (blahFirst: int) = - member _.Normal (what: string) = 1 + member _.Normal (what: string) = 1 let a = C 1 let cc = a.Normal "hmm" @@ -40,6 +40,10 @@ let cc = a.Normal "hmm" Content = ": Song" Location = (2, 18) } + { + Content = ": string " + Location = (2, 19) + } { Content = "song = " Location = (4, 23) @@ -68,6 +72,10 @@ let cc = a.Normal "hmm" Content = ": Shape" Location = (11, 6) } + { + Content = ": int " + Location = (14, 36) + } { Content = "blahFirst = " Location = (16, 11) diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs new file mode 100644 index 00000000000..660494955b7 --- /dev/null +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs @@ -0,0 +1,80 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module FSharp.Editor.Tests.Hints.ReturnTypeHintTests + +open Xunit +open HintTestFramework +open FSharp.Test + +[] +let ``Hints are shown for let-bound function return types`` () = + let code = + """ +let func () = 3 +let func2 x = x + 1 +let setConsoleOut = System.Console.SetOut +""" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + let expected = + [ + { + Content = ": int " + Location = (1, 13) + } + { + Content = ": int " + Location = (2, 13) + } + { + Content = ": unit " + Location = (3, 19) + } + ] + + Assert.Equal(expected, result) + +[] +let ``Hints are shown for method return types`` () = + let code = + """ +type Test() = + member this.Func() = 3 +""" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + let expected = + [ + { + Content = ": int " + Location = (2, 24) + } + ] + + Assert.Equal(expected, result) + +[] +let ``Hints are not shown for lambda bindings`` () = + let code = "let func = fun () -> 3" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + Assert.Empty result + +[] +let ``Hints are not shown when there's type annotation`` () = + let code = "let func x : int = x" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + Assert.Empty result From bbbfbad3924f31400f133786468314c702e14680 Mon Sep 17 00:00:00 2001 From: Petr Pokorny Date: Wed, 29 Mar 2023 16:56:41 +0200 Subject: [PATCH 03/12] Add search string --- vsintegration/src/FSharp.Editor/FSharp.Editor.resx | 1 + 1 file changed, 1 insertion(+) diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx index 505a8cf1629..53f3978cdb1 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.resx +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.resx @@ -224,6 +224,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking From 399d48356d305c90cc32c379c4a57119b37ca523 Mon Sep 17 00:00:00 2001 From: Petr Pokorny Date: Wed, 29 Mar 2023 18:13:26 +0200 Subject: [PATCH 04/12] Showing reutrn type hints for generic functions --- .../src/FSharp.Editor/Hints/InlineTypeHints.fs | 2 +- .../src/FSharp.Editor/Hints/ReturnTypeHints.fs | 5 +---- .../src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.de.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.es.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.it.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf | 2 ++ .../FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf | 2 ++ .../src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf | 2 ++ .../xlf/FSharp.Editor.zh-Hans.xlf | 2 ++ .../xlf/FSharp.Editor.zh-Hant.xlf | 2 ++ .../Hints/ReturnTypeHintTests.fs | 18 ++++++++++++++++++ 16 files changed, 46 insertions(+), 5 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs index 707a25cfb35..94aba509bc5 100644 --- a/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/InlineTypeHints.fs @@ -28,7 +28,7 @@ module InlineTypeHints = Parts = getHintParts symbol symbolUse } - let isSolved (symbol: FSharpMemberOrFunctionOrValue) = + let private isSolved (symbol: FSharpMemberOrFunctionOrValue) = if symbol.GenericParameters.Count > 0 then symbol.GenericParameters |> Seq.forall (fun p -> p.IsSolveAtCompileTime) diff --git a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs index 209e4563975..c3b00b2128c 100644 --- a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs @@ -8,7 +8,6 @@ open FSharp.Compiler.Symbols open FSharp.Compiler.Syntax open FSharp.Compiler.Text open Hints -open InlineTypeHints type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMemberOrFunctionOrValue) = @@ -30,8 +29,6 @@ type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMem Parts = parts }) - let isSolved = isSolved symbol - let findEqualsPositionIfValid (symbolUse: FSharpSymbolUse) = SyntaxTraversal.Traverse( symbolUse.Range.End, @@ -63,7 +60,7 @@ type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMem member _.getHints symbolUse = [ - if symbol.IsFunction && isSolved then + if symbol.IsFunction then yield! findEqualsPositionIfValid symbolUse |> Option.bind (getHint symbolUse) diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf index a831bef879f..2014501b2e8 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf index f93b21f57af..96428fd3af5 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf index 433fe605418..a9f0793da07 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf index bd0c4c69881..e5a2fcf6e58 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf index ece82b76af6..516179e8057 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf index 688ad3123f0..925baddcb25 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf index a01fcb2e77f..35912d93aac 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf index 39618f26945..ee3dafd4a3c 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf index 940c53b43a5..96dba0bfd1f 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf index 0a5b668279e..56a1271598a 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf index eb8a524241d..486d2a886a6 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf index aa70f9bf92c..8d10219c3db 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hans.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf index 0002b466f32..4c4764fa3a4 100644 --- a/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf +++ b/vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.zh-Hant.xlf @@ -34,6 +34,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking @@ -43,6 +44,7 @@ Outlining; Show outlining and collapsible nodes for F# code; Inline hints; Display inline type hints (preview); +Display return type hints (preview); Display inline parameter name hints (preview);Beer; Live Buffers; Use live (unsaved) buffers for checking diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs index 660494955b7..5f7e2e8cd2b 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs @@ -59,6 +59,24 @@ type Test() = Assert.Equal(expected, result) +[] +let ``Hints are shown for generic functions`` () = + let code = "let func _a = 5" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + let expected = + [ + { + Content = ": int " + Location = (0, 13) + } + ] + + Assert.Equal(expected, result) + [] let ``Hints are not shown for lambda bindings`` () = let code = "let func = fun () -> 3" From 6d5580a4c49407952d372aea0f97a47ac31c999b Mon Sep 17 00:00:00 2001 From: Petr Pokorny Date: Wed, 29 Mar 2023 18:21:37 +0200 Subject: [PATCH 05/12] clarification --- .../src/FSharp.Editor/Hints/ReturnTypeHints.fs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs index c3b00b2128c..8c9f868b447 100644 --- a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs +++ b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs @@ -37,21 +37,18 @@ type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMem override _.VisitBinding(_path, defaultTraverse, binding) = match binding with // Skip lambdas - | SynBinding(expr = SynExpr.Lambda _) -> defaultTraverse binding + | SynBinding(expr = SynExpr.Lambda _) + + // Skip manually type-annotated bindings + | SynBinding(returnInfo = Some (SynBindingReturnInfo(typeName = SynType.LongIdent _))) -> defaultTraverse binding // Let binding - | SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range; returnInfo = None) when - range.Start = symbolUse.Range.Start - -> + | SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range) when range.Start = symbolUse.Range.Start -> Some equalsRange.StartRange // Member binding | SynBinding (headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = _ :: ident :: _)) - trivia = { EqualsRange = Some equalsRange } - returnInfo = None) when - - ident.idRange.Start = symbolUse.Range.Start - -> + trivia = { EqualsRange = Some equalsRange }) when ident.idRange.Start = symbolUse.Range.Start -> Some equalsRange.StartRange | _ -> defaultTraverse binding From 27d08b0f52d18fcb7b861a24b8d0d25513cb9824 Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 11:34:28 +0200 Subject: [PATCH 06/12] review feedback --- .../Service/FSharpParseFileResults.fs | 27 ++++++++ .../Service/FSharpParseFileResults.fsi | 4 ++ .../src/FSharp.Editor/FSharp.Editor.fsproj | 2 +- .../src/FSharp.Editor/Hints/HintService.fs | 2 +- .../Hints/InlineReturnTypeHints.fs | 38 +++++++++++ .../FSharp.Editor/Hints/ReturnTypeHints.fs | 65 ------------------- .../FSharp.Editor.Tests.fsproj | 2 +- ...tTests.fs => InlineReturnTypeHintTests.fs} | 2 +- 8 files changed, 73 insertions(+), 69 deletions(-) create mode 100644 vsintegration/src/FSharp.Editor/Hints/InlineReturnTypeHints.fs delete mode 100644 vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs rename vsintegration/tests/FSharp.Editor.Tests/Hints/{ReturnTypeHintTests.fs => InlineReturnTypeHintTests.fs} (97%) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index 2cb1110b76a..14a4b9b47c4 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -398,6 +398,33 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, SyntaxTraversal.Traverse(expressionPos, input, visitor) + member _.TryRangeOfReturnTypeHint(symbolUseStart: pos, ?skipLambdas) = + let skipLambdas = defaultArg skipLambdas true + + SyntaxTraversal.Traverse( + symbolUseStart, + input, + { new SyntaxVisitorBase<_>() with + override _.VisitBinding(_path, defaultTraverse, binding) = + match binding with + | SynBinding(expr = SynExpr.Lambda _) when skipLambdas -> defaultTraverse binding + + // Skip manually type-annotated bindings + | SynBinding(returnInfo = Some (SynBindingReturnInfo(typeName = SynType.LongIdent _))) -> defaultTraverse binding + + // Let binding + | SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range) when range.Start = symbolUseStart -> + Some equalsRange.StartRange + + // Member binding + | SynBinding (headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = _ :: ident :: _)) + trivia = { EqualsRange = Some equalsRange }) when ident.idRange.Start = symbolUseStart -> + Some equalsRange.StartRange + + | _ -> defaultTraverse binding + } + ) + member _.FindParameterLocations pos = ParameterLocations.Find(pos, input) member _.IsPositionContainedInACurriedParameter pos = diff --git a/src/Compiler/Service/FSharpParseFileResults.fsi b/src/Compiler/Service/FSharpParseFileResults.fsi index e20de374d16..2d3918015c2 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fsi +++ b/src/Compiler/Service/FSharpParseFileResults.fsi @@ -52,6 +52,10 @@ type public FSharpParseFileResults = /// Gets the range of an expression being dereferenced. For `!expr`, gives the range of `expr` member TryRangeOfExpressionBeingDereferencedContainingPos: expressionPos: pos -> range option + /// Gets the range of where a return type hint could be placed for a function binding. This will be right in front of the equals sign. + /// Returns None if type annotation is present. + member TryRangeOfReturnTypeHint: symbolUseStart: pos * ?skipLambdas: bool -> range option + /// Notable parse info for ParameterInfo at a given location member FindParameterLocations: pos: pos -> ParameterLocations option diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj index 80a90a90c2a..6ba152f9233 100644 --- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj +++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj @@ -137,7 +137,7 @@ - + diff --git a/vsintegration/src/FSharp.Editor/Hints/HintService.fs b/vsintegration/src/FSharp.Editor/Hints/HintService.fs index 68fb91fd130..d83b182348d 100644 --- a/vsintegration/src/FSharp.Editor/Hints/HintService.fs +++ b/vsintegration/src/FSharp.Editor/Hints/HintService.fs @@ -18,7 +18,7 @@ module HintService = >> Seq.collect (InlineTypeHints.getHints symbol) let inline private getReturnTypeHints parseResults symbol = - Seq.collect (ReturnTypeHints(parseResults, symbol).getHints) + Seq.collect (InlineReturnTypeHints(parseResults, symbol).getHints) let inline private getHintsForMemberOrFunctionOrValue (sourceText: SourceText) parseResults symbol : NativeHintResolver = Seq.filter (InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol) diff --git a/vsintegration/src/FSharp.Editor/Hints/InlineReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/InlineReturnTypeHints.fs new file mode 100644 index 00000000000..f9152c6e88e --- /dev/null +++ b/vsintegration/src/FSharp.Editor/Hints/InlineReturnTypeHints.fs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Microsoft.VisualStudio.FSharp.Editor.Hints + +open Microsoft.VisualStudio.FSharp.Editor +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.Text +open Hints + +type InlineReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMemberOrFunctionOrValue) = + + let getHintParts (symbolUse: FSharpSymbolUse) = + symbol.GetReturnTypeLayout symbolUse.DisplayContext + |> Option.map (fun typeInfo -> + [ + TaggedText(TextTag.Text, ": ") + yield! typeInfo |> Array.toList + TaggedText(TextTag.Space, " ") + ]) + + let getHint symbolUse range = + getHintParts symbolUse + |> Option.map (fun parts -> + { + Kind = HintKind.ReturnTypeHint + Range = range + Parts = parts + }) + + member _.getHints(symbolUse: FSharpSymbolUse) = + [ + if symbol.IsFunction then + yield! + parseFileResults.TryRangeOfReturnTypeHint symbolUse.Range.Start + |> Option.bind (getHint symbolUse) + |> Option.toList + ] diff --git a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs b/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs deleted file mode 100644 index 8c9f868b447..00000000000 --- a/vsintegration/src/FSharp.Editor/Hints/ReturnTypeHints.fs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -namespace Microsoft.VisualStudio.FSharp.Editor.Hints - -open Microsoft.VisualStudio.FSharp.Editor -open FSharp.Compiler.CodeAnalysis -open FSharp.Compiler.Symbols -open FSharp.Compiler.Syntax -open FSharp.Compiler.Text -open Hints - -type ReturnTypeHints(parseFileResults: FSharpParseFileResults, symbol: FSharpMemberOrFunctionOrValue) = - - let getHintParts (symbolUse: FSharpSymbolUse) = - symbol.GetReturnTypeLayout symbolUse.DisplayContext - |> Option.map (fun typeInfo -> - [ - TaggedText(TextTag.Text, ": ") - yield! typeInfo |> Array.toList - TaggedText(TextTag.Space, " ") - ]) - - let getHint symbolUse range = - getHintParts symbolUse - |> Option.map (fun parts -> - { - Kind = HintKind.ReturnTypeHint - Range = range - Parts = parts - }) - - let findEqualsPositionIfValid (symbolUse: FSharpSymbolUse) = - SyntaxTraversal.Traverse( - symbolUse.Range.End, - parseFileResults.ParseTree, - { new SyntaxVisitorBase<_>() with - override _.VisitBinding(_path, defaultTraverse, binding) = - match binding with - // Skip lambdas - | SynBinding(expr = SynExpr.Lambda _) - - // Skip manually type-annotated bindings - | SynBinding(returnInfo = Some (SynBindingReturnInfo(typeName = SynType.LongIdent _))) -> defaultTraverse binding - - // Let binding - | SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range) when range.Start = symbolUse.Range.Start -> - Some equalsRange.StartRange - - // Member binding - | SynBinding (headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = _ :: ident :: _)) - trivia = { EqualsRange = Some equalsRange }) when ident.idRange.Start = symbolUse.Range.Start -> - Some equalsRange.StartRange - - | _ -> defaultTraverse binding - } - ) - - member _.getHints symbolUse = - [ - if symbol.IsFunction then - yield! - findEqualsPositionIfValid symbolUse - |> Option.bind (getHint symbolUse) - |> Option.toList - ] diff --git a/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj b/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj index a33516f185c..9fe2d265ade 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj +++ b/vsintegration/tests/FSharp.Editor.Tests/FSharp.Editor.Tests.fsproj @@ -34,7 +34,7 @@ - + diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs similarity index 97% rename from vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs rename to vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs index 5f7e2e8cd2b..4fd571e0493 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/ReturnTypeHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -module FSharp.Editor.Tests.Hints.ReturnTypeHintTests +module FSharp.Editor.Tests.Hints.InlineReturnTypeHintTests open Xunit open HintTestFramework From 6b7af7242011021d5a9a560426dd17f309f4e040 Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 11:52:28 +0200 Subject: [PATCH 07/12] telemetry --- vsintegration/src/FSharp.Editor/Hints/OptionParser.fs | 2 +- .../src/FSharp.Editor/LanguageService/LanguageService.fs | 3 +++ vsintegration/src/FSharp.Editor/Options/EditorOptions.fs | 4 ++-- .../src/FSharp.UIResources/AdvancedOptionsControl.xaml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs index 28858627bf3..4b318490111 100644 --- a/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs +++ b/vsintegration/src/FSharp.Editor/Hints/OptionParser.fs @@ -16,6 +16,6 @@ module OptionParser = if options.IsInlineParameterNameHintsEnabled then HintKind.ParameterNameHint - if options.IsReturnTypeHintsEnabled then + if options.IsInlineReturnTypeHintsEnabled then HintKind.ReturnTypeHint ] diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs index e83dcbacaf7..d5743953124 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs @@ -137,6 +137,8 @@ type internal FSharpWorkspaceServiceFactory [ - From ebe314f383cc3c764cf6acb147843cdb5d2bca8d Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 11:59:54 +0200 Subject: [PATCH 08/12] fantomas --- .../src/FSharp.Editor/LanguageService/LanguageService.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs index d5743953124..0b51e1c7818 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs @@ -137,7 +137,8 @@ type internal FSharpWorkspaceServiceFactory [ Date: Thu, 30 Mar 2023 12:29:08 +0200 Subject: [PATCH 09/12] Hints are shown for functions within expressions --- .../Service/FSharpParseFileResults.fs | 2 ++ .../Hints/InlineReturnTypeHintTests.fs | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index 14a4b9b47c4..3589c79f0d8 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -405,6 +405,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, symbolUseStart, input, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = defaultTraverse expr + override _.VisitBinding(_path, defaultTraverse, binding) = match binding with | SynBinding(expr = SynExpr.Lambda _) when skipLambdas -> defaultTraverse binding diff --git a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs index 4fd571e0493..48f838f9e8a 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/Hints/InlineReturnTypeHintTests.fs @@ -77,6 +77,28 @@ let ``Hints are shown for generic functions`` () = Assert.Equal(expected, result) +[] +let ``Hints are shown for functions within expressions`` () = + let code = + """ + let _ = + let func () = 2 +""" + + let document = getFsDocument code + + let result = getReturnTypeHints document + + let expected = + [ + { + Content = ": int " + Location = (2, 21) + } + ] + + Assert.Equal(expected, result) + [] let ``Hints are not shown for lambda bindings`` () = let code = "let func = fun () -> 3" From 420b727c381caca40a08b0c68b9dee443bd820b8 Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 12:33:32 +0200 Subject: [PATCH 10/12] remove empty hint parts filtering --- vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs index 82969d335b0..53820400d94 100644 --- a/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs +++ b/vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs @@ -33,9 +33,7 @@ type internal RoslynAdapter [] (settings: EditorOptions) = let! nativeHints = HintService.getHintsForDocument sourceText document hintKinds userOpName cancellationToken let roslynHints = - nativeHints - |> Seq.filter (fun hint -> not hint.Parts.IsEmpty) - |> Seq.map (NativeToRoslynHintConverter.convert sourceText) + nativeHints |> Seq.map (NativeToRoslynHintConverter.convert sourceText) return roslynHints.ToImmutableArray() } From 9d9db91ba9f06fd169daf260c97dbea31f21f318 Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 14:26:42 +0200 Subject: [PATCH 11/12] update surfacearea --- .../FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 86a216e066b..5cf10db4690 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -2091,6 +2091,7 @@ FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FShar FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfNameOfNearestOuterBindingContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRecordExpressionContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRefCellDereferenceContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfReturnTypeHint(FSharp.Compiler.Text.Position, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfStringInterpolationContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ValidateBreakpointLocation(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] GetAllArgumentsForFunctionApplicationAtPosition(FSharp.Compiler.Text.Position) From a17d1c3a4af6074efad19cf21dc447b469804573 Mon Sep 17 00:00:00 2001 From: 0101 <0101@innit.cz> Date: Thu, 30 Mar 2023 15:21:29 +0200 Subject: [PATCH 12/12] update surfacearea --- ...FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 86a216e066b..5cf10db4690 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -2091,6 +2091,7 @@ FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FShar FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfNameOfNearestOuterBindingContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRecordExpressionContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRefCellDereferenceContainingPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfReturnTypeHint(FSharp.Compiler.Text.Position, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfStringInterpolationContainingPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ValidateBreakpointLocation(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] GetAllArgumentsForFunctionApplicationAtPosition(FSharp.Compiler.Text.Position)