Skip to content

Commit 4a25a87

Browse files
dotnet-bot0101KevinRansom
authored
Merge main to release/dev17.6 (#15010)
* Fix parameter name hints crashing with multi-line arguments (#15004) * Return type hints (#14998) --------- Co-authored-by: Petr Pokorny <[email protected]> Co-authored-by: Kevin Ransom (msft) <[email protected]>
1 parent 399389c commit 4a25a87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+407
-55
lines changed

src/Compiler/Service/FSharpParseFileResults.fs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,35 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
398398

399399
SyntaxTraversal.Traverse(expressionPos, input, visitor)
400400

401+
member _.TryRangeOfReturnTypeHint(symbolUseStart: pos, ?skipLambdas) =
402+
let skipLambdas = defaultArg skipLambdas true
403+
404+
SyntaxTraversal.Traverse(
405+
symbolUseStart,
406+
input,
407+
{ new SyntaxVisitorBase<_>() with
408+
member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = defaultTraverse expr
409+
410+
override _.VisitBinding(_path, defaultTraverse, binding) =
411+
match binding with
412+
| SynBinding(expr = SynExpr.Lambda _) when skipLambdas -> defaultTraverse binding
413+
414+
// Skip manually type-annotated bindings
415+
| SynBinding(returnInfo = Some (SynBindingReturnInfo(typeName = SynType.LongIdent _))) -> defaultTraverse binding
416+
417+
// Let binding
418+
| SynBinding (trivia = { EqualsRange = Some equalsRange }; range = range) when range.Start = symbolUseStart ->
419+
Some equalsRange.StartRange
420+
421+
// Member binding
422+
| SynBinding (headPat = SynPat.LongIdent(longDotId = SynLongIdent(id = _ :: ident :: _))
423+
trivia = { EqualsRange = Some equalsRange }) when ident.idRange.Start = symbolUseStart ->
424+
Some equalsRange.StartRange
425+
426+
| _ -> defaultTraverse binding
427+
}
428+
)
429+
401430
member _.FindParameterLocations pos = ParameterLocations.Find(pos, input)
402431

403432
member _.IsPositionContainedInACurriedParameter pos =

src/Compiler/Service/FSharpParseFileResults.fsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ type public FSharpParseFileResults =
5252
/// Gets the range of an expression being dereferenced. For `!expr`, gives the range of `expr`
5353
member TryRangeOfExpressionBeingDereferencedContainingPos: expressionPos: pos -> range option
5454

55+
/// 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.
56+
/// Returns None if type annotation is present.
57+
member TryRangeOfReturnTypeHint: symbolUseStart: pos * ?skipLambdas: bool -> range option
58+
5559
/// Notable parse info for ParameterInfo at a given location
5660
member FindParameterLocations: pos: pos -> ParameterLocations option
5761

src/Compiler/Symbols/Symbols.fs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,24 +2331,20 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
23312331
|> LayoutRender.toArray
23322332

23332333
member x.GetReturnTypeLayout (displayContext: FSharpDisplayContext) =
2334-
match x.IsMember, d with
2335-
| true, _ ->
2336-
None
2337-
| false, _ ->
2338-
checkIsResolved()
2339-
match d with
2340-
| E _
2341-
| P _
2342-
| C _ -> None
2343-
| M m ->
2344-
let retTy = m.GetFSharpReturnType(cenv.amap, range0, m.FormalMethodInst)
2345-
NicePrint.layoutType (displayContext.Contents cenv.g) retTy
2346-
|> LayoutRender.toArray
2347-
|> Some
2348-
| V v ->
2349-
NicePrint.layoutOfValReturnType (displayContext.Contents cenv.g) v
2350-
|> LayoutRender.toArray
2351-
|> Some
2334+
checkIsResolved()
2335+
match d with
2336+
| E _
2337+
| P _
2338+
| C _ -> None
2339+
| M m ->
2340+
let retTy = m.GetFSharpReturnType(cenv.amap, range0, m.FormalMethodInst)
2341+
NicePrint.layoutType (displayContext.Contents cenv.g) retTy
2342+
|> LayoutRender.toArray
2343+
|> Some
2344+
| V v ->
2345+
NicePrint.layoutOfValReturnType (displayContext.Contents cenv.g) v
2346+
|> LayoutRender.toArray
2347+
|> Some
23522348

23532349
member x.GetWitnessPassingInfo() =
23542350
let witnessInfos =

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,7 @@ FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FShar
20912091
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfNameOfNearestOuterBindingContainingPos(FSharp.Compiler.Text.Position)
20922092
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRecordExpressionContainingPos(FSharp.Compiler.Text.Position)
20932093
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRefCellDereferenceContainingPos(FSharp.Compiler.Text.Position)
2094+
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])
20942095
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfStringInterpolationContainingPos(FSharp.Compiler.Text.Position)
20952096
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ValidateBreakpointLocation(FSharp.Compiler.Text.Position)
20962097
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] GetAllArgumentsForFunctionApplicationAtPosition(FSharp.Compiler.Text.Position)

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,7 @@ FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FShar
20912091
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfNameOfNearestOuterBindingContainingPos(FSharp.Compiler.Text.Position)
20922092
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRecordExpressionContainingPos(FSharp.Compiler.Text.Position)
20932093
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfRefCellDereferenceContainingPos(FSharp.Compiler.Text.Position)
2094+
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])
20942095
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] TryRangeOfStringInterpolationContainingPos(FSharp.Compiler.Text.Position)
20952096
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ValidateBreakpointLocation(FSharp.Compiler.Text.Position)
20962097
FSharp.Compiler.CodeAnalysis.FSharpParseFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range]] GetAllArgumentsForFunctionApplicationAtPosition(FSharp.Compiler.Text.Position)

vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
<Compile Include="AutomaticCompletion\BraceCompletionSessionProvider.fs" />
138138
<Compile Include="Hints\Hints.fs" />
139139
<Compile Include="Hints\InlineTypeHints.fs" />
140+
<Compile Include="hints\InlineReturnTypeHints.fs" />
140141
<Compile Include="Hints\InlineParameterNameHints.fs" />
141142
<Compile Include="Hints\HintService.fs" />
142143
<Compile Include="Hints\NativeToRoslynHintConverter.fs" />

vsintegration/src/FSharp.Editor/FSharp.Editor.resx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ Outlining;
224224
Show outlining and collapsible nodes for F# code;
225225
Inline hints;
226226
Display inline type hints (preview);
227+
Display return type hints (preview);
227228
Display inline parameter name hints (preview);Beer;
228229
Live Buffers;
229230
Use live (unsaved) buffers for checking</value>

vsintegration/src/FSharp.Editor/Hints/HintService.fs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ module HintService =
1717
Seq.filter (InlineTypeHints.isValidForHint parseResults symbol)
1818
>> Seq.collect (InlineTypeHints.getHints symbol)
1919

20+
let inline private getReturnTypeHints parseResults symbol =
21+
Seq.collect (InlineReturnTypeHints(parseResults, symbol).getHints)
22+
2023
let inline private getHintsForMemberOrFunctionOrValue (sourceText: SourceText) parseResults symbol : NativeHintResolver =
2124
Seq.filter (InlineParameterNameHints.isMemberOrFunctionOrValueValidForHint symbol)
2225
>> Seq.collect (InlineParameterNameHints.getHintsForMemberOrFunctionOrValue sourceText parseResults symbol)
@@ -35,6 +38,10 @@ module HintService =
3538
match symbol with
3639
| :? FSharpMemberOrFunctionOrValue as symbol -> getTypeHints parseResults symbol |> Some
3740
| _ -> None
41+
| HintKind.ReturnTypeHint ->
42+
match symbol with
43+
| :? FSharpMemberOrFunctionOrValue as symbol -> getReturnTypeHints parseResults symbol |> Some
44+
| _ -> None
3845
| HintKind.ParameterNameHint ->
3946
match symbol with
4047
| :? FSharpMemberOrFunctionOrValue as symbol ->
@@ -45,7 +52,7 @@ module HintService =
4552
:: resolvers
4653
|> resolve hintKinds
4754

48-
in resolve hintKinds []
55+
resolve hintKinds []
4956

5057
let private getHintsForSymbol (sourceText: SourceText) parseResults hintKinds (symbol: FSharpSymbol, symbolUses: FSharpSymbolUse seq) =
5158
symbol

vsintegration/src/FSharp.Editor/Hints/Hints.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Hints =
99
type HintKind =
1010
| TypeHint
1111
| ParameterNameHint
12+
| ReturnTypeHint
1213

1314
// Relatively convenient for testing
1415
type NativeHint =
@@ -22,3 +23,4 @@ module Hints =
2223
match kind with
2324
| TypeHint -> "type"
2425
| ParameterNameHint -> "parameterName"
26+
| ReturnTypeHint -> "returnType"

vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ open FSharp.Compiler.EditorServices
99
open FSharp.Compiler.Symbols
1010
open FSharp.Compiler.Text
1111
open Hints
12+
open Microsoft.VisualStudio.FSharp.Editor
1213

1314
module InlineParameterNameHints =
1415

@@ -56,10 +57,8 @@ module InlineParameterNameHints =
5657
>> Seq.contains range
5758

5859
let private getSourceTextAtRange (sourceText: SourceText) (range: range) =
59-
60-
let line = sourceText.Lines[ range.Start.Line - 1 ].ToString()
61-
let length = range.EndColumn - range.StartColumn
62-
line.Substring(range.Start.Column, length)
60+
(RoslynHelpers.FSharpRangeToTextSpan(sourceText, range) |> sourceText.GetSubText)
61+
.ToString()
6362

6463
let isMemberOrFunctionOrValueValidForHint (symbol: FSharpMemberOrFunctionOrValue) (symbolUse: FSharpSymbolUse) =
6564

0 commit comments

Comments
 (0)