Skip to content

Commit 2f43308

Browse files
zardoyandrewbranch
andauthored
Add API option to getCompletionsAtPosition to expose completion symbol information (#52560)
Co-authored-by: Andrew Branch <[email protected]>
1 parent 1513649 commit 2f43308

File tree

6 files changed

+66
-6
lines changed

6 files changed

+66
-6
lines changed

src/services/completions.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ export function getCompletionsAtPosition(
643643
completionKind: CompletionTriggerKind | undefined,
644644
cancellationToken: CancellationToken,
645645
formatContext?: formatting.FormatContext,
646+
includeSymbol = false
646647
): CompletionInfo | undefined {
647648
const { previousToken } = getRelevantTokens(position, sourceFile);
648649
if (triggerCharacter && !isInString(sourceFile, position, previousToken) && !isValidTrigger(sourceFile, triggerCharacter, previousToken, position)) {
@@ -672,7 +673,7 @@ export function getCompletionsAtPosition(
672673
incompleteCompletionsCache?.clear();
673674
}
674675

675-
const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, compilerOptions, host, program, log, preferences);
676+
const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, previousToken, compilerOptions, host, program, log, preferences, includeSymbol);
676677
if (stringCompletions) {
677678
return stringCompletions;
678679
}
@@ -689,7 +690,7 @@ export function getCompletionsAtPosition(
689690

690691
switch (completionData.kind) {
691692
case CompletionDataKind.Data:
692-
const response = completionInfoFromData(sourceFile, host, program, compilerOptions, log, completionData, preferences, formatContext, position);
693+
const response = completionInfoFromData(sourceFile, host, program, compilerOptions, log, completionData, preferences, formatContext, position, includeSymbol);
693694
if (response?.isIncomplete) {
694695
incompleteCompletionsCache?.set(response);
695696
}
@@ -863,7 +864,8 @@ function completionInfoFromData(
863864
completionData: CompletionData,
864865
preferences: UserPreferences,
865866
formatContext: formatting.FormatContext | undefined,
866-
position: number
867+
position: number,
868+
includeSymbol: boolean | undefined,
867869
): CompletionInfo | undefined {
868870
const {
869871
symbols,
@@ -948,6 +950,7 @@ function completionInfoFromData(
948950
symbolToSortTextMap,
949951
isJsxIdentifierExpected,
950952
isRightOfOpenTag,
953+
includeSymbol
951954
);
952955

953956
if (keywordFilters !== KeywordCompletionFilters.None) {
@@ -1267,6 +1270,7 @@ function createCompletionEntry(
12671270
formatContext: formatting.FormatContext | undefined,
12681271
isJsxIdentifierExpected: boolean | undefined,
12691272
isRightOfOpenTag: boolean | undefined,
1273+
includeSymbol: boolean
12701274
): CompletionEntry | undefined {
12711275
let insertText: string | undefined;
12721276
let replacementSpan = getReplacementSpanForContextToken(replacementToken);
@@ -1422,6 +1426,7 @@ function createCompletionEntry(
14221426
isPackageJsonImport: originIsPackageJsonImport(origin) || undefined,
14231427
isImportStatementCompletion: !!importStatementCompletion || undefined,
14241428
data,
1429+
...includeSymbol ? { symbol } : undefined
14251430
};
14261431
}
14271432

@@ -2051,6 +2056,7 @@ export function getCompletionEntriesFromSymbols(
20512056
symbolToSortTextMap?: SymbolSortTextMap,
20522057
isJsxIdentifierExpected?: boolean,
20532058
isRightOfOpenTag?: boolean,
2059+
includeSymbol = false
20542060
): UniqueNameSet {
20552061
const start = timestamp();
20562062
const variableDeclaration = getVariableDeclaration(location);
@@ -2096,6 +2102,7 @@ export function getCompletionEntriesFromSymbols(
20962102
formatContext,
20972103
isJsxIdentifierExpected,
20982104
isRightOfOpenTag,
2105+
includeSymbol
20992106
);
21002107
if (!entry) {
21012108
continue;

src/services/services.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,8 @@ export function createLanguageService(
19901990
options.triggerCharacter,
19911991
options.triggerKind,
19921992
cancellationToken,
1993-
formattingSettings && formatting.getFormatContext(formattingSettings, host));
1993+
formattingSettings && formatting.getFormatContext(formattingSettings, host),
1994+
options.includeSymbol);
19941995
}
19951996

19961997
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = emptyOptions, data?: CompletionEntryData): CompletionEntryDetails | undefined {

src/services/stringCompletions.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,16 @@ export function getStringLiteralCompletions(
192192
host: LanguageServiceHost,
193193
program: Program,
194194
log: Log,
195-
preferences: UserPreferences): CompletionInfo | undefined {
195+
preferences: UserPreferences,
196+
includeSymbol: boolean): CompletionInfo | undefined {
196197
if (isInReferenceComment(sourceFile, position)) {
197198
const entries = getTripleSlashReferenceCompletion(sourceFile, position, options, host);
198199
return entries && convertPathCompletions(entries);
199200
}
200201
if (isInString(sourceFile, position, contextToken)) {
201202
if (!contextToken || !isStringLiteralLike(contextToken)) return undefined;
202203
const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, program.getTypeChecker(), options, host, preferences);
203-
return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences, position);
204+
return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences, position, includeSymbol);
204205
}
205206
}
206207

@@ -214,6 +215,7 @@ function convertStringLiteralCompletions(
214215
options: CompilerOptions,
215216
preferences: UserPreferences,
216217
position: number,
218+
includeSymbol: boolean,
217219
): CompletionInfo | undefined {
218220
if (completion === undefined) {
219221
return undefined;
@@ -241,6 +243,17 @@ function convertStringLiteralCompletions(
241243
preferences,
242244
options,
243245
/*formatContext*/ undefined,
246+
/*isTypeOnlyLocation */ undefined,
247+
/*propertyAccessToConvert*/ undefined,
248+
/*jsxIdentifierExpected*/ undefined,
249+
/*isJsxInitializer*/ undefined,
250+
/*importStatementCompletion*/ undefined,
251+
/*recommendedCompletion*/ undefined,
252+
/*symbolToOriginInfoMap*/ undefined,
253+
/*symbolToSortTextMap*/ undefined,
254+
/*isJsxIdentifierExpected*/ undefined,
255+
/*isRightOfOpenTag*/ undefined,
256+
includeSymbol
244257
); // Target will not be used, so arbitrary
245258
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, optionalReplacementSpan, entries };
246259
}

src/services/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,13 @@ export interface GetCompletionsAtPositionOptions extends UserPreferences {
700700
*/
701701
triggerCharacter?: CompletionsTriggerCharacter;
702702
triggerKind?: CompletionTriggerKind;
703+
/**
704+
* Include a `symbol` property on each completion entry object.
705+
* Symbols reference cyclic data structures and sometimes an entire TypeChecker instance,
706+
* so use caution when serializing or retaining completion entries retrieved with this option.
707+
* @default false
708+
*/
709+
includeSymbol?: boolean
703710
/** @deprecated Use includeCompletionsForModuleExports */
704711
includeExternalModuleExports?: boolean;
705712
/** @deprecated Use includeCompletionsWithInsertText */
@@ -1379,6 +1386,12 @@ export interface CompletionEntry {
13791386
isFromUncheckedFile?: true;
13801387
isPackageJsonImport?: true;
13811388
isImportStatementCompletion?: true;
1389+
/**
1390+
* For API purposes.
1391+
* Included for non-string completions only when `includeSymbol: true` option is passed to `getCompletionsAtPosition`.
1392+
* @example Get declaration of completion: `symbol.valueDeclaration`
1393+
*/
1394+
symbol?: Symbol
13821395
/**
13831396
* A property to be sent back to TS Server in the CompletionDetailsRequest, along with `name`,
13841397
* that allows TS Server to look up the symbol represented by the completion item, disambiguating

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10073,6 +10073,13 @@ declare namespace ts {
1007310073
*/
1007410074
triggerCharacter?: CompletionsTriggerCharacter;
1007510075
triggerKind?: CompletionTriggerKind;
10076+
/**
10077+
* Include a `symbol` property on each completion entry object.
10078+
* Symbols reference cyclic data structures and sometimes an entire TypeChecker instance,
10079+
* so use caution when serializing or retaining completion entries retrieved with this option.
10080+
* @default false
10081+
*/
10082+
includeSymbol?: boolean;
1007610083
/** @deprecated Use includeCompletionsForModuleExports */
1007710084
includeExternalModuleExports?: boolean;
1007810085
/** @deprecated Use includeCompletionsWithInsertText */
@@ -10630,6 +10637,12 @@ declare namespace ts {
1063010637
isFromUncheckedFile?: true;
1063110638
isPackageJsonImport?: true;
1063210639
isImportStatementCompletion?: true;
10640+
/**
10641+
* For API purposes.
10642+
* Included for non-string completions only when `includeSymbol: true` option is passed to `getCompletionsAtPosition`.
10643+
* @example Get declaration of completion: `symbol.valueDeclaration`
10644+
*/
10645+
symbol?: Symbol;
1063310646
/**
1063410647
* A property to be sent back to TS Server in the CompletionDetailsRequest, along with `name`,
1063510648
* that allows TS Server to look up the symbol represented by the completion item, disambiguating

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6171,6 +6171,13 @@ declare namespace ts {
61716171
*/
61726172
triggerCharacter?: CompletionsTriggerCharacter;
61736173
triggerKind?: CompletionTriggerKind;
6174+
/**
6175+
* Include a `symbol` property on each completion entry object.
6176+
* Symbols reference cyclic data structures and sometimes an entire TypeChecker instance,
6177+
* so use caution when serializing or retaining completion entries retrieved with this option.
6178+
* @default false
6179+
*/
6180+
includeSymbol?: boolean;
61746181
/** @deprecated Use includeCompletionsForModuleExports */
61756182
includeExternalModuleExports?: boolean;
61766183
/** @deprecated Use includeCompletionsWithInsertText */
@@ -6728,6 +6735,12 @@ declare namespace ts {
67286735
isFromUncheckedFile?: true;
67296736
isPackageJsonImport?: true;
67306737
isImportStatementCompletion?: true;
6738+
/**
6739+
* For API purposes.
6740+
* Included for non-string completions only when `includeSymbol: true` option is passed to `getCompletionsAtPosition`.
6741+
* @example Get declaration of completion: `symbol.valueDeclaration`
6742+
*/
6743+
symbol?: Symbol;
67316744
/**
67326745
* A property to be sent back to TS Server in the CompletionDetailsRequest, along with `name`,
67336746
* that allows TS Server to look up the symbol represented by the completion item, disambiguating

0 commit comments

Comments
 (0)