From 407bb4d67e8058349ce531281018325e8364801f Mon Sep 17 00:00:00 2001 From: Apoorv Darshan Date: Mon, 16 Feb 2026 15:49:49 +0530 Subject: [PATCH] Deprioritize native Function methods in IntelliSense completions When autocompleting on a function value with custom properties, native Function prototype methods (apply, bind, call, etc.) now sort below custom properties. This is achieved by assigning SortText.SortBelow(LocationPriority) to members of the global Function, CallableFunction, and NewableFunction interfaces. Fixes #61426 --- src/harness/fourslashInterfaceImpl.ts | 6 +- src/services/completions.ts | 20 +- .../completionsCommentsClassMembers.baseline | 684 +++++++++--------- ...mpletionsCommitCharactersAfterDot.baseline | 32 +- .../tsserver/fourslashServer/completions02.js | 196 ++--- .../fourslash/completionListOnAliases2.ts | 2 +- .../completionListStaticProtectedMembers2.ts | 11 +- .../completionsFunctionCustomProperties.ts | 44 ++ tests/cases/fourslash/javaScriptPrototype1.ts | 2 +- tests/cases/fourslash/server/completions02.ts | 7 +- 10 files changed, 530 insertions(+), 474 deletions(-) create mode 100644 tests/cases/fourslash/completionsFunctionCustomProperties.ts diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 6178b2723f13e..8a08d1e05dab6 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1408,6 +1408,8 @@ export namespace Completion { sortText: SortText.GlobalsOrKeywords, })); + const deprioritizedSortText = SortText.SortBelow(SortText.LocationPriority); + export const functionMembers: readonly ExpectedCompletionEntryObject[] = [ methodEntry("apply"), methodEntry("call"), @@ -1416,7 +1418,7 @@ export namespace Completion { propertyEntry("length"), { name: "arguments", kind: "property", kindModifiers: "declare", text: "(property) Function.arguments: any" }, propertyEntry("caller"), - ].sort(compareExpectedCompletionEntries); + ].map(m => ({ ...m, sortText: deprioritizedSortText })).sort(compareExpectedCompletionEntries); export function functionMembersPlus(plus: readonly ExpectedCompletionEntryObject[]): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries("functionMembersPlus", functionMembers, plus); @@ -1448,7 +1450,7 @@ export namespace Completion { export const functionMembersWithPrototype: readonly ExpectedCompletionEntryObject[] = [ ...functionMembers, - propertyEntry("prototype"), + { ...propertyEntry("prototype"), sortText: deprioritizedSortText }, ].sort(compareExpectedCompletionEntries); export function functionMembersWithPrototypePlus(plus: readonly ExpectedCompletionEntryObject[]): ExpectedCompletionEntryObject[] { diff --git a/src/services/completions.ts b/src/services/completions.ts index 28d29136dab89..f7c2541d8c72b 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -3824,7 +3824,13 @@ function getCompletionData( // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part // of the individual types to a higher status since we know what they are. - symbols.push(...filter(getPropertiesForCompletion(type, typeChecker), s => typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, s))); + const uncheckedSymbols = filter(getPropertiesForCompletion(type, typeChecker), s => typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, s)); + for (const symbol of uncheckedSymbols) { + if (isNativeFunctionMember(symbol)) { + symbolToSortTextMap[getSymbolId(symbol)] = SortText.SortBelow(SortText.LocationPriority); + } + } + symbols.push(...uncheckedSymbols); } if (insertAwait && preferences.includeCompletionsWithInsertText) { @@ -3913,6 +3919,9 @@ function getCompletionData( if (isStaticProperty(symbol)) { symbolToSortTextMap[getSymbolId(symbol)] = SortText.LocalDeclarationPriority; } + else if (isNativeFunctionMember(symbol)) { + symbolToSortTextMap[getSymbolId(symbol)] = SortText.SortBelow(SortText.LocationPriority); + } } function addSymbolOriginInfo(symbol: Symbol) { @@ -5857,6 +5866,15 @@ function isStaticProperty(symbol: Symbol) { return !!(symbol.valueDeclaration && getEffectiveModifierFlags(symbol.valueDeclaration) & ModifierFlags.Static && isClassLike(symbol.valueDeclaration.parent)); } +function isNativeFunctionMember(symbol: Symbol): boolean { + const parent = symbol.parent; + if (!parent) return false; + const parentName = parent.escapedName; + if (parentName !== "Function" && parentName !== "CallableFunction" && parentName !== "NewableFunction") return false; + // A symbol is in the global scope if its parent is undefined + return parent.parent === undefined; +} + function tryGetObjectLiteralContextualType(node: ObjectLiteralExpression, typeChecker: TypeChecker) { const type = typeChecker.getContextualType(node); if (type) { diff --git a/tests/baselines/reference/completionsCommentsClassMembers.baseline b/tests/baselines/reference/completionsCommentsClassMembers.baseline index 83b68c30f5a4f..905d6ddb34c1a 100644 --- a/tests/baselines/reference/completionsCommentsClassMembers.baseline +++ b/tests/baselines/reference/completionsCommentsClassMembers.baseline @@ -926,13 +926,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // ^ @@ -1238,13 +1238,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // ^^ @@ -1400,13 +1400,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // } @@ -1567,13 +1567,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // ^^ @@ -1730,13 +1730,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // ^^^^^ @@ -2983,13 +2983,13 @@ // | (property) c1.s1: number // | (method) c1.s2(b: number): number // | (property) c1.s3: number +// | (property) c1.prototype: c1 // | (method) NewableFunction.apply(this: new () => T, thisArg: T): void (+1 overload) // | (property) Function.arguments: any // | (method) NewableFunction.bind(this: T, thisArg: any): T (+1 overload) // | (method) NewableFunction.call(this: new (...args: A) => T, thisArg: T, ...args: A): void // | (property) Function.caller: Function // | (property) Function.length: number -// | (property) c1.prototype: c1 // | (method) Function.toString(): string // | ---------------------------------------------------------------------- // var i1_s_f = c1.s2; @@ -34006,11 +34006,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34199,7 +34248,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34248,7 +34297,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34409,7 +34458,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34671,7 +34720,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34720,7 +34769,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -34765,60 +34814,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -44311,11 +44311,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -44504,7 +44553,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -44553,7 +44602,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -44714,7 +44763,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -44976,7 +45025,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -45025,7 +45074,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -45070,60 +45119,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50070,11 +50070,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50263,7 +50312,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50312,7 +50361,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50473,7 +50522,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50735,7 +50784,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50784,7 +50833,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -50829,60 +50878,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -55875,11 +55875,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56068,7 +56117,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56117,7 +56166,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56278,7 +56327,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56540,7 +56589,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56589,7 +56638,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -56634,60 +56683,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -61680,11 +61680,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -61873,7 +61922,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -61922,7 +61971,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -62083,7 +62132,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -62345,7 +62394,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -62394,7 +62443,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -62439,60 +62488,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -99762,11 +99762,60 @@ } ] }, + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "prototype", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "c1", + "kind": "className" + } + ], + "documentation": [] + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -99955,7 +100004,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -100004,7 +100053,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -100165,7 +100214,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -100427,7 +100476,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -100476,7 +100525,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -100521,60 +100570,11 @@ ], "documentation": [] }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "prototype", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "c1", - "kind": "className" - } - ], - "documentation": [] - }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", diff --git a/tests/baselines/reference/completionsCommitCharactersAfterDot.baseline b/tests/baselines/reference/completionsCommitCharactersAfterDot.baseline index 3e35e33ce2e79..4a80ff1235af0 100644 --- a/tests/baselines/reference/completionsCommitCharactersAfterDot.baseline +++ b/tests/baselines/reference/completionsCommitCharactersAfterDot.baseline @@ -260,7 +260,7 @@ "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -469,7 +469,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -518,7 +518,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -703,7 +703,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -993,7 +993,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1042,7 +1042,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1091,7 +1091,7 @@ "name": "prototype", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1140,7 +1140,7 @@ "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1218,7 +1218,7 @@ "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1427,7 +1427,7 @@ "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1476,7 +1476,7 @@ "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1661,7 +1661,7 @@ "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -1951,7 +1951,7 @@ "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -2000,7 +2000,7 @@ "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -2049,7 +2049,7 @@ "name": "prototype", "kind": "property", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", @@ -2098,7 +2098,7 @@ "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11", + "sortText": "111", "displayParts": [ { "text": "(", diff --git a/tests/baselines/reference/tsserver/fourslashServer/completions02.js b/tests/baselines/reference/tsserver/fourslashServer/completions02.js index 5f793a8e1b60e..8951c97560f0b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/completions02.js +++ b/tests/baselines/reference/tsserver/fourslashServer/completions02.js @@ -173,59 +173,59 @@ Info seq [hh:mm:ss:mss] response: "isMemberCompletion": true, "isNewIdentifierLocation": false, "entries": [ + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11" + }, + { + "name": "x", + "kind": "var", + "kindModifiers": "export", + "sortText": "11" + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11" - }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11" + "sortText": "111" }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11" - }, - { - "name": "x", - "kind": "var", - "kindModifiers": "export", - "sortText": "11" + "sortText": "111" } ], "defaultCommitCharacters": [ @@ -245,7 +245,7 @@ Info seq [hh:mm:ss:mss] request: "offset": 5, "entryNames": [ { - "name": "arguments" + "name": "x" } ] }, @@ -265,37 +265,29 @@ Info seq [hh:mm:ss:mss] response: "success": true, "body": [ { - "name": "arguments", - "kindModifiers": "declare", - "kind": "property", + "name": "x", + "kindModifiers": "export", + "kind": "var", "displayParts": [ { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" + "text": "var", + "kind": "keyword" }, { "text": " ", "kind": "space" }, { - "text": "Function", - "kind": "localName" + "text": "Foo", + "kind": "className" }, { "text": ".", "kind": "punctuation" }, { - "text": "arguments", - "kind": "propertyName" + "text": "x", + "kind": "localName" }, { "text": ":", @@ -306,7 +298,7 @@ Info seq [hh:mm:ss:mss] response: "kind": "space" }, { - "text": "any", + "text": "number", "kind": "keyword" } ], @@ -325,7 +317,7 @@ Info seq [hh:mm:ss:mss] request: "offset": 5, "entryNames": [ { - "name": "x" + "name": "arguments" } ] }, @@ -345,29 +337,37 @@ Info seq [hh:mm:ss:mss] response: "success": true, "body": [ { - "name": "x", - "kindModifiers": "export", - "kind": "var", + "name": "arguments", + "kindModifiers": "declare", + "kind": "property", "displayParts": [ { - "text": "var", - "kind": "keyword" + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" }, { "text": " ", "kind": "space" }, { - "text": "Foo", - "kind": "className" + "text": "Function", + "kind": "localName" }, { "text": ".", "kind": "punctuation" }, { - "text": "x", - "kind": "localName" + "text": "arguments", + "kind": "propertyName" }, { "text": ":", @@ -378,7 +378,7 @@ Info seq [hh:mm:ss:mss] response: "kind": "space" }, { - "text": "number", + "text": "any", "kind": "keyword" } ], @@ -598,59 +598,59 @@ Info seq [hh:mm:ss:mss] response: "isMemberCompletion": true, "isNewIdentifierLocation": false, "entries": [ + { + "name": "prototype", + "kind": "property", + "kindModifiers": "", + "sortText": "11" + }, + { + "name": "x", + "kind": "var", + "kindModifiers": "export", + "sortText": "11" + }, { "name": "apply", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "arguments", "kind": "property", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "bind", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "call", "kind": "method", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "caller", "kind": "property", "kindModifiers": "declare", - "sortText": "11" + "sortText": "111" }, { "name": "length", "kind": "property", "kindModifiers": "declare", - "sortText": "11" - }, - { - "name": "prototype", - "kind": "property", - "kindModifiers": "", - "sortText": "11" + "sortText": "111" }, { "name": "toString", "kind": "method", "kindModifiers": "declare", - "sortText": "11" - }, - { - "name": "x", - "kind": "var", - "kindModifiers": "export", - "sortText": "11" + "sortText": "111" } ], "defaultCommitCharacters": [ @@ -678,7 +678,7 @@ Info seq [hh:mm:ss:mss] request: "offset": 5, "entryNames": [ { - "name": "arguments" + "name": "x" } ] }, @@ -698,37 +698,29 @@ Info seq [hh:mm:ss:mss] response: "success": true, "body": [ { - "name": "arguments", - "kindModifiers": "declare", - "kind": "property", + "name": "x", + "kindModifiers": "export", + "kind": "var", "displayParts": [ { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" + "text": "var", + "kind": "keyword" }, { "text": " ", "kind": "space" }, { - "text": "Function", - "kind": "localName" + "text": "Foo", + "kind": "className" }, { "text": ".", "kind": "punctuation" }, { - "text": "arguments", - "kind": "propertyName" + "text": "x", + "kind": "localName" }, { "text": ":", @@ -739,7 +731,7 @@ Info seq [hh:mm:ss:mss] response: "kind": "space" }, { - "text": "any", + "text": "number", "kind": "keyword" } ], @@ -758,7 +750,7 @@ Info seq [hh:mm:ss:mss] request: "offset": 5, "entryNames": [ { - "name": "x" + "name": "arguments" } ] }, @@ -778,29 +770,37 @@ Info seq [hh:mm:ss:mss] response: "success": true, "body": [ { - "name": "x", - "kindModifiers": "export", - "kind": "var", + "name": "arguments", + "kindModifiers": "declare", + "kind": "property", "displayParts": [ { - "text": "var", - "kind": "keyword" + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" }, { "text": " ", "kind": "space" }, { - "text": "Foo", - "kind": "className" + "text": "Function", + "kind": "localName" }, { "text": ".", "kind": "punctuation" }, { - "text": "x", - "kind": "localName" + "text": "arguments", + "kind": "propertyName" }, { "text": ":", @@ -811,7 +811,7 @@ Info seq [hh:mm:ss:mss] response: "kind": "space" }, { - "text": "number", + "text": "any", "kind": "keyword" } ], diff --git a/tests/cases/fourslash/completionListOnAliases2.ts b/tests/cases/fourslash/completionListOnAliases2.ts index 6f41ab240de9c..864c221c50981 100644 --- a/tests/cases/fourslash/completionListOnAliases2.ts +++ b/tests/cases/fourslash/completionListOnAliases2.ts @@ -55,5 +55,5 @@ verify.completions( // var V { marker: "5", includes: "toFixed" }, // function F - { marker: "6", includes: "call" }, + { marker: "6", includes: { name: "call", sortText: completion.SortText.SortBelow(completion.SortText.LocationPriority) } }, ); diff --git a/tests/cases/fourslash/completionListStaticProtectedMembers2.ts b/tests/cases/fourslash/completionListStaticProtectedMembers2.ts index 17227a11a64c6..416030647759c 100644 --- a/tests/cases/fourslash/completionListStaticProtectedMembers2.ts +++ b/tests/cases/fourslash/completionListStaticProtectedMembers2.ts @@ -59,21 +59,14 @@ verify.completions( { // only public and protected methods of the base class are accessible through super marker: "4", - exact: [ + exact: completion.functionMembersPlus([ { name: "protectedMethod", sortText: completion.SortText.LocalDeclarationPriority }, { name: "protectedOverriddenMethod", sortText: completion.SortText.LocalDeclarationPriority }, { name: "protectedOverriddenProperty", sortText: completion.SortText.LocalDeclarationPriority }, { name: "protectedProperty", sortText: completion.SortText.LocalDeclarationPriority }, { name: "publicMethod", sortText: completion.SortText.LocalDeclarationPriority }, { name: "publicProperty", sortText: completion.SortText.LocalDeclarationPriority }, - { name: "apply", sortText: completion.SortText.LocationPriority }, - { name: "arguments", sortText: completion.SortText.LocationPriority }, - { name: "bind", sortText: completion.SortText.LocationPriority }, - { name: "call", sortText: completion.SortText.LocationPriority }, - { name: "caller", sortText: completion.SortText.LocationPriority }, - { name: "length", sortText: completion.SortText.LocationPriority }, { name: "prototype", sortText: completion.SortText.LocationPriority }, - { name: "toString", sortText: completion.SortText.LocationPriority }, - ], + ]), }, ); diff --git a/tests/cases/fourslash/completionsFunctionCustomProperties.ts b/tests/cases/fourslash/completionsFunctionCustomProperties.ts new file mode 100644 index 0000000000000..5032930fb5098 --- /dev/null +++ b/tests/cases/fourslash/completionsFunctionCustomProperties.ts @@ -0,0 +1,44 @@ +/// + +// @lib: es5 + +// Case 1: Function with custom properties — custom properties should appear above native Function methods +////declare function myFunc(): void; +////declare namespace myFunc { +//// const customProp: string; +//// function customMethod(): void; +////} +////myFunc./*1*/ + +// Case 2: User-defined Function interface in a module — should NOT be deprioritized +////declare module "myModule" { +//// interface Function { +//// mySpecialMethod(): void; +//// } +////} + +// Case 3: Static class members — should continue to work as before +////class MyClass { +//// static staticProp: number; +//// static staticMethod(): void {} +////} +////MyClass./*3*/ + +verify.completions( + { + marker: "1", + exact: [ + { name: "customMethod", kind: "function", kindModifiers: "declare", sortText: completion.SortText.LocationPriority }, + { name: "customProp", kind: "const", kindModifiers: "declare", sortText: completion.SortText.LocationPriority }, + ...completion.functionMembersWithPrototype, + ], + }, + { + marker: "3", + exact: completion.functionMembersPlus([ + { name: "staticMethod", sortText: completion.SortText.LocalDeclarationPriority }, + { name: "staticProp", sortText: completion.SortText.LocalDeclarationPriority }, + { name: "prototype", sortText: completion.SortText.LocationPriority }, + ]), + }, +); diff --git a/tests/cases/fourslash/javaScriptPrototype1.ts b/tests/cases/fourslash/javaScriptPrototype1.ts index 44810cb83df2e..224decb6f4f71 100644 --- a/tests/cases/fourslash/javaScriptPrototype1.ts +++ b/tests/cases/fourslash/javaScriptPrototype1.ts @@ -28,7 +28,7 @@ edit.backspace(); // Members of a class method (1) goTo.marker('2'); edit.insert('.'); -verify.completions({ includes: { name: "length", kind: "property", kindModifiers: "declare" } }); +verify.completions({ includes: { name: "length", kind: "property", kindModifiers: "declare", sortText: completion.SortText.SortBelow(completion.SortText.LocationPriority) } }); edit.backspace(); // Members of the invocation of a class method (1) diff --git a/tests/cases/fourslash/server/completions02.ts b/tests/cases/fourslash/server/completions02.ts index 3f035d4ebc65e..1240bea0a982b 100644 --- a/tests/cases/fourslash/server/completions02.ts +++ b/tests/cases/fourslash/server/completions02.ts @@ -9,12 +9,11 @@ ////} ////Foo./**/ -const sortedFunctionMembers = completion.functionMembersWithPrototype.slice().sort((a, b) => a.name.localeCompare(b.name)); const exact: ReadonlyArray = [ - ...sortedFunctionMembers.map(e => - e.name === "arguments" ? { ...e, kind: "property", kindModifiers: "declare", tags: [] } : - e.name === "prototype" ? { ...e, kindModifiers: undefined } : e), + { name: "prototype", kind: "property", sortText: completion.SortText.LocationPriority }, { name: "x", text: "var Foo.x: number", tags: [] }, + ...completion.functionMembers.map(e => + e.name === "arguments" ? { ...e, kind: "property", kindModifiers: "declare", tags: [] } : e), ]; verify.completions({ marker: "", exact });