Skip to content

Commit 07c4fcf

Browse files
committed
Improve new sort text system
1 parent 7c9cbdb commit 07c4fcf

6 files changed

+108
-62
lines changed

Diff for: src/harness/fourslashInterfaceImpl.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -950,9 +950,35 @@ namespace FourSlashInterface {
950950
}
951951

952952
export namespace Completion {
953-
export import SortText = ts.Completions.SortText;
953+
import SortTextType = ts.Completions.SortText;
954+
export type SortText = SortTextType;
954955
export import CompletionSource = ts.Completions.CompletionSource;
955956

957+
export const SortText = {
958+
// Presets
959+
LocalDeclarationPriority: "10" as SortText,
960+
LocationPriority: "11" as SortText,
961+
OptionalMember: "12" as SortText,
962+
MemberDeclaredBySpreadAssignment: "13" as SortText,
963+
SuggestedClassMembers: "14" as SortText,
964+
GlobalsOrKeywords: "15" as SortText,
965+
AutoImportSuggestions: "16" as SortText,
966+
JavascriptIdentifiers: "17" as SortText,
967+
968+
// Transformations
969+
Deprecated(sortText: SortText): SortText {
970+
return "z" + sortText as SortText;
971+
},
972+
973+
ObjectLiteralProperty(presetSortText: SortText, symbolDisplayName: string): SortText {
974+
return `${presetSortText}\0${symbolDisplayName}\0` as SortText;
975+
},
976+
977+
AddIsSnippetSuffix(sortText: SortText): SortText {
978+
return sortText + "1" as SortText;
979+
},
980+
};
981+
956982
const functionEntry = (name: string): ExpectedCompletionEntryObject => ({
957983
name,
958984
kind: "function",

Diff for: src/services/completions.ts

+32-21
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,31 @@ namespace ts.Completions {
66

77
export type Log = (message: string) => void;
88

9-
// NOTE: Make sure that each entry has the exact same number of digits
10-
// since many implementations will sort by string contents,
11-
// where "10" is considered less than "2".
12-
export enum SortText {
13-
LocalDeclarationPriority = "10",
14-
LocationPriority = "11",
15-
OptionalMember = "12",
16-
MemberDeclaredBySpreadAssignment = "13",
17-
SuggestedClassMembers = "14",
18-
GlobalsOrKeywords = "15",
19-
AutoImportSuggestions = "16",
20-
JavascriptIdentifiers = "17",
21-
}
9+
export type SortText = string & { __sortText: any };
10+
export const SortText = {
11+
// Presets
12+
LocalDeclarationPriority: "10" as SortText,
13+
LocationPriority: "11" as SortText,
14+
OptionalMember: "12" as SortText,
15+
MemberDeclaredBySpreadAssignment: "13" as SortText,
16+
SuggestedClassMembers: "14" as SortText,
17+
GlobalsOrKeywords: "15" as SortText,
18+
AutoImportSuggestions: "16" as SortText,
19+
JavascriptIdentifiers: "17" as SortText,
20+
21+
// Transformations
22+
Deprecated(sortText: SortText): SortText {
23+
return "z" + sortText as SortText;
24+
},
25+
26+
ObjectLiteralProperty(presetSortText: SortText, symbolDisplayName: string): SortText {
27+
return `${presetSortText}\0${symbolDisplayName}\0` as SortText;
28+
},
29+
30+
AddIsSnippetSuffix(sortText: SortText): SortText {
31+
return sortText + "1" as SortText;
32+
},
33+
};
2234

2335
/**
2436
* Special values for `CompletionInfo['source']` used to disambiguate
@@ -129,7 +141,6 @@ namespace ts.Completions {
129141

130142
/**
131143
* Map from symbol index in `symbols` -> SymbolOriginInfo.
132-
* Only populated for symbols that come from other modules.
133144
*/
134145
type SymbolOriginInfoMap = Record<number, SymbolOriginInfo>;
135146

@@ -767,7 +778,7 @@ namespace ts.Completions {
767778
}
768779
({ insertText, isSnippet, importAdder, sourceDisplay } = entry);
769780
source = CompletionSource.ObjectLiteralMethodSnippet;
770-
sortText = sortText + "1" as SortText;
781+
sortText = SortText.AddIsSnippetSuffix(sortText);
771782
if (importAdder.hasFixes()) {
772783
hasAction = true;
773784
}
@@ -1373,7 +1384,7 @@ namespace ts.Completions {
13731384

13741385
const { name, needsConvertPropertyAccess } = info;
13751386
const originalSortText = symbolToSortTextIdMap?.[getSymbolId(symbol)] ?? SortText.LocationPriority;
1376-
const sortText = (isDeprecated(symbol, typeChecker) ? "z" + originalSortText : originalSortText) as SortText;
1387+
const sortText = (isDeprecated(symbol, typeChecker) ? SortText.Deprecated(originalSortText) : originalSortText);
13771388
const entry = createCompletionEntry(
13781389
symbol,
13791390
sortText,
@@ -2950,6 +2961,7 @@ namespace ts.Completions {
29502961
* @returns true if 'symbols' was successfully populated; false otherwise.
29512962
*/
29522963
function tryGetObjectLikeCompletionSymbols(): GlobalsSearch | undefined {
2964+
const symbolsStartIndex = symbols.length;
29532965
const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
29542966
if (!objectLikeContainer) return GlobalsSearch.Continue;
29552967

@@ -3027,8 +3039,7 @@ namespace ts.Completions {
30273039
}
30283040
setSortTextToOptionalMember();
30293041
if (objectLikeContainer.kind === SyntaxKind.ObjectLiteralExpression && preferences.includeCompletionsWithInsertText) {
3030-
// >> TODO: specify `symbols` range?
3031-
transformObjectLiteralMembersSortText();
3042+
transformObjectLiteralMembersSortText(symbolsStartIndex);
30323043
}
30333044

30343045
return GlobalsSearch.Success;
@@ -3568,9 +3579,9 @@ namespace ts.Completions {
35683579
}
35693580
}
35703581

3571-
function transformObjectLiteralMembersSortText(): void {
3582+
function transformObjectLiteralMembersSortText(start: number): void {
35723583
const pastSymbolIds: Set<number> = new Set();
3573-
for (let i = 0; i < symbols.length; i++) {
3584+
for (let i = start; i < symbols.length; i++) {
35743585
const symbol = symbols[i];
35753586
const symbolId = getSymbolId(symbol);
35763587
if (pastSymbolIds.has(symbolId)) {
@@ -3588,7 +3599,7 @@ namespace ts.Completions {
35883599
if (displayName) {
35893600
const originalSortText = symbolToSortTextIdMap[symbolId] ?? SortText.LocationPriority;
35903601
const { name } = displayName;
3591-
symbolToSortTextIdMap[symbolId] = `${originalSortText}\0${name}\0` as SortText;
3602+
symbolToSortTextIdMap[symbolId] = SortText.ObjectLiteralProperty(originalSortText, name);
35923603
}
35933604
}
35943605
}

Diff for: tests/cases/fourslash/completionsObjectLiteralMethod1.ts

+16-11
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ verify.completions({
4141
includes: [
4242
{
4343
name: "bar",
44-
sortText: `${completion.SortText.LocationPriority}\0bar\0` as completion.SortText,
44+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar"),
4545
insertText: undefined,
4646
},
4747
{
4848
name: "bar",
49-
sortText: `${completion.SortText.LocationPriority}\0bar\0${1}` as completion.SortText,
49+
sortText: completion.SortText.AddIsSnippetSuffix(
50+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")),
5051
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
5152
insertText: "bar(x: number): void {\n},",
5253
},
@@ -61,23 +62,25 @@ verify.completions({
6162
includes: [
6263
{
6364
name: "bar",
64-
sortText: `${completion.SortText.LocationPriority}\0bar\0` as completion.SortText,
65+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar"),
6566
insertText: undefined,
6667
},
6768
{
6869
name: "bar",
69-
sortText: `${completion.SortText.LocationPriority}\0bar\0${1}` as completion.SortText,
70+
sortText: completion.SortText.AddIsSnippetSuffix(
71+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")),
7072
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
7173
insertText: "bar(x: number): void {\n},",
7274
},
7375
{
7476
name: "foo",
75-
sortText: `${completion.SortText.LocationPriority}\0foo\0` as completion.SortText,
77+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "foo"),
7678
insertText: undefined,
7779
},
7880
{
7981
name: "foo",
80-
sortText: `${completion.SortText.LocationPriority}\0foo\0${1}` as completion.SortText,
82+
sortText: completion.SortText.AddIsSnippetSuffix(
83+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "foo")),
8184
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
8285
insertText: "foo(x: string): string {\n},",
8386
},
@@ -92,7 +95,7 @@ verify.completions({
9295
exact: [
9396
{
9497
name: "buzz",
95-
sortText: `${completion.SortText.LocationPriority}\0buzz\0` as completion.SortText,
98+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "buzz"),
9699
// no declaration insert text, because this property has overloads
97100
insertText: undefined,
98101
},
@@ -107,12 +110,13 @@ verify.completions({
107110
includes: [
108111
{
109112
name: "\"space bar\"",
110-
sortText: `${completion.SortText.LocationPriority}\0${"\"space bar\""}\0` as completion.SortText,
113+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "\"space bar\""),
111114
insertText: undefined,
112115
},
113116
{
114117
name: "\"space bar\"",
115-
sortText: `${completion.SortText.LocationPriority}\0${"\"space bar\""}\0${1}` as completion.SortText,
118+
sortText: completion.SortText.AddIsSnippetSuffix(
119+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "\"space bar\"")),
116120
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
117121
insertText: "\"space bar\"(): string {\n},",
118122
},
@@ -127,12 +131,13 @@ verify.completions({
127131
includes: [
128132
{
129133
name: "bar",
130-
sortText: `${completion.SortText.LocationPriority}\0bar\0` as completion.SortText,
134+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar"),
131135
insertText: undefined,
132136
},
133137
{
134138
name: "bar",
135-
sortText: `${completion.SortText.LocationPriority}\0bar\0${1}` as completion.SortText,
139+
sortText: completion.SortText.AddIsSnippetSuffix(
140+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "bar")),
136141
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
137142
isSnippet: true,
138143
insertText: "bar(x: number): void {\n $0\n},",

Diff for: tests/cases/fourslash/completionsObjectLiteralMethod2.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ verify.completions({
2727
includes: [
2828
{
2929
name: "foo",
30-
sortText: completion.SortText.LocationPriority,
30+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "foo"),
3131
insertText: undefined,
3232
},
3333
{
3434
name: "foo",
35-
sortText: completion.SortText.OptionalMember,
35+
sortText: completion.SortText.AddIsSnippetSuffix(
36+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "foo")),
3637
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
3738
insertText: "foo(f: IFoo): void {\n},",
3839
hasAction: true,

Diff for: tests/cases/fourslash/completionsObjectLiteralMethod3.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ verify.completions({
4141
includes: [
4242
{
4343
name: "M",
44-
sortText: completion.SortText.LocationPriority,
44+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "M"),
4545
insertText: undefined,
4646
},
4747
{
4848
name: "M",
49-
sortText: completion.SortText.OptionalMember,
49+
sortText: completion.SortText.AddIsSnippetSuffix(
50+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "M")),
5051
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
5152
insertText: "M(x: number): void {\n},",
5253
},
@@ -61,7 +62,7 @@ verify.completions({
6162
includes: [
6263
{
6364
name: "M",
64-
sortText: completion.SortText.LocationPriority,
65+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "M"),
6566
insertText: undefined,
6667
},
6768
// No signature completion because type of `M` is intersection type
@@ -76,7 +77,7 @@ verify.completions({
7677
exact: [
7778
{
7879
name: "M",
79-
sortText: completion.SortText.LocationPriority,
80+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "M"),
8081
insertText: undefined,
8182
},
8283
// No signature completion because type of `M` is intersection type
@@ -91,34 +92,37 @@ verify.completions({
9192
includes: [
9293
{
9394
name: "M",
94-
sortText: completion.SortText.OptionalMember,
95+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "M"),
9596
insertText: undefined,
9697
},
9798
{
9899
name: "M",
99-
sortText: completion.SortText.OptionalMember,
100+
sortText: completion.SortText.AddIsSnippetSuffix(
101+
completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "M")),
100102
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
101103
insertText: "M(x: number): void {\n},",
102104
},
103105
{
104106
name: "N",
105-
sortText: completion.SortText.LocationPriority,
107+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "N"),
106108
insertText: undefined,
107109
},
108110
{
109111
name: "N",
110-
sortText: completion.SortText.OptionalMember,
112+
sortText: completion.SortText.AddIsSnippetSuffix(
113+
completion.SortText.ObjectLiteralProperty(completion.SortText.LocationPriority, "N")),
111114
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
112115
insertText: "N(x: string): void {\n},",
113116
},
114117
{
115118
name: "O",
116-
sortText: completion.SortText.OptionalMember,
119+
sortText: completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "O"),
117120
insertText: undefined,
118121
},
119122
{
120123
name: "O",
121-
sortText: completion.SortText.OptionalMember,
124+
sortText: completion.SortText.AddIsSnippetSuffix(
125+
completion.SortText.ObjectLiteralProperty(completion.SortText.OptionalMember, "O")),
122126
source: completion.CompletionSource.ObjectLiteralMethodSnippet,
123127
insertText: "O(): void {\n},",
124128
},

Diff for: tests/cases/fourslash/fourslash.ts

+16-17
Original file line numberDiff line numberDiff line change
@@ -838,23 +838,22 @@ declare namespace completion {
838838
interface GlobalsPlusOptions {
839839
noLib?: boolean;
840840
}
841-
export const enum SortText {
842-
LocalDeclarationPriority = "10",
843-
LocationPriority = "11",
844-
OptionalMember = "12",
845-
MemberDeclaredBySpreadAssignment = "13",
846-
SuggestedClassMembers = "14",
847-
GlobalsOrKeywords = "15",
848-
AutoImportSuggestions = "16",
849-
JavascriptIdentifiers = "17",
850-
DeprecatedLocalDeclarationPriority = "18",
851-
DeprecatedLocationPriority = "19",
852-
DeprecatedOptionalMember = "20",
853-
DeprecatedMemberDeclaredBySpreadAssignment = "21",
854-
DeprecatedSuggestedClassMembers = "22",
855-
DeprecatedGlobalsOrKeywords = "23",
856-
DeprecatedAutoImportSuggestions = "24"
857-
}
841+
export type SortText = string & { __sortText: any };
842+
export const SortText: {
843+
LocalDeclarationPriority: SortText,
844+
LocationPriority: SortText,
845+
OptionalMember: SortText,
846+
MemberDeclaredBySpreadAssignment: SortText,
847+
SuggestedClassMembers: SortText,
848+
GlobalsOrKeywords: SortText,
849+
AutoImportSuggestions: SortText,
850+
JavascriptIdentifiers: SortText,
851+
852+
Deprecated(sortText: SortText): SortText,
853+
ObjectLiteralProperty(presetSortText: SortText, symbolDisplayName: string): SortText,
854+
AddIsSnippetSuffix(sortText: SortText): SortText,
855+
};
856+
858857
export const enum CompletionSource {
859858
ThisProperty = "ThisProperty/",
860859
ClassMemberSnippet = "ClassMemberSnippet/",

0 commit comments

Comments
 (0)