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

Commit 73e36fd

Browse files
authored
Track the signaturehelp session kind in signature help (dotnet#10970)
1 parent a0e4d8c commit 73e36fd

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
}
@@ -425,7 +433,8 @@ type internal FSharpSignatureHelpProvider
425433
ApplicableSpan = TextSpan(symbolSpan.End, caretPosition - symbolSpan.End)
426434
ArgumentIndex = argumentIndex
427435
ArgumentCount = displayArgs.Count
428-
ArgumentName = None }
436+
ArgumentName = None
437+
CurrentSignatureHelpSessionKind = FunctionApplication }
429438

430439
return! Some data
431440
| _ ->
@@ -443,7 +452,8 @@ type internal FSharpSignatureHelpProvider
443452
options: FSharpProjectOptions,
444453
filePath: string,
445454
textVersionHash: int,
446-
triggerTypedChar: char option
455+
triggerTypedChar: char option,
456+
possibleCurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind option
447457
) =
448458
asyncMaybe {
449459
let textLines = sourceText.Lines
@@ -463,11 +473,23 @@ type internal FSharpSignatureHelpProvider
463473

464474
let adjustedColumnChar = sourceText.[adjustedColumnInSource]
465475

466-
match triggerTypedChar with
476+
match triggerTypedChar, possibleCurrentSignatureHelpSessionKind with
467477
// Generally ' ' indicates a function application, but it's also used commonly after a comma in a method call.
468478
// This means that the adjusted position relative to the caret could be a ',' or a '(' or '<',
469479
// which would mean we're already inside of a method call - not a function argument. So we bail if that's the case.
470-
| Some ' ' when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
480+
| Some ' ', None when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
481+
return!
482+
FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
483+
parseResults,
484+
checkFileResults,
485+
document.Id,
486+
defines,
487+
documentationBuilder,
488+
sourceText,
489+
caretPosition,
490+
adjustedColumnInSource,
491+
filePath)
492+
| _, Some FunctionApplication when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
471493
return!
472494
FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
473495
parseResults,
@@ -510,46 +532,63 @@ type internal FSharpSignatureHelpProvider
510532
Some triggerInfo.TriggerCharacter.Value
511533
else None
512534

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

537-
FSharpSignatureHelpItem(
538-
isVariadic=item.HasParamArrayArg,
539-
documentationFactory=(fun _ -> item.Documentation :> seq<_>),
540-
prefixParts=item.PrefixParts,
541-
separatorParts=item.SeparatorParts,
542-
suffixParts=item.SuffixParts,
543-
parameters=parameters,
544-
descriptionParts=item.MainDescription))
545-
546-
return
547-
FSharpSignatureHelpItems(
548-
items,
549-
signatureHelpData.ApplicableSpan,
550-
signatureHelpData.ArgumentIndex,
551-
signatureHelpData.ArgumentCount,
552-
Option.toObj signatureHelpData.ArgumentName)
567+
FSharpSignatureHelpItem(
568+
isVariadic=item.HasParamArrayArg,
569+
documentationFactory=(fun _ -> item.Documentation :> seq<_>),
570+
prefixParts=item.PrefixParts,
571+
separatorParts=item.SeparatorParts,
572+
suffixParts=item.SuffixParts,
573+
parameters=parameters,
574+
descriptionParts=item.MainDescription))
575+
576+
match signatureHelpData.CurrentSignatureHelpSessionKind with
577+
| MethodCall ->
578+
possibleCurrentSignatureHelpSessionKind <- Some MethodCall
579+
| FunctionApplication ->
580+
possibleCurrentSignatureHelpSessionKind <- Some FunctionApplication
581+
582+
return
583+
FSharpSignatureHelpItems(
584+
items,
585+
signatureHelpData.ApplicableSpan,
586+
signatureHelpData.ArgumentIndex,
587+
signatureHelpData.ArgumentCount,
588+
Option.toObj signatureHelpData.ArgumentName)
589+
|> Some
590+
}
591+
return! doWork ()
553592
}
554593
|> Async.map Option.toObj
555594
|> RoslynHelpers.StartAsyncAsTask cancellationToken

0 commit comments

Comments
 (0)