Skip to content

Return type hints #14998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/Compiler/Service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,35 @@ 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
member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = defaultTraverse expr

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 =
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Service/FSharpParseFileResults.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
32 changes: 14 additions & 18 deletions src/Compiler/Symbols/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
<Compile Include="AutomaticCompletion\BraceCompletionSessionProvider.fs" />
<Compile Include="Hints\Hints.fs" />
<Compile Include="Hints\InlineTypeHints.fs" />
<Compile Include="hints\InlineReturnTypeHints.fs" />
<Compile Include="Hints\InlineParameterNameHints.fs" />
<Compile Include="Hints\HintService.fs" />
<Compile Include="Hints\NativeToRoslynHintConverter.fs" />
Expand Down
1 change: 1 addition & 0 deletions vsintegration/src/FSharp.Editor/FSharp.Editor.resx
Original file line number Diff line number Diff line change
Expand Up @@ -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</value>
Expand Down
9 changes: 8 additions & 1 deletion vsintegration/src/FSharp.Editor/Hints/HintService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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 (InlineReturnTypeHints(parseResults, symbol).getHints)

let inline private getHintsForMemberOrFunctionOrValue (sourceText: SourceText) parseResults symbol : NativeHintResolver =
Seq.filter (InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol)
>> Seq.collect (InlineParameterNameHints.getHintsForMemberOrFunctionOrValue sourceText parseResults symbol)
Expand All @@ -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 ->
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/Hints/Hints.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Hints =
type HintKind =
| TypeHint
| ParameterNameHint
| ReturnTypeHint

// Relatively convenient for testing
type NativeHint =
Expand All @@ -22,3 +23,4 @@ module Hints =
match kind with
| TypeHint -> "type"
| ParameterNameHint -> "parameterName"
| ReturnTypeHint -> "returnType"
38 changes: 38 additions & 0 deletions vsintegration/src/FSharp.Editor/Hints/InlineReturnTypeHints.fs
Original file line number Diff line number Diff line change
@@ -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
]
3 changes: 3 additions & 0 deletions vsintegration/src/FSharp.Editor/Hints/OptionParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ module OptionParser =

if options.IsInlineParameterNameHintsEnabled then
HintKind.ParameterNameHint

if options.IsInlineReturnTypeHintsEnabled then
HintKind.ReturnTypeHint
]
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ type internal FSharpWorkspaceServiceFactory [<System.Composition.ImportingConstr

let isInlineTypeHintsEnabled = editorOptions.Advanced.IsInlineTypeHintsEnabled

let isInlineReturnTypeHintsEnabled =
editorOptions.Advanced.IsInlineReturnTypeHintsEnabled

let enablePartialTypeChecking =
editorOptions.LanguageServicePerformance.EnablePartialTypeChecking

Expand Down Expand Up @@ -169,6 +172,7 @@ type internal FSharpWorkspaceServiceFactory [<System.Composition.ImportingConstr
nameof enableFastFindReferences, enableFastFindReferences
nameof isInlineParameterNameHintsEnabled, isInlineParameterNameHintsEnabled
nameof isInlineTypeHintsEnabled, isInlineTypeHintsEnabled
nameof isInlineReturnTypeHintsEnabled, isInlineReturnTypeHintsEnabled
nameof enablePartialTypeChecking, enablePartialTypeChecking
]

Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/Options/EditorOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type AdvancedOptions =
IsOutliningEnabled: bool
IsInlineTypeHintsEnabled: bool
IsInlineParameterNameHintsEnabled: bool
IsInlineReturnTypeHintsEnabled: bool
IsLiveBuffersEnabled: bool
}

Expand All @@ -114,6 +115,7 @@ type AdvancedOptions =
IsOutliningEnabled = true
IsInlineTypeHintsEnabled = false
IsInlineParameterNameHintsEnabled = false
IsInlineReturnTypeHintsEnabled = false
IsLiveBuffersEnabled = FSharpExperimentalFeaturesEnabledAutomatically
}

Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
2 changes: 2 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -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</source>
Expand All @@ -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</target>
Expand Down
Loading