Skip to content

Commit

Permalink
Fix triggering the outer application's signature help when triggering…
Browse files Browse the repository at this point in the history
… an inner application inside a lambda (#10954)

* Fix issue where sighelp triggered in lambda gave outer signature help

* Updates
  • Loading branch information
cartermp authored Jan 27, 2021
1 parent 2892367 commit fe4a61a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
33 changes: 26 additions & 7 deletions src/fsharp/service/ServiceUntypedParse.fs
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,18 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
member _.VisitExpr(_, _, defaultTraverse, expr) =
match expr with
| SynExpr.App (_, _, SynExpr.App(_, true, SynExpr.Ident ident, _, _), argExpr, _) when rangeContainsPos argExpr.Range pos ->
if ident.idText = "op_PipeRight" then
Some (ident, 1)
elif ident.idText = "op_PipeRight2" then
Some (ident, 2)
elif ident.idText = "op_PipeRight3" then
Some (ident, 3)
else
match argExpr with
| SynExpr.App(_, _, _, SynExpr.Paren(expr, _, _, _), _) when rangeContainsPos expr.Range pos ->
None
| _ ->
if ident.idText = "op_PipeRight" then
Some (ident, 1)
elif ident.idText = "op_PipeRight2" then
Some (ident, 2)
elif ident.idText = "op_PipeRight3" then
Some (ident, 3)
else
None
| _ -> defaultTraverse expr
})
| None -> None
Expand Down Expand Up @@ -216,6 +220,10 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
match argExpr with
| SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos

| SynExpr.Paren(SynExpr.Lambda(_, _, _args, body, _, _), _, _, _) when rangeContainsPos body.Range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr body pos

| _ ->
match funcExpr with
| SynExpr.App (_, true, _, _, _) when rangeContainsPos argExpr.Range pos ->
Expand All @@ -227,6 +235,17 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
// Generally, we want to dive into the func expr to get the range
// of the identifier of the function we're after
getIdentRangeForFuncExprInApp traverseSynExpr funcExpr pos

| SynExpr.LetOrUse(_, _, bindings, body, range) when rangeContainsPos range pos ->
let binding =
bindings
|> List.tryFind (fun x -> rangeContainsPos x.RangeOfBindingAndRhs pos)
match binding with
| Some(SynBinding.Binding(_, _, _, _, _, _, _, _, _, expr, _, _)) ->
getIdentRangeForFuncExprInApp traverseSynExpr expr pos
| None ->
getIdentRangeForFuncExprInApp traverseSynExpr body pos

| expr ->
traverseSynExpr expr
|> Option.map (fun expr -> expr)
Expand Down
35 changes: 35 additions & 0 deletions tests/service/ServiceUntypedParseTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,26 @@ async {
|> tups
|> shouldEqual ((4, 11), (4, 16))

[<Test>]
let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda``() =
let source = """
let add n1 n2 = n1 + n2
let lst = [1; 2; 3]
let mapped =
lst |> List.map (fun n ->
let sum = add
n.ToString()
)
"""
let parseFileResults, _ = getParseAndCheckResults source
let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 6 21)
match res with
| None -> Assert.Fail("Expected 'add' but got nothing")
| Some range ->
range
|> tups
|> shouldEqual ((6, 18), (6, 21))

module PipelinesAndArgs =
[<Test>]
let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - No pipeline, no infix app``() =
Expand Down Expand Up @@ -897,6 +917,21 @@ let square x = x *
| None ->
Assert.Fail("No pipeline found")

[<Test>]
let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - none when inside lambda``() =
let source = """
let add n1 n2 = n1 + n2
let lst = [1; 2; 3]
let mapped =
lst |> List.map (fun n ->
let sum = add 1
n.ToString()
)
"""
let parseFileResults, _ = getParseAndCheckResults source
let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 6 22)
Assert.IsTrue(res.IsNone, "Inside a lambda but counted the pipeline outside of that lambda.")

[<Test>]
let ``TryRangeOfExprInYieldOrReturn - not contained``() =
let source = """
Expand Down

0 comments on commit fe4a61a

Please sign in to comment.