Skip to content

Commit 4cf5774

Browse files
author
Andy
authored
Add tsserver test for completions and avoid excess properties (#25622)
1 parent 9938f31 commit 4cf5774

File tree

4 files changed

+130
-3
lines changed

4 files changed

+130
-3
lines changed

src/server/protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,7 @@ namespace ts.server.protocol {
18391839
* begin with prefix.
18401840
*/
18411841
export interface CompletionsRequest extends FileLocationRequest {
1842-
command: CommandTypes.Completions;
1842+
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
18431843
arguments: CompletionsRequestArgs;
18441844
}
18451845

src/services/codefixes/importFixes.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,13 @@ namespace ts.codefix {
168168
// We sort the best codefixes first, so taking `first` is best for completions.
169169
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier;
170170
const fix = first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences));
171-
return { moduleSpecifier, codeAction: codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences)) };
171+
return { moduleSpecifier, codeAction: codeFixActionToCodeAction(codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences))) };
172172
}
173+
174+
function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction {
175+
return { description, changes, commands };
176+
}
177+
173178
function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
174179
const result: SymbolExportInfo[] = [];
175180
forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => {

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9210,6 +9210,128 @@ export function Test2() {
92109210
});
92119211
});
92129212

9213+
describe("tsserverProjectSystem completions", () => {
9214+
it("works", () => {
9215+
const aTs: File = {
9216+
path: "/a.ts",
9217+
content: "export const foo = 0;",
9218+
};
9219+
const bTs: File = {
9220+
path: "/b.ts",
9221+
content: "foo",
9222+
};
9223+
const tsconfig: File = {
9224+
path: "/tsconfig.json",
9225+
content: "{}",
9226+
};
9227+
9228+
const host = createServerHost([aTs, bTs, tsconfig]);
9229+
const session = createSession(host);
9230+
openFilesForSession([aTs, bTs], session);
9231+
9232+
const requestLocation: protocol.FileLocationRequestArgs = {
9233+
file: bTs.path,
9234+
line: 1,
9235+
offset: 3,
9236+
};
9237+
9238+
const response = executeSessionRequest<protocol.CompletionsRequest, protocol.CompletionInfoResponse>(session, protocol.CommandTypes.CompletionInfo, {
9239+
...requestLocation,
9240+
includeExternalModuleExports: true,
9241+
prefix: "foo",
9242+
});
9243+
const entry: protocol.CompletionEntry = {
9244+
hasAction: true,
9245+
insertText: undefined,
9246+
isRecommended: undefined,
9247+
kind: ScriptElementKind.constElement,
9248+
kindModifiers: ScriptElementKindModifier.exportedModifier,
9249+
name: "foo",
9250+
replacementSpan: undefined,
9251+
sortText: "0",
9252+
source: "/a",
9253+
};
9254+
assert.deepEqual<protocol.CompletionInfo | undefined>(response, {
9255+
isGlobalCompletion: true,
9256+
isMemberCompletion: false,
9257+
isNewIdentifierLocation: false,
9258+
entries: [entry],
9259+
});
9260+
9261+
const detailsRequestArgs: protocol.CompletionDetailsRequestArgs = {
9262+
...requestLocation,
9263+
entryNames: [{ name: "foo", source: "/a" }],
9264+
};
9265+
9266+
const detailsResponse = executeSessionRequest<protocol.CompletionDetailsRequest, protocol.CompletionDetailsResponse>(session, protocol.CommandTypes.CompletionDetails, detailsRequestArgs);
9267+
const detailsCommon: protocol.CompletionEntryDetails & CompletionEntryDetails = {
9268+
displayParts: [
9269+
keywordPart(SyntaxKind.ConstKeyword),
9270+
spacePart(),
9271+
displayPart("foo", SymbolDisplayPartKind.localName),
9272+
punctuationPart(SyntaxKind.ColonToken),
9273+
spacePart(),
9274+
displayPart("0", SymbolDisplayPartKind.stringLiteral),
9275+
],
9276+
documentation: emptyArray,
9277+
kind: ScriptElementKind.constElement,
9278+
kindModifiers: ScriptElementKindModifier.exportedModifier,
9279+
name: "foo",
9280+
source: [{ text: "./a", kind: "text" }],
9281+
tags: emptyArray,
9282+
};
9283+
assert.deepEqual<ReadonlyArray<protocol.CompletionEntryDetails> | undefined>(detailsResponse, [
9284+
{
9285+
codeActions: [
9286+
{
9287+
description: `Import 'foo' from module "./a"`,
9288+
changes: [
9289+
{
9290+
fileName: "/b.ts",
9291+
textChanges: [
9292+
{
9293+
start: { line: 1, offset: 1 },
9294+
end: { line: 1, offset: 1 },
9295+
newText: 'import { foo } from "./a";\n\n',
9296+
},
9297+
],
9298+
},
9299+
],
9300+
commands: undefined,
9301+
},
9302+
],
9303+
...detailsCommon,
9304+
},
9305+
]);
9306+
9307+
interface CompletionDetailsFullRequest extends protocol.FileLocationRequest {
9308+
readonly command: protocol.CommandTypes.CompletionDetailsFull;
9309+
readonly arguments: protocol.CompletionDetailsRequestArgs;
9310+
}
9311+
interface CompletionDetailsFullResponse extends protocol.Response {
9312+
readonly body?: ReadonlyArray<CompletionEntryDetails>;
9313+
}
9314+
const detailsFullResponse = executeSessionRequest<CompletionDetailsFullRequest, CompletionDetailsFullResponse>(session, protocol.CommandTypes.CompletionDetailsFull, detailsRequestArgs);
9315+
assert.deepEqual<ReadonlyArray<CompletionEntryDetails> | undefined>(detailsFullResponse, [
9316+
{
9317+
codeActions: [
9318+
{
9319+
description: `Import 'foo' from module "./a"`,
9320+
changes: [
9321+
{
9322+
fileName: "/b.ts",
9323+
textChanges: [createTextChange(createTextSpan(0, 0), 'import { foo } from "./a";\n\n')],
9324+
},
9325+
],
9326+
commands: undefined,
9327+
}
9328+
],
9329+
...detailsCommon,
9330+
}
9331+
]);
9332+
});
9333+
});
9334+
92139335
describe("tsserverProjectSystem project references", () => {
92149336
const aTs: File = {
92159337
path: "/a/a.ts",

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6948,7 +6948,7 @@ declare namespace ts.server.protocol {
69486948
* begin with prefix.
69496949
*/
69506950
interface CompletionsRequest extends FileLocationRequest {
6951-
command: CommandTypes.Completions;
6951+
command: CommandTypes.Completions | CommandTypes.CompletionInfo;
69526952
arguments: CompletionsRequestArgs;
69536953
}
69546954
/**

0 commit comments

Comments
 (0)