Skip to content

Commit

Permalink
Only show type hints for lambdas + tests + surface
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermp committed Oct 28, 2020
1 parent 6f616fe commit de05f68
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 6 deletions.
21 changes: 19 additions & 2 deletions src/fsharp/service/ServiceUntypedParse.fs
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,25 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: ParsedInput option
Some range
| _ -> defaultTraverse pat })
res.IsSome
| None ->
false
| None -> false

member scope.IsBindingALambda(pos) =
match input with
| Some parseTree ->
let res =
AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with
member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) =
defaultTraverse expr

override _.VisitBinding(defaultTraverse, binding) =
match binding with
| SynBinding.Binding(_, _, _, _, _, _, _, _, _, expr, range, _) when posEq range.Start pos ->
match expr with
| SynExpr.Lambda _ -> Some range
| _ -> None
| _ -> defaultTraverse binding })
res.IsSome
| None -> false

/// Get declared items and the selected item at the specified location
member private scope.GetNavigationItemsImpl() =
Expand Down
5 changes: 4 additions & 1 deletion src/fsharp/service/ServiceUntypedParse.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ type public FSharpParseFileResults =
// doot doot yeet yeet
member GetAllArgumentsForFunctionApplication: pos: pos -> range list option

// doot doot yeet yeet
// Determines if the expression or pattern at the given position has a type annotation
member IsTypeAnnotationGiven: pos -> bool

// Determines if the binding at a given position is a lambda expression
member IsBindingALambda: pos -> bool

/// Name of the file for which this information were created
member FileName: string

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22427,6 +22427,7 @@ FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsOver
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsProperty
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsPropertyGetterMethod
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsPropertySetterMethod
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsMethod
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsSetterMethod
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsTypeFunction
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean IsUnresolved
Expand Down Expand Up @@ -22461,6 +22462,7 @@ FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_Is
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsProperty()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsPropertyGetterMethod()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsPropertySetterMethod()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsMethod()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsSetterMethod()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsTypeFunction()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Boolean get_IsUnresolved()
Expand Down Expand Up @@ -22515,8 +22517,8 @@ FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collect
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.SourceCodeServices.FSharpGenericParameter] get_GenericParameters()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.SourceCodeServices.FSharpParameter]] CurriedParameterGroups
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.SourceCodeServices.FSharpParameter]] get_CurriedParameterGroups()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList1[System.String]] PossibleArgumentList
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList1[System.String]] get_PossibleArgumentList()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]] PossibleArgumentList
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]] get_PossibleArgumentList()
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.String] ElaboratedXmlDoc
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.String] XmlDoc
FSharp.Compiler.SourceCodeServices.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[System.String] get_ElaboratedXmlDoc()
Expand Down
47 changes: 47 additions & 0 deletions tests/service/ServiceUntypedParseTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,15 @@ let f (x: int) (y: string) = ()
Assert.IsTrue(parseFileResults.IsTypeAnnotationGiven (mkPos 2 7), "Expected annotation for argument 'x'")
Assert.IsTrue(parseFileResults.IsTypeAnnotationGiven (mkPos 2 16), "Expected annotation for argument 'y'")

[<Test>]
let ``IsTypeAnnotationGiven - lambda function - all args annotated``() =
let source = """
let f = fun (x: int) (y: string) -> ()
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsTrue(parseFileResults.IsTypeAnnotationGiven (mkPos 2 13), "Expected a annotation for argument 'x'")
Assert.IsTrue(parseFileResults.IsTypeAnnotationGiven (mkPos 2 22), "Expected a annotation for argument 'y'")

[<Test>]
let ``IsTypeAnnotationGiven - constuctor - arg no annotations``() =
let source = """
Expand Down Expand Up @@ -745,3 +754,41 @@ let (x, y: string) = (12, "hello")
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsFalse(parseFileResults.IsTypeAnnotationGiven (mkPos 2 5), "Expected no annotation for argument 'x'")
Assert.IsTrue(parseFileResults.IsTypeAnnotationGiven (mkPos 2 8), "Expected annotation for argument 'y'")

module LambdaRecognition =
[<Test>]
let ``IsBindingALambda - recognize a lambda``() =
let source = """
let f = fun x y -> x + y
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsTrue(parseFileResults.IsBindingALambda (mkPos 2 4), "Expected 'f' to be a lambda expression")

[<Test>]
let ``IsBindingALambda - recognize a nested lambda``() =
let source = """
let f =
fun x ->
fun y ->
x + y
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsTrue(parseFileResults.IsBindingALambda (mkPos 2 4), "Expected 'f' to be a lambda expression")

[<Test>]
let ``IsBindingALambda - recognize a "partial" lambda``() =
let source = """
let f x =
fun y ->
x + y
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsTrue(parseFileResults.IsBindingALambda (mkPos 2 4), "Expected 'f' to be a lambda expression")

[<Test>]
let ``IsBindingALambda - not a lambda``() =
let source = """
let f x y = x + y
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsFalse(parseFileResults.IsBindingALambda (mkPos 2 4), "'f' is not a lambda expression'")
6 changes: 5 additions & 1 deletion vsintegration/src/FSharp.Editor/InlineHints/InlineHints.fs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ type internal FSharpInlineHintsService
let parameterHints = ImmutableArray.CreateBuilder()

let isValidForTypeHint (funcOrValue: FSharpMemberOrFunctionOrValue) (symbolUse: FSharpSymbolUse) =
let isLambdaIfFunction =
funcOrValue.IsFunction &&
parseFileResults.IsBindingALambda symbolUse.RangeAlternate.Start

(funcOrValue.IsValue || isLambdaIfFunction) &&
not (parseFileResults.IsTypeAnnotationGiven symbolUse.RangeAlternate.Start) &&
symbolUse.IsFromDefinition &&
(funcOrValue.IsValue || funcOrValue.IsFunction) &&
not funcOrValue.IsMember &&
not funcOrValue.IsMemberThisValue &&
not funcOrValue.IsConstructorThisValue &&
Expand Down

0 comments on commit de05f68

Please sign in to comment.