From 48267c031493eb3dc0832c8847b267b77cce4aec Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 19 Jun 2018 15:03:48 -0700 Subject: [PATCH 1/2] Add CompletionInfo command to protocol --- src/server/protocol.ts | 12 +++++ src/server/session.ts | 44 ++++++++++++------- .../reference/api/tsserverlibrary.d.ts | 10 +++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 2f128aa1663f7..dc8630391f9b2 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -15,6 +15,7 @@ namespace ts.server.protocol { Change = "change", Close = "close", Completions = "completions", + CompletionInfo = "completionInfo", /* @internal */ CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", @@ -1947,6 +1948,17 @@ namespace ts.server.protocol { body?: CompletionEntry[]; } + export interface CompletionInfoResponse extends Response { + body?: CompletionInfo; + } + + export interface CompletionInfo { + readonly isGlobalCompletion: boolean; + readonly isMemberCompletion: boolean; + readonly isNewIdentifierLocation: boolean; + readonly entries: ReadonlyArray; + } + export interface CompletionDetailsResponse extends Response { body?: CompletionEntryDetails[]; } diff --git a/src/server/session.ts b/src/server/session.ts index 74629d97e4877..c6934bb8d829c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1343,8 +1343,7 @@ namespace ts.server { }); } - private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): ReadonlyArray | CompletionInfo | undefined { - const prefix = args.prefix || ""; + private getCompletions(args: protocol.CompletionsRequestArgs, kind: protocol.CommandTypes.CompletionInfo | protocol.CommandTypes.Completions | protocol.CommandTypes.CompletionsFull): ReadonlyArray | protocol.CompletionInfo | CompletionInfo | undefined { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!; const position = this.getPosition(args, scriptInfo); @@ -1355,19 +1354,27 @@ namespace ts.server { includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions }); - if (simplifiedResult) { - return mapDefined(completions && completions.entries, entry => { - if (completions!.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { - const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; - const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; - // Use `hasAction || undefined` to avoid serializing `false`. - return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; - } - }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); - } - else { - return completions; - } + if (completions === undefined) return undefined; + + if (kind === protocol.CommandTypes.CompletionsFull) return completions; + + const prefix = args.prefix || ""; + const entries = mapDefined(completions.entries, entry => { + if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { + const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; + const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; + // Use `hasAction || undefined` to avoid serializing `false`. + return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; + } + }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); + + if (kind === protocol.CommandTypes.Completions) return entries; + + const res: protocol.CompletionInfo = { + ...completions, + entries, + }; + return res; } private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -2035,11 +2042,14 @@ namespace ts.server { [CommandNames.FormatRangeFull]: (request: protocol.FormatRequest) => { return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments)); }, + [CommandNames.CompletionInfo]: (request: protocol.CompletionsRequest) => { + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.CompletionInfo)); + }, [CommandNames.Completions]: (request: protocol.CompletionsRequest) => { - return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ true)); + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.Completions)); }, [CommandNames.CompletionsFull]: (request: protocol.CompletionsRequest) => { - return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false)); + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.CompletionsFull)); }, [CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => { return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true)); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 74045ba417d5c..114b2341fa95e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -12175,6 +12175,7 @@ declare namespace ts.server.protocol { Change = "change", Close = "close", Completions = "completions", + CompletionInfo = "completionInfo", CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", CompletionDetailsFull = "completionEntryDetails-full", @@ -12876,6 +12877,15 @@ declare namespace ts.server.protocol { interface CompletionsResponse extends Response { body?: CompletionEntry[]; } + interface CompletionInfoResponse extends Response { + body?: CompletionInfo; + } + interface CompletionInfo { + readonly isGlobalCompletion: boolean; + readonly isMemberCompletion: boolean; + readonly isNewIdentifierLocation: boolean; + readonly entries: ReadonlyArray; + } interface CompletionDetailsResponse extends Response { body?: CompletionEntryDetails[]; } From 8ba5f2c2a7ca94cef0670a548638d185d504e3e6 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 19 Jun 2018 15:44:42 -0700 Subject: [PATCH 2/2] Add comments to protocol --- src/server/protocol.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index dc8630391f9b2..49fb54a6b10dd 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -14,6 +14,7 @@ namespace ts.server.protocol { GetSpanOfEnclosingComment = "getSpanOfEnclosingComment", Change = "change", Close = "close", + /** @deprecated Prefer CompletionInfo -- see comment on CompletionsResponse */ Completions = "completions", CompletionInfo = "completionInfo", /* @internal */ @@ -1944,6 +1945,7 @@ namespace ts.server.protocol { source?: SymbolDisplayPart[]; } + /** @deprecated Prefer CompletionInfoResponse, which supports several top-level fields in addition to the array of entries. */ export interface CompletionsResponse extends Response { body?: CompletionEntry[]; }