Skip to content

Commit e33b24d

Browse files
Merge pull request #2480 from dbaeumer/feature/signatureHelp
Add signature help to Typescript server
2 parents e925aa7 + c66571b commit e33b24d

File tree

4 files changed

+196
-1
lines changed

4 files changed

+196
-1
lines changed

src/server/client.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,35 @@ module ts.server {
433433
}
434434

435435
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems {
436-
throw new Error("Not Implemented Yet.");
436+
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
437+
var args: protocol.SignatureHelpRequestArgs = {
438+
file: fileName,
439+
line: lineOffset.line,
440+
offset: lineOffset.offset
441+
};
442+
443+
var request = this.processRequest<protocol.SignatureHelpRequest>(CommandNames.SignatureHelp, args);
444+
var response = this.processResponse<protocol.SignatureHelpResponse>(request);
445+
446+
if (!response.body) {
447+
return undefined;
448+
}
449+
var helpItems: protocol.SignatureHelpItems = response.body;
450+
var span = helpItems.applicableSpan;
451+
var start = this.lineOffsetToPosition(fileName, span.start);
452+
var end = this.lineOffsetToPosition(fileName, span.end);
453+
454+
var result: SignatureHelpItems = {
455+
items: helpItems.items,
456+
applicableSpan: {
457+
start: start,
458+
length: end - start
459+
},
460+
selectedItemIndex: helpItems.selectedItemIndex,
461+
argumentIndex: helpItems.argumentIndex,
462+
argumentCount: helpItems.argumentCount,
463+
}
464+
return result;
437465
}
438466

439467
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {

src/server/protocol.d.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,122 @@ declare module ts.server.protocol {
592592
body?: CompletionEntryDetails[];
593593
}
594594

595+
/**
596+
* Signature help information for a single parameter
597+
*/
598+
export interface SignatureHelpParameter {
599+
600+
/**
601+
* The parameter's name
602+
*/
603+
name: string;
604+
605+
/**
606+
* Documentation of the parameter.
607+
*/
608+
documentation: SymbolDisplayPart[];
609+
610+
/**
611+
* Display parts of the parameter.
612+
*/
613+
displayParts: SymbolDisplayPart[];
614+
615+
/**
616+
* Whether the parameter is optional or not.
617+
*/
618+
isOptional: boolean;
619+
}
620+
621+
/**
622+
* Represents a single signature to show in signature help.
623+
*/
624+
export interface SignatureHelpItem {
625+
626+
/**
627+
* Whether the signature accepts a variable number of arguments.
628+
*/
629+
isVariadic: boolean;
630+
631+
/**
632+
* The prefix display parts.
633+
*/
634+
prefixDisplayParts: SymbolDisplayPart[];
635+
636+
/**
637+
* The suffix disaply parts.
638+
*/
639+
suffixDisplayParts: SymbolDisplayPart[];
640+
641+
/**
642+
* The separator display parts.
643+
*/
644+
separatorDisplayParts: SymbolDisplayPart[];
645+
646+
/**
647+
* The signature helps items for the parameters.
648+
*/
649+
parameters: SignatureHelpParameter[];
650+
651+
/**
652+
* The signature's documentation
653+
*/
654+
documentation: SymbolDisplayPart[];
655+
}
656+
657+
/**
658+
* Signature help items found in the response of a signature help request.
659+
*/
660+
export interface SignatureHelpItems {
661+
662+
/**
663+
* The signature help items.
664+
*/
665+
items: SignatureHelpItem[];
666+
667+
/**
668+
* The span for which signature help should appear on a signature
669+
*/
670+
applicableSpan: TextSpan;
671+
672+
/**
673+
* The item selected in the set of available help items.
674+
*/
675+
selectedItemIndex: number;
676+
677+
/**
678+
* The argument selected in the set of parameters.
679+
*/
680+
argumentIndex: number;
681+
682+
/**
683+
* The argument count
684+
*/
685+
argumentCount: number;
686+
}
687+
688+
/**
689+
* Arguments of a signature help request.
690+
*/
691+
export interface SignatureHelpRequestArgs extends FileLocationRequestArgs {
692+
693+
}
694+
695+
/**
696+
* Signature help request; value of command field is "signatureHelp".
697+
* Given a file location (file, line, col), return the signature
698+
* help.
699+
*/
700+
export interface SignatureHelpRequest extends FileLocationRequest {
701+
arguments: SignatureHelpRequestArgs;
702+
}
703+
704+
/**
705+
* Repsonse object for a SignatureHelpRequest.
706+
*/
707+
export interface SignatureHelpResponse extends Response {
708+
body?: SignatureHelpItems;
709+
}
710+
595711
/**
596712
* Arguments for geterr messages.
597713
*/

src/server/session.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ module ts.server {
8080
export var Close = "close";
8181
export var Completions = "completions";
8282
export var CompletionDetails = "completionEntryDetails";
83+
export var SignatureHelp = "signatureHelp";
8384
export var Configure = "configure";
8485
export var Definition = "definition";
8586
export var Format = "format";
@@ -577,6 +578,35 @@ module ts.server {
577578
}, []);
578579
}
579580

581+
getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
582+
var file = ts.normalizePath(fileName);
583+
var project = this.projectService.getProjectForFile(file);
584+
if (!project) {
585+
throw Errors.NoProject;
586+
}
587+
588+
var compilerService = project.compilerService;
589+
var position = compilerService.host.lineOffsetToPosition(file, line, offset);
590+
var helpItems = compilerService.languageService.getSignatureHelpItems(file, position);
591+
if (!helpItems) {
592+
return undefined;
593+
}
594+
595+
var span = helpItems.applicableSpan;
596+
var result: protocol.SignatureHelpItems = {
597+
items: helpItems.items,
598+
applicableSpan: {
599+
start: compilerService.host.positionToLineOffset(file, span.start),
600+
end: compilerService.host.positionToLineOffset(file, span.start + span.length)
601+
},
602+
selectedItemIndex: helpItems.selectedItemIndex,
603+
argumentIndex: helpItems.argumentIndex,
604+
argumentCount: helpItems.argumentCount,
605+
}
606+
607+
return result;
608+
}
609+
580610
getDiagnostics(delay: number, fileNames: string[]) {
581611
var checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => {
582612
fileName = ts.normalizePath(fileName);
@@ -790,6 +820,11 @@ module ts.server {
790820
completionDetailsArgs.entryNames,completionDetailsArgs.file);
791821
break;
792822
}
823+
case CommandNames.SignatureHelp: {
824+
var signatureHelpArgs = <protocol.SignatureHelpRequestArgs>request.arguments;
825+
response = this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file);
826+
break;
827+
}
793828
case CommandNames.Geterr: {
794829
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
795830
response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
////function foo(data: number) {
4+
////}
5+
////
6+
////function bar {
7+
//// foo(/*1*/)
8+
////}
9+
10+
goTo.marker('1');
11+
verify.signatureHelpPresent();
12+
verify.signatureHelpCountIs(1);
13+
verify.signatureHelpArgumentCountIs(0);
14+
15+
verify.currentSignatureParameterCountIs(1);
16+
verify.currentSignatureHelpDocCommentIs('');

0 commit comments

Comments
 (0)