Merge pull request #2480 from dbaeumer/feature/signatureHelp

Add signature help to Typescript server
This commit is contained in:
Daniel Rosenwasser 2015-03-25 15:07:24 -07:00
commit e33b24d3d0
4 changed files with 196 additions and 1 deletions

View File

@ -433,7 +433,35 @@ module ts.server {
}
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems {
throw new Error("Not Implemented Yet.");
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
var args: protocol.SignatureHelpRequestArgs = {
file: fileName,
line: lineOffset.line,
offset: lineOffset.offset
};
var request = this.processRequest<protocol.SignatureHelpRequest>(CommandNames.SignatureHelp, args);
var response = this.processResponse<protocol.SignatureHelpResponse>(request);
if (!response.body) {
return undefined;
}
var helpItems: protocol.SignatureHelpItems = response.body;
var span = helpItems.applicableSpan;
var start = this.lineOffsetToPosition(fileName, span.start);
var end = this.lineOffsetToPosition(fileName, span.end);
var result: SignatureHelpItems = {
items: helpItems.items,
applicableSpan: {
start: start,
length: end - start
},
selectedItemIndex: helpItems.selectedItemIndex,
argumentIndex: helpItems.argumentIndex,
argumentCount: helpItems.argumentCount,
}
return result;
}
getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {

View File

@ -592,6 +592,122 @@ declare module ts.server.protocol {
body?: CompletionEntryDetails[];
}
/**
* Signature help information for a single parameter
*/
export interface SignatureHelpParameter {
/**
* The parameter's name
*/
name: string;
/**
* Documentation of the parameter.
*/
documentation: SymbolDisplayPart[];
/**
* Display parts of the parameter.
*/
displayParts: SymbolDisplayPart[];
/**
* Whether the parameter is optional or not.
*/
isOptional: boolean;
}
/**
* Represents a single signature to show in signature help.
*/
export interface SignatureHelpItem {
/**
* Whether the signature accepts a variable number of arguments.
*/
isVariadic: boolean;
/**
* The prefix display parts.
*/
prefixDisplayParts: SymbolDisplayPart[];
/**
* The suffix disaply parts.
*/
suffixDisplayParts: SymbolDisplayPart[];
/**
* The separator display parts.
*/
separatorDisplayParts: SymbolDisplayPart[];
/**
* The signature helps items for the parameters.
*/
parameters: SignatureHelpParameter[];
/**
* The signature's documentation
*/
documentation: SymbolDisplayPart[];
}
/**
* Signature help items found in the response of a signature help request.
*/
export interface SignatureHelpItems {
/**
* The signature help items.
*/
items: SignatureHelpItem[];
/**
* The span for which signature help should appear on a signature
*/
applicableSpan: TextSpan;
/**
* The item selected in the set of available help items.
*/
selectedItemIndex: number;
/**
* The argument selected in the set of parameters.
*/
argumentIndex: number;
/**
* The argument count
*/
argumentCount: number;
}
/**
* Arguments of a signature help request.
*/
export interface SignatureHelpRequestArgs extends FileLocationRequestArgs {
}
/**
* Signature help request; value of command field is "signatureHelp".
* Given a file location (file, line, col), return the signature
* help.
*/
export interface SignatureHelpRequest extends FileLocationRequest {
arguments: SignatureHelpRequestArgs;
}
/**
* Repsonse object for a SignatureHelpRequest.
*/
export interface SignatureHelpResponse extends Response {
body?: SignatureHelpItems;
}
/**
* Arguments for geterr messages.
*/

View File

@ -80,6 +80,7 @@ module ts.server {
export var Close = "close";
export var Completions = "completions";
export var CompletionDetails = "completionEntryDetails";
export var SignatureHelp = "signatureHelp";
export var Configure = "configure";
export var Definition = "definition";
export var Format = "format";
@ -577,6 +578,35 @@ module ts.server {
}, []);
}
getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems {
var file = ts.normalizePath(fileName);
var project = this.projectService.getProjectForFile(file);
if (!project) {
throw Errors.NoProject;
}
var compilerService = project.compilerService;
var position = compilerService.host.lineOffsetToPosition(file, line, offset);
var helpItems = compilerService.languageService.getSignatureHelpItems(file, position);
if (!helpItems) {
return undefined;
}
var span = helpItems.applicableSpan;
var result: protocol.SignatureHelpItems = {
items: helpItems.items,
applicableSpan: {
start: compilerService.host.positionToLineOffset(file, span.start),
end: compilerService.host.positionToLineOffset(file, span.start + span.length)
},
selectedItemIndex: helpItems.selectedItemIndex,
argumentIndex: helpItems.argumentIndex,
argumentCount: helpItems.argumentCount,
}
return result;
}
getDiagnostics(delay: number, fileNames: string[]) {
var checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => {
fileName = ts.normalizePath(fileName);
@ -790,6 +820,11 @@ module ts.server {
completionDetailsArgs.entryNames,completionDetailsArgs.file);
break;
}
case CommandNames.SignatureHelp: {
var signatureHelpArgs = <protocol.SignatureHelpRequestArgs>request.arguments;
response = this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file);
break;
}
case CommandNames.Geterr: {
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files);

View File

@ -0,0 +1,16 @@
/// <reference path="fourslash.ts"/>
////function foo(data: number) {
////}
////
////function bar {
//// foo(/*1*/)
////}
goTo.marker('1');
verify.signatureHelpPresent();
verify.signatureHelpCountIs(1);
verify.signatureHelpArgumentCountIs(0);
verify.currentSignatureParameterCountIs(1);
verify.currentSignatureHelpDocCommentIs('');