Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit 6a37f94

Browse files
committed
Track the signaturehelp session kind in signature help (dotnet#10970)
1 parent 2c127b7 commit 6a37f94

File tree

1 file changed

+84
-45
lines changed

1 file changed

+84
-45
lines changed

Completion/SignatureHelp.fs

Lines changed: 84 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,17 @@ type SignatureHelpItem =
3333
Parameters: SignatureHelpParameterInfo[]
3434
MainDescription: ResizeArray<RoslynTaggedText> }
3535

36+
type CurrentSignatureHelpSessionKind =
37+
| FunctionApplication
38+
| MethodCall
39+
3640
type SignatureHelpData =
3741
{ SignatureHelpItems: SignatureHelpItem[]
3842
ApplicableSpan: TextSpan
3943
ArgumentIndex: int
4044
ArgumentCount: int
41-
ArgumentName: string option }
45+
ArgumentName: string option
46+
CurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind }
4247

4348
[<Shared>]
4449
[<Export(typeof<IFSharpSignatureHelpProvider>)>]
@@ -56,6 +61,8 @@ type internal FSharpSignatureHelpProvider
5661
static let oneColAfter (lp: LinePosition) = LinePosition(lp.Line,lp.Character+1)
5762
static let oneColBefore (lp: LinePosition) = LinePosition(lp.Line,max 0 (lp.Character-1))
5863

64+
let mutable possibleCurrentSignatureHelpSessionKind = None
65+
5966
static member internal ProvideMethodsAsyncAux
6067
(
6168
caretLinePos: LinePosition,
@@ -212,7 +219,8 @@ type internal FSharpSignatureHelpProvider
212219
ApplicableSpan = applicableSpan
213220
ArgumentIndex = argumentIndex
214221
ArgumentCount = argumentCount
215-
ArgumentName = argumentName }
222+
ArgumentName = argumentName
223+
CurrentSignatureHelpSessionKind = MethodCall }
216224

217225
return! Some data
218226
}
@@ -424,7 +432,8 @@ type internal FSharpSignatureHelpProvider
424432
ApplicableSpan = TextSpan(symbolSpan.End, caretPosition - symbolSpan.End)
425433
ArgumentIndex = argumentIndex
426434
ArgumentCount = displayArgs.Count
427-
ArgumentName = None }
435+
ArgumentName = None
436+
CurrentSignatureHelpSessionKind = FunctionApplication }
428437

429438
return! Some data
430439
| _ ->
@@ -442,7 +451,8 @@ type internal FSharpSignatureHelpProvider
442451
options: FSharpProjectOptions,
443452
filePath: string,
444453
textVersionHash: int,
445-
triggerTypedChar: char option
454+
triggerTypedChar: char option,
455+
possibleCurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind option
446456
) =
447457
asyncMaybe {
448458
let textLines = sourceText.Lines
@@ -468,11 +478,23 @@ type internal FSharpSignatureHelpProvider
468478

469479
let adjustedColumnString = sourceText.GetSubText(TextSpan(adjustedColumnInSource, 1)).ToString()
470480

471-
match triggerTypedChar with
481+
match triggerTypedChar, possibleCurrentSignatureHelpSessionKind with
472482
// Generally ' ' indicates a function application, but it's also used commonly after a comma in a method call.
473483
// This means that the adjusted position relative to the caret could be a ',' or a ')' or '>',
474484
// which would mean we're already inside of a method call - not a function argument. So we bail if that's the case.
475-
| Some ' ' when adjustedColumnString <> "," && adjustedColumnString <> ")" && adjustedColumnString <> ">" ->
485+
| Some ' ', None when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
486+
return!
487+
FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
488+
parseResults,
489+
checkFileResults,
490+
document.Id,
491+
defines,
492+
documentationBuilder,
493+
sourceText,
494+
caretPosition,
495+
adjustedColumnInSource,
496+
filePath)
497+
| _, Some FunctionApplication when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
476498
return!
477499
FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
478500
parseResults,
@@ -515,46 +537,63 @@ type internal FSharpSignatureHelpProvider
515537
Some triggerInfo.TriggerCharacter.Value
516538
else None
517539

518-
let! signatureHelpData =
519-
FSharpSignatureHelpProvider.ProvideSignatureHelp(
520-
document,
521-
defines,
522-
checker,
523-
documentationBuilder,
524-
sourceText,
525-
position,
526-
projectOptions,
527-
document.FilePath,
528-
textVersion.GetHashCode(),
529-
triggerTypedChar)
530-
let items =
531-
signatureHelpData.SignatureHelpItems
532-
|> Array.map (fun item ->
533-
let parameters =
534-
item.Parameters
535-
|> Array.map (fun paramInfo ->
536-
FSharpSignatureHelpParameter(
537-
paramInfo.ParameterName,
538-
paramInfo.IsOptional,
539-
documentationFactory = (fun _ -> paramInfo.Documentation :> seq<_>),
540-
displayParts = paramInfo.DisplayParts))
540+
let doWork () =
541+
async {
542+
let! signatureHelpDataOpt =
543+
FSharpSignatureHelpProvider.ProvideSignatureHelp(
544+
document,
545+
defines,
546+
checker,
547+
documentationBuilder,
548+
sourceText,
549+
position,
550+
projectOptions,
551+
document.FilePath,
552+
textVersion.GetHashCode(),
553+
triggerTypedChar,
554+
possibleCurrentSignatureHelpSessionKind)
555+
match signatureHelpDataOpt with
556+
| None ->
557+
possibleCurrentSignatureHelpSessionKind <- None
558+
return None
559+
| Some signatureHelpData ->
560+
let items =
561+
signatureHelpData.SignatureHelpItems
562+
|> Array.map (fun item ->
563+
let parameters =
564+
item.Parameters
565+
|> Array.map (fun paramInfo ->
566+
FSharpSignatureHelpParameter(
567+
paramInfo.ParameterName,
568+
paramInfo.IsOptional,
569+
documentationFactory = (fun _ -> paramInfo.Documentation :> seq<_>),
570+
displayParts = paramInfo.DisplayParts))
541571

542-
FSharpSignatureHelpItem(
543-
isVariadic=item.HasParamArrayArg,
544-
documentationFactory=(fun _ -> item.Documentation :> seq<_>),
545-
prefixParts=item.PrefixParts,
546-
separatorParts=item.SeparatorParts,
547-
suffixParts=item.SuffixParts,
548-
parameters=parameters,
549-
descriptionParts=item.MainDescription))
550-
551-
return
552-
FSharpSignatureHelpItems(
553-
items,
554-
signatureHelpData.ApplicableSpan,
555-
signatureHelpData.ArgumentIndex,
556-
signatureHelpData.ArgumentCount,
557-
Option.toObj signatureHelpData.ArgumentName)
572+
FSharpSignatureHelpItem(
573+
isVariadic=item.HasParamArrayArg,
574+
documentationFactory=(fun _ -> item.Documentation :> seq<_>),
575+
prefixParts=item.PrefixParts,
576+
separatorParts=item.SeparatorParts,
577+
suffixParts=item.SuffixParts,
578+
parameters=parameters,
579+
descriptionParts=item.MainDescription))
580+
581+
match signatureHelpData.CurrentSignatureHelpSessionKind with
582+
| MethodCall ->
583+
possibleCurrentSignatureHelpSessionKind <- Some MethodCall
584+
| FunctionApplication ->
585+
possibleCurrentSignatureHelpSessionKind <- Some FunctionApplication
586+
587+
return
588+
FSharpSignatureHelpItems(
589+
items,
590+
signatureHelpData.ApplicableSpan,
591+
signatureHelpData.ArgumentIndex,
592+
signatureHelpData.ArgumentCount,
593+
Option.toObj signatureHelpData.ArgumentName)
594+
|> Some
595+
}
596+
return! doWork ()
558597
}
559598
|> Async.map Option.toObj
560599
|> RoslynHelpers.StartAsyncAsTask cancellationToken

0 commit comments

Comments
 (0)