Cherry Pick into 16.9 - Fix triggering the outer application's signature help when triggering an inner application inside a lambda (#10954) (#10973)

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

* Updates
This commit is contained in:
Phillip Carter 2021-02-01 10:46:14 -08:00 коммит произвёл nosami
Родитель 02dabea6f9
Коммит 40d4782e9f
2 изменённых файлов: 61 добавлений и 7 удалений

Просмотреть файл

@ -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
@ -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 ->
@ -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)

Просмотреть файл

@ -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``() =
@ -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 = """