From 1836bdb0cbae5fcc432d2dda2f78a484f10dca3e Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 24 Mar 2022 10:20:33 -0700 Subject: [PATCH 1/8] add label details to completion entry --- src/server/protocol.ts | 19 ++++++++++ src/server/session.ts | 35 +++++++++++++++++-- src/services/types.ts | 6 ++++ .../reference/api/tsserverlibrary.d.ts | 23 ++++++++++++ tests/baselines/reference/api/typescript.d.ts | 5 +++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 35e941cabe253..c6b03b2839d6d 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2290,6 +2290,10 @@ namespace ts.server.protocol { * Human-readable description of the `source`. */ sourceDisplay?: SymbolDisplayPart[]; + /** + * Additional details for the label. + */ + labelDetails?: CompletionEntryLabelDetails; /** * If true, this completion should be highlighted as recommended. There will only be one of these. * This will be set when we know the user should write an expression with a certain type and that type is an enum or constructable class. @@ -2319,6 +2323,21 @@ namespace ts.server.protocol { data?: unknown; } + export interface CompletionEntryLabelDetails { + /** + * An optional string which is rendered less prominently directly after + * {@link CompletionEntry.name name}, without any spacing. Should be + * used for function signatures or type annotations. + */ + detail?: string; + /** + * An optional string which is rendered less prominently after + * {@link CompletionEntryLabelDetails.detail}. Should be used for fully qualified + * names or file path. + */ + description?: string; + } + /** * Additional completion entry details, available on demand */ diff --git a/src/server/session.ts b/src/server/session.ts index 51585b02f169f..5123867f4334c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1837,10 +1837,41 @@ namespace ts.server { 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, sourceDisplay, isSnippet, isRecommended, isPackageJsonImport, isImportStatementCompletion, data } = entry; + const { + name, + kind, + kindModifiers, + sortText, + insertText, + replacementSpan, + hasAction, + source, + sourceDisplay, + labelDetails, + isSnippet, + isRecommended, + isPackageJsonImport, + isImportStatementCompletion, + data } = entry; const convertedSpan = replacementSpan ? toProtocolTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. - return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, isSnippet, hasAction: hasAction || undefined, source, sourceDisplay, isRecommended, isPackageJsonImport, isImportStatementCompletion, data }; + return { + name, + kind, + kindModifiers, + sortText, + insertText, + replacementSpan: convertedSpan, + isSnippet, + hasAction: hasAction || undefined, + source, + sourceDisplay, + labelDetails, + isRecommended, + isPackageJsonImport, + isImportStatementCompletion, + data + }; } }); diff --git a/src/services/types.ts b/src/services/types.ts index a32fa6599fa22..19749416467ab 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1232,6 +1232,7 @@ namespace ts { hasAction?: true; source?: string; sourceDisplay?: SymbolDisplayPart[]; + labelDetails?: CompletionEntryLabelDetails; isRecommended?: true; isFromUncheckedFile?: true; isPackageJsonImport?: true; @@ -1247,6 +1248,11 @@ namespace ts { data?: CompletionEntryData; } + export interface CompletionEntryLabelDetails { + detail?: string; + description?: string; + } + export interface CompletionEntryDetails { name: string; kind: ScriptElementKind; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 32bbdc4c79a39..e2df210f9e6e3 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6485,6 +6485,7 @@ declare namespace ts { hasAction?: true; source?: string; sourceDisplay?: SymbolDisplayPart[]; + labelDetails?: CompletionEntryLabelDetails; isRecommended?: true; isFromUncheckedFile?: true; isPackageJsonImport?: true; @@ -6499,6 +6500,10 @@ declare namespace ts { */ data?: CompletionEntryData; } + interface CompletionEntryLabelDetails { + detail?: string; + description?: string; + } interface CompletionEntryDetails { name: string; kind: ScriptElementKind; @@ -8708,6 +8713,10 @@ declare namespace ts.server.protocol { * Human-readable description of the `source`. */ sourceDisplay?: SymbolDisplayPart[]; + /** + * Additional details for the label. + */ + labelDetails?: CompletionEntryLabelDetails; /** * If true, this completion should be highlighted as recommended. There will only be one of these. * This will be set when we know the user should write an expression with a certain type and that type is an enum or constructable class. @@ -8736,6 +8745,20 @@ declare namespace ts.server.protocol { */ data?: unknown; } + interface CompletionEntryLabelDetails { + /** + * An optional string which is rendered less prominently directly after + * {@link CompletionEntry.name name}, without any spacing. Should be + * used for function signatures or type annotations. + */ + detail?: string; + /** + * An optional string which is rendered less prominently after + * {@link CompletionEntryLabelDetails.detail}. Should be used for fully qualified + * names or file path. + */ + description?: string; + } /** * Additional completion entry details, available on demand */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 9f9f42ebdfa62..8d9fa645fcc74 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -6485,6 +6485,7 @@ declare namespace ts { hasAction?: true; source?: string; sourceDisplay?: SymbolDisplayPart[]; + labelDetails?: CompletionEntryLabelDetails; isRecommended?: true; isFromUncheckedFile?: true; isPackageJsonImport?: true; @@ -6499,6 +6500,10 @@ declare namespace ts { */ data?: CompletionEntryData; } + interface CompletionEntryLabelDetails { + detail?: string; + description?: string; + } interface CompletionEntryDetails { name: string; kind: ScriptElementKind; From 0c375613cd7d6aea9896c9461ba1bf73dfd9e31d Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 24 Mar 2022 11:03:21 -0700 Subject: [PATCH 2/8] Use label details for obj literal method completions --- src/services/completions.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index f2f7e83d5fbb5..eeab6f257ede9 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -98,7 +98,7 @@ namespace ts.Completions { interface SymbolOriginInfoObjectLiteralMethod extends SymbolOriginInfo { importAdder: codefix.ImportAdder, insertText: string, - sourceDisplay: SymbolDisplayPart[], + labelDetails: CompletionEntryLabelDetails, isSnippet?: true, } @@ -706,6 +706,7 @@ namespace ts.Completions { let source = getSourceFromOrigin(origin); let sourceDisplay; let hasAction; + let labelDetails; const typeChecker = program.getTypeChecker(); const insertQuestionDot = origin && originIsNullableMember(origin); @@ -780,7 +781,7 @@ namespace ts.Completions { if (origin && originIsObjectLiteralMethod(origin)) { let importAdder; - ({ insertText, isSnippet, importAdder, sourceDisplay } = origin); + ({ insertText, isSnippet, importAdder, labelDetails } = origin); source = CompletionSource.ObjectLiteralMethodSnippet; sortText = SortText.SortBelow(sortText); if (importAdder.hasFixes()) { @@ -842,6 +843,7 @@ namespace ts.Completions { insertText, replacementSpan, sourceDisplay, + labelDetails, isSnippet, isPackageJsonImport: originIsPackageJsonImport(origin) || undefined, isImportStatementCompletion: !!importCompletionNode || undefined, @@ -1066,7 +1068,7 @@ namespace ts.Completions { options: CompilerOptions, preferences: UserPreferences, formatContext: formatting.FormatContext | undefined, - ): { insertText: string, isSnippet?: true, importAdder: codefix.ImportAdder, sourceDisplay: SymbolDisplayPart[] } | undefined { + ): { insertText: string, isSnippet?: true, importAdder: codefix.ImportAdder, labelDetails: CompletionEntryLabelDetails } | undefined { const isSnippet = preferences.includeCompletionsWithSnippetText || undefined; let insertText: string = name; @@ -1092,16 +1094,22 @@ namespace ts.Completions { insertText = printer.printSnippetList(ListFormat.CommaDelimited | ListFormat.AllowTrailingComma, factory.createNodeArray([method], /*hasTrailingComma*/ true), sourceFile); } + const signaturePrinter = createPrinter({ + removeComments: true, + module: options.module, + target: options.target, + omitTrailingSemicolon: true, + }); const methodSignature = factory.createMethodSignature( method.modifiers, - method.name, + /*name*/ "", method.questionToken, method.typeParameters, method.parameters, method.type); - const sourceDisplay = nodeToDisplayParts(methodSignature, enclosingDeclaration); + const labelDetails = { detail: signaturePrinter.printNode(EmitHint.Unspecified, methodSignature, sourceFile) }; - return { isSnippet, insertText, importAdder, sourceDisplay }; + return { isSnippet, insertText, importAdder, labelDetails }; }; From e6a8abf9ea2822d1cdc19b1547223b888939f40c Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 24 Mar 2022 15:46:08 -0700 Subject: [PATCH 3/8] add label details support flag --- src/compiler/types.ts | 1 + src/server/protocol.ts | 4 ++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 5 +++++ tests/baselines/reference/api/typescript.d.ts | 1 + tests/cases/fourslash/fourslash.ts | 1 + 5 files changed, 12 insertions(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1a9030bb0f55c..20952ab0f7980 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8753,6 +8753,7 @@ namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/src/server/protocol.ts b/src/server/protocol.ts index c6b03b2839d6d..986981761adfd 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -3432,6 +3432,10 @@ namespace ts.server.protocol { * in addition to `const objectLiteral: T = { foo }`. */ readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + /** + * Indicates whether {@link CompletionEntry.labelDetails completion entry label details} are supported. + */ + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e2df210f9e6e3..594ec7e0228d4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4100,6 +4100,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ @@ -9659,6 +9660,10 @@ declare namespace ts.server.protocol { * in addition to `const objectLiteral: T = { foo }`. */ readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + /** + * Indicates whether {@link CompletionEntry.labelDetails completion entry label details} are supported. + */ + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8d9fa645fcc74..08e278195947a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4100,6 +4100,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 147bb243091fe..d8b70b74eefee 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -648,6 +648,7 @@ declare namespace FourSlashInterface { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; + readonly includeCompletionsWithLabelDetails?: boolean; readonly allowIncompleteCompletions?: boolean; /** @deprecated use `includeCompletionsWithInsertText` */ readonly includeInsertTextCompletions?: boolean; From 4864a3e3428f4da4d522a52c1f8deb324cd29c3d Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 24 Mar 2022 16:59:15 -0700 Subject: [PATCH 4/8] add label details support to fourslash --- src/harness/fourslashImpl.ts | 2 ++ src/harness/fourslashInterfaceImpl.ts | 6 ++++++ tests/cases/fourslash/fourslash.ts | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index a24e1870beba2..71886f8ff5f26 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -983,6 +983,8 @@ namespace FourSlash { assert.equal(actual.isPackageJsonImport, expected.isPackageJsonImport, `At entry ${actual.name}: Expected 'isPackageJsonImport' properties to match`); } + assert.equal(actual.labelDetails?.description, expected.labelDetails?.description, `At entry ${actual.name}: Expected 'labelDetails.description' properties to match`); + assert.equal(actual.labelDetails?.detail, expected.labelDetails?.detail, `At entry ${actual.name}: Expected 'labelDetails.detail' properties to match`); assert.equal(actual.hasAction, expected.hasAction, `At entry ${actual.name}: Expected 'hasAction' properties to match`); assert.equal(actual.isRecommended, expected.isRecommended, `At entry ${actual.name}: Expected 'isRecommended' properties to match'`); assert.equal(actual.isSnippet, expected.isSnippet, `At entry ${actual.name}: Expected 'isSnippet' properties to match`); diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 976fdf9220ba3..dfe3808c8e5d8 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1719,10 +1719,16 @@ namespace FourSlashInterface { readonly text?: string; readonly documentation?: string; readonly sourceDisplay?: string; + readonly labelDetails?: ExpectedCompletionEntryLabelDetails; readonly tags?: readonly ts.JSDocTagInfo[]; readonly sortText?: ts.Completions.SortText; } + export interface ExpectedCompletionEntryLabelDetails { + detail?: string; + description?: string; + } + export type ExpectedExactCompletionsPlus = readonly ExpectedCompletionEntry[] & { plusFunctionName: string, plusArgument: readonly ExpectedCompletionEntry[] diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index d8b70b74eefee..0860369afb7ad 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -700,6 +700,12 @@ declare namespace FourSlashInterface { readonly documentation?: string; readonly tags?: ReadonlyArray; readonly sourceDisplay?: string; + readonly labelDetails?: ExpectedCompletionEntryLabelDetails; + } + + export interface ExpectedCompletionEntryLabelDetails { + detail?: string; + description?: string; } interface VerifySignatureHelpOptions { From fe5a809d6f994f26459078e944cdd81d1662a729 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 24 Mar 2022 17:54:37 -0700 Subject: [PATCH 5/8] support both label details and non-label details in object literal method snippets --- src/services/completions.ts | 4 ++ .../completionsObjectLiteralMethod1.ts | 43 +++++++++++++++++++ .../completionsObjectLiteralMethod2.ts | 5 +++ .../completionsObjectLiteralMethod3.ts | 14 ++++++ 4 files changed, 66 insertions(+) diff --git a/src/services/completions.ts b/src/services/completions.ts index eeab6f257ede9..c4f5e46a053bc 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -782,6 +782,10 @@ namespace ts.Completions { if (origin && originIsObjectLiteralMethod(origin)) { let importAdder; ({ insertText, isSnippet, importAdder, labelDetails } = origin); + if (!preferences.includeCompletionsWithLabelDetails) { + name = name + labelDetails.detail; + labelDetails = undefined; + } source = CompletionSource.ObjectLiteralMethodSnippet; sortText = SortText.SortBelow(sortText); if (importAdder.hasFixes()) { diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod1.ts b/tests/cases/fourslash/completionsObjectLiteralMethod1.ts index e6fef55cfa4ff..9a82d6f9d2b3c 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod1.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod1.ts @@ -38,6 +38,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -51,6 +52,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "bar(x: number): void {\n},", + labelDetails: { + detail: "(x: number): void", + }, }, ], }); @@ -60,6 +64,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -73,6 +78,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "bar(x: number): void {\n},", + labelDetails: { + detail: "(x: number): void", + }, }, { name: "foo", @@ -85,6 +93,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "foo")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "foo(x: string): string {\n},", + labelDetails: { + detail: "(x: string): string", + }, }, ], }); @@ -110,6 +121,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -123,6 +135,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "\"space bar\"")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "\"space bar\"(): string {\n},", + labelDetails: { + detail: "(): string", + }, }, ], }); @@ -132,6 +147,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: true, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -146,6 +162,33 @@ verify.completions({ source: completion.CompletionSource.ObjectLiteralMethodSnippet, isSnippet: true, insertText: "bar(x: number): void {\n $0\n},", + labelDetails: { + detail: "(x: number): void", + }, + }, + ], +}); +verify.completions({ + marker: "a", + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: false, + }, + includes: [ + { + name: "bar", + sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar"), + insertText: undefined, + }, + { + name: "bar(x: number): void", + sortText: completion.SortText.SortBelow( + completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")), + source: completion.CompletionSource.ObjectLiteralMethodSnippet, + isSnippet: true, + insertText: "bar(x: number): void {\n $0\n},", }, ], }); diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod2.ts b/tests/cases/fourslash/completionsObjectLiteralMethod2.ts index 08e2fa824a79c..7cf9199eee3f8 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod2.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod2.ts @@ -24,6 +24,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -38,6 +39,9 @@ verify.completions({ source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "foo(f: IFoo): void {\n},", hasAction: true, + labelDetails: { + detail: "(f: IFoo): void", + }, }, ], }); @@ -47,6 +51,7 @@ verify.applyCodeActionFromCompletion("a", { includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, name: "foo", source: completion.CompletionSource.ObjectLiteralMethodSnippet, diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod3.ts b/tests/cases/fourslash/completionsObjectLiteralMethod3.ts index 96aa3467540f1..eeaafd8b7590f 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod3.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod3.ts @@ -39,6 +39,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -52,6 +53,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "M")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "M(x: number): void {\n},", + labelDetails: { + detail: "(x: number): void", + }, }, ], }); @@ -93,6 +97,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, + includeCompletionsWithLabelDetails: true, }, includes: [ { @@ -106,6 +111,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "M")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "M(x: number): void {\n},", + labelDetails: { + detail: "(x: number): void", + }, }, { name: "N", @@ -118,6 +126,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "N")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "N(x: string): void {\n},", + labelDetails: { + detail: "(x: string): void", + }, }, { name: "O", @@ -130,6 +141,9 @@ verify.completions({ completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "O")), source: completion.CompletionSource.ObjectLiteralMethodSnippet, insertText: "O(): void {\n},", + labelDetails: { + detail: "(): void", + }, }, ], }); \ No newline at end of file From 41db01cc771be60bba22cc964b4d9770561dd33a Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 29 Mar 2022 11:38:16 -0700 Subject: [PATCH 6/8] CR fixes --- src/compiler/types.ts | 2 +- src/server/protocol.ts | 3 ++- src/services/completions.ts | 6 ++++-- .../cases/fourslash/completionsObjectLiteralMethod1.ts | 10 +++++----- .../cases/fourslash/completionsObjectLiteralMethod2.ts | 4 ++-- .../cases/fourslash/completionsObjectLiteralMethod3.ts | 4 ++-- tests/cases/fourslash/fourslash.ts | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 20952ab0f7980..788853371b042 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8753,7 +8753,7 @@ namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 986981761adfd..426eccb2b1325 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -3434,8 +3434,9 @@ namespace ts.server.protocol { readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; /** * Indicates whether {@link CompletionEntry.labelDetails completion entry label details} are supported. + * If not, contents of `labelDetails` may be included in the {@link CompletionEntry.name} property. */ - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/src/services/completions.ts b/src/services/completions.ts index c4f5e46a053bc..bc813b400de96 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -782,7 +782,7 @@ namespace ts.Completions { if (origin && originIsObjectLiteralMethod(origin)) { let importAdder; ({ insertText, isSnippet, importAdder, labelDetails } = origin); - if (!preferences.includeCompletionsWithLabelDetails) { + if (!preferences.useLabelDetailsInCompletionEntries) { name = name + labelDetails.detail; labelDetails = undefined; } @@ -1104,8 +1104,10 @@ namespace ts.Completions { target: options.target, omitTrailingSemicolon: true, }); + // The `labelDetails.detail` will be displayed right beside the method name, + // so we drop the name (and modifiers) from the signature. const methodSignature = factory.createMethodSignature( - method.modifiers, + /*modifiers*/ undefined, /*name*/ "", method.questionToken, method.typeParameters, diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod1.ts b/tests/cases/fourslash/completionsObjectLiteralMethod1.ts index 9a82d6f9d2b3c..2802c9b06a341 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod1.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod1.ts @@ -38,7 +38,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -64,7 +64,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -121,7 +121,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -147,7 +147,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: true, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -174,7 +174,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: true, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: false, + useLabelDetailsInCompletionEntries: false, }, includes: [ { diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod2.ts b/tests/cases/fourslash/completionsObjectLiteralMethod2.ts index 7cf9199eee3f8..6543e75337fb2 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod2.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod2.ts @@ -24,7 +24,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -51,7 +51,7 @@ verify.applyCodeActionFromCompletion("a", { includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, name: "foo", source: completion.CompletionSource.ObjectLiteralMethodSnippet, diff --git a/tests/cases/fourslash/completionsObjectLiteralMethod3.ts b/tests/cases/fourslash/completionsObjectLiteralMethod3.ts index eeaafd8b7590f..170df601ac1d1 100644 --- a/tests/cases/fourslash/completionsObjectLiteralMethod3.ts +++ b/tests/cases/fourslash/completionsObjectLiteralMethod3.ts @@ -39,7 +39,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { @@ -97,7 +97,7 @@ verify.completions({ includeCompletionsWithInsertText: true, includeCompletionsWithSnippetText: false, includeCompletionsWithObjectLiteralMethodSnippets: true, - includeCompletionsWithLabelDetails: true, + useLabelDetailsInCompletionEntries: true, }, includes: [ { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 0860369afb7ad..a02e06a574c05 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -648,7 +648,7 @@ declare namespace FourSlashInterface { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; /** @deprecated use `includeCompletionsWithInsertText` */ readonly includeInsertTextCompletions?: boolean; From a6299ca3f0d68d66a2138439c003dc7bc3d7d46b Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 29 Mar 2022 17:59:33 -0700 Subject: [PATCH 7/8] fixes after rebasing --- src/services/completions.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 5 +++-- tests/baselines/reference/api/typescript.d.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index bc813b400de96..0e936a774d580 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1072,7 +1072,7 @@ namespace ts.Completions { options: CompilerOptions, preferences: UserPreferences, formatContext: formatting.FormatContext | undefined, - ): { insertText: string, isSnippet?: true, importAdder: codefix.ImportAdder, labelDetails: CompletionEntryLabelDetails } | undefined { + ): { insertText: string, isSnippet?: true, importAdder: codefix.ImportAdder, labelDetails: CompletionEntryLabelDetails } | undefined { const isSnippet = preferences.includeCompletionsWithSnippetText || undefined; let insertText: string = name; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 594ec7e0228d4..e21f42f5bc214 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4100,7 +4100,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ @@ -9662,8 +9662,9 @@ declare namespace ts.server.protocol { readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; /** * Indicates whether {@link CompletionEntry.labelDetails completion entry label details} are supported. + * If not, contents of `labelDetails` may be included in the {@link CompletionEntry.name} property. */ - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 08e278195947a..cb79446a1da5e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4100,7 +4100,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly includeCompletionsWithClassMemberSnippets?: boolean; readonly includeCompletionsWithObjectLiteralMethodSnippets?: boolean; - readonly includeCompletionsWithLabelDetails?: boolean; + readonly useLabelDetailsInCompletionEntries?: boolean; readonly allowIncompleteCompletions?: boolean; readonly importModuleSpecifierPreference?: "shortest" | "project-relative" | "relative" | "non-relative"; /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ From 00f000983e3f5b644af34e5badb3aa2c8d9f65a3 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 30 Mar 2022 12:15:58 -0700 Subject: [PATCH 8/8] fix tsserver tests --- src/testRunner/unittests/tsserver/completions.ts | 3 ++- src/testRunner/unittests/tsserver/partialSemanticServer.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/completions.ts b/src/testRunner/unittests/tsserver/completions.ts index e3f5652461445..ab84366efc933 100644 --- a/src/testRunner/unittests/tsserver/completions.ts +++ b/src/testRunner/unittests/tsserver/completions.ts @@ -42,7 +42,8 @@ namespace ts.projectSystem { source: "/a", sourceDisplay: undefined, isSnippet: undefined, - data: { exportName: "foo", fileName: "/a.ts", ambientModuleName: undefined, isPackageJsonImport: undefined } + data: { exportName: "foo", fileName: "/a.ts", ambientModuleName: undefined, isPackageJsonImport: undefined }, + labelDetails: undefined, }; // `data.exportMapKey` contains a SymbolId so should not be mocked up with an expected value here. diff --git a/src/testRunner/unittests/tsserver/partialSemanticServer.ts b/src/testRunner/unittests/tsserver/partialSemanticServer.ts index 290cd1cade215..2aee331883dcf 100644 --- a/src/testRunner/unittests/tsserver/partialSemanticServer.ts +++ b/src/testRunner/unittests/tsserver/partialSemanticServer.ts @@ -75,6 +75,7 @@ import { something } from "something"; data: undefined, sourceDisplay: undefined, isSnippet: undefined, + labelDetails: undefined, }; } });