diff --git a/src/fsharp/service/FSharpParseFileResults.fs b/src/fsharp/service/FSharpParseFileResults.fs index 923097f807..e894230911 100644 --- a/src/fsharp/service/FSharpParseFileResults.fs +++ b/src/fsharp/service/FSharpParseFileResults.fs @@ -158,6 +158,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = match expr with + | SynExpr.TypeApp (_, _, _, _, _, _, range) when rangeContainsPos range pos -> + Some range | SynExpr.App(_, _, _, SynExpr.CompExpr (_, _, expr, _), range) when rangeContainsPos range pos -> traverseSynExpr expr | SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos -> @@ -176,6 +178,9 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Paren (expr, _, _, range) when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos + | SynExpr.TypeApp (expr, _, _, _, _, _, _) -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + | SynExpr.App (_, _, funcExpr, argExpr, _) -> match argExpr with | SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos -> @@ -269,6 +274,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = match expr with + | SynExpr.TypeApp (expr, _, _, _, _, _, range) when rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos | SynExpr.App (_, _, _funcExpr, _, range) as app when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr app pos | _ -> defaultTraverse expr diff --git a/tests/service/ServiceUntypedParseTests.fs b/tests/service/ServiceUntypedParseTests.fs index d33ca49e82..ae23e2ae02 100644 --- a/tests/service/ServiceUntypedParseTests.fs +++ b/tests/service/ServiceUntypedParseTests.fs @@ -683,7 +683,7 @@ async { Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 2 5), "Pos should not be in application") [] - let ``TryRangeOfFunctionOrMethodBeingApplied - inside CE return - no``() = + let ``IsPosContainedInApplication - inside CE return - no``() = let source = """ async { return sqrt @@ -693,7 +693,7 @@ async { Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 2 5), "Pos should not be in application") [] - let ``TryRangeOfFunctionOrMethodBeingApplied - inside CE - yes``() = + let ``IsPosContainedInApplication - inside CE - yes``() = let source = """ let myAdd x y = x + y async { @@ -703,6 +703,15 @@ async { let parseFileResults, _ = getParseAndCheckResults source Assert.False(parseFileResults.IsPosContainedInApplication (mkPos 3 18), "Pos should not be in application") + [] + let ``IsPosContainedInApplication - inside type application``() = + let source = """ +let f<'x> x = () +f + """ + let parseFileResults, _ = getParseAndCheckResults source + Assert.True(parseFileResults.IsPosContainedInApplication (mkPos 3 6), "A type application is an application, expected True.") + [] let ``TryRangeOfFunctionOrMethodBeingApplied - no application``() = let source = """ @@ -982,6 +991,21 @@ C.Yeet(1, 2, (fun x -> sqrt)) |> tups |> shouldEqual ((3, 23), (3, 27)) + [] + let ``TryRangeOfFunctionOrMethodBeingApplied - generic-typed app``() = + let source = """ +let f<'x> x = () +f +""" + let parseFileResults, _ = getParseAndCheckResults source + let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 3 6) + match res with + | None -> Assert.Fail("Expected 'f' but got nothing") + | Some range -> + range + |> tups + |> shouldEqual ((3, 0), (3, 1)) + module PipelinesAndArgs = [] let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - No pipeline, no infix app``() = diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs index 7e1523ea0b..5baf4bf593 100644 --- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs +++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs @@ -476,7 +476,7 @@ type internal FSharpSignatureHelpProvider // Generally ' ' indicates a function application, but it's also used commonly after a comma in a method call. // This means that the adjusted position relative to the caret could be a ',' or a '(' or '<', // which would mean we're already inside of a method call - not a function argument. So we bail if that's the case. - | Some ' ', None when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' -> + | Some ' ', _ when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' -> return! FSharpSignatureHelpProvider.ProvideParametersAsyncAux( parseResults,