From 24ac9e75c2f04f9084fcd21df7d3fabc7dee9fe0 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 17 May 2023 19:14:34 -0300 Subject: [PATCH] Improve class member snippet completions and keyword completions interaction (#52525) --- src/compiler/factory/nodeFactory.ts | 14 + src/compiler/types.ts | 3 +- src/harness/fourslashImpl.ts | 14 +- src/harness/fourslashInterfaceImpl.ts | 1 + src/server/protocol.ts | 5 + src/server/session.ts | 2 + src/services/codefixes/helpers.ts | 3 +- src/services/completions.ts | 114 ++++++-- src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 6 + tests/baselines/reference/api/typescript.d.ts | 1 + .../completionsClassMembers2.baseline | 119 ++++---- .../completionsClassMembers4.baseline | 225 +++++++-------- .../completionsClassMembers5.baseline | 113 ++++---- .../completionsOverridingMethod15.baseline | 103 +++---- .../completionsOverridingMethod16.baseline | 103 +++---- ...-file-is-opened-with-different-contents.js | 38 +-- ...hod.ts => completionsOverridingMethod0.ts} | 34 ++- .../fourslash/completionsOverridingMethod1.ts | 3 +- .../completionsOverridingMethod10.ts | 9 +- .../completionsOverridingMethod11.ts | 9 +- .../completionsOverridingMethod12.ts | 16 +- .../completionsOverridingMethod13.ts | 5 +- .../completionsOverridingMethod14.ts | 5 +- .../completionsOverridingMethod17.ts | 3 +- .../fourslash/completionsOverridingMethod2.ts | 15 +- .../fourslash/completionsOverridingMethod3.ts | 3 +- .../fourslash/completionsOverridingMethod4.ts | 6 +- .../fourslash/completionsOverridingMethod5.ts | 26 +- .../fourslash/completionsOverridingMethod6.ts | 268 +++++++++++++----- .../fourslash/completionsOverridingMethod7.ts | 6 +- .../fourslash/completionsOverridingMethod8.ts | 3 +- .../fourslash/completionsOverridingMethod9.ts | 10 +- .../completionsOverridingMethodCrash1.ts | 3 +- ...pletionsOverridingMethodDefaultExported.ts | 3 +- .../completionsOverridingProperties1.ts | 3 +- tests/cases/fourslash/fourslash.ts | 1 + .../completionsOverridingMethodCrash2.ts | 6 +- 38 files changed, 780 insertions(+), 522 deletions(-) rename tests/cases/fourslash/{completionsOverridingMethod.ts => completionsOverridingMethod0.ts} (86%) diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index c3d2e25f38e..638ff154747 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -125,6 +125,7 @@ import { getSyntheticLeadingComments, getSyntheticTrailingComments, getTextOfIdentifierOrLiteral, + HasDecorators, hasInvalidEscape, HasModifiers, hasProperty, @@ -1023,6 +1024,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode liftToBlock, mergeLexicalEnvironment, updateModifiers, + updateModifierLike, }; forEach(nodeFactoryPatchers, fn => fn(factory)); @@ -6989,6 +6991,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode Debug.assertNever(node); } + function updateModifierLike(node: T, modifiers: readonly ModifierLike[]): T; + function updateModifierLike(node: HasModifiers & HasDecorators, modifierArray: readonly ModifierLike[]) { + return isParameter(node) ? updateParameterDeclaration(node, modifierArray, node.dotDotDotToken, node.name, node.questionToken, node.type, node.initializer) : + isPropertyDeclaration(node) ? updatePropertyDeclaration(node, modifierArray, node.name, node.questionToken ?? node.exclamationToken, node.type, node.initializer) : + isMethodDeclaration(node) ? updateMethodDeclaration(node, modifierArray, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body) : + isGetAccessorDeclaration(node) ? updateGetAccessorDeclaration(node, modifierArray, node.name, node.parameters, node.type, node.body) : + isSetAccessorDeclaration(node) ? updateSetAccessorDeclaration(node, modifierArray, node.name, node.parameters, node.body) : + isClassExpression(node) ? updateClassExpression(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : + isClassDeclaration(node) ? updateClassDeclaration(node, modifierArray, node.name, node.typeParameters, node.heritageClauses, node.members) : + Debug.assertNever(node); + } + function asNodeArray(array: readonly T[]): NodeArray; function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined; function asNodeArray(array: readonly T[] | undefined): NodeArray | undefined { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 905552c7fc7..d5c402ea307 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1335,7 +1335,7 @@ export type HasIllegalDecorators = ; // NOTE: Changing the following list requires changes to: -// - `canHaveModifiers` in factory/utilities.ts +// - `canHaveModifiers` in factory/utilitiesPublic.ts // - `updateModifiers` in factory/nodeFactory.ts export type HasModifiers = | TypeParameterDeclaration @@ -9057,6 +9057,7 @@ export interface NodeFactory { */ cloneNode(node: T): T; /** @internal */ updateModifiers(node: T, modifiers: readonly Modifier[] | ModifierFlags | undefined): T; + /** @internal */ updateModifierLike(node: T, modifierLike: readonly ModifierLike[] | undefined): T; } /** @internal */ diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 2b6b93dffcd..6f571c049ba 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -1009,8 +1009,18 @@ export class TestState { 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.filterText, + expected.filterText, + `At entry ${actual.name}: Completion 'filterText' not match: ${showTextDiff(expected.filterText || "", actual.filterText || "")}`); + assert.equal( + actual.labelDetails?.description, + expected.labelDetails?.description, + `At entry ${actual.name}: Completion 'labelDetails.description' did not match: ${showTextDiff(expected.labelDetails?.description || "", actual.labelDetails?.description || "")}`); + assert.equal( + actual.labelDetails?.detail, + expected.labelDetails?.detail, + `At entry ${actual.name}: Completion 'labelDetails.detail' did not match: ${showTextDiff(expected.labelDetails?.detail || "", actual.labelDetails?.detail || "")}`); 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 ae83c034f9f..95ac483aafb 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1738,6 +1738,7 @@ export interface ExpectedCompletionEntryObject { readonly name: string; readonly source?: string; readonly insertText?: string; + readonly filterText?: string; readonly replacementSpan?: FourSlash.Range; readonly hasAction?: boolean; // If not specified, will assert that this is false. readonly isRecommended?: boolean; // If not specified, will assert that this is false. diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 4e4432d0bc2..cc90e749bf0 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2335,6 +2335,11 @@ export interface CompletionEntry { * coupled with `replacementSpan` to replace a dotted access with a bracket access. */ insertText?: string; + /** + * A string that should be used when filtering a set of + * completion items. + */ + filterText?: string; /** * `insertText` should be interpreted as a snippet if true. */ diff --git a/src/server/session.ts b/src/server/session.ts index 5d6eb523377..9434a5d58cd 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2267,6 +2267,7 @@ export class Session implements EventSender { kindModifiers, sortText, insertText, + filterText, replacementSpan, hasAction, source, @@ -2285,6 +2286,7 @@ export class Session implements EventSender { kindModifiers, sortText, insertText, + filterText, replacementSpan: convertedSpan, isSnippet, hasAction: hasAction || undefined, diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index e47e4c99777..3365c36dbf0 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -194,7 +194,8 @@ export function addNewNodeForMemberSymbol( const kind = declaration?.kind ?? SyntaxKind.PropertySignature; const declarationName = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName; const effectiveModifierFlags = declaration ? getEffectiveModifierFlags(declaration) : ModifierFlags.None; - let modifierFlags = + let modifierFlags = effectiveModifierFlags & ModifierFlags.Static; + modifierFlags |= effectiveModifierFlags & ModifierFlags.Public ? ModifierFlags.Public : effectiveModifierFlags & ModifierFlags.Protected ? ModifierFlags.Protected : ModifierFlags.None; diff --git a/src/services/completions.ts b/src/services/completions.ts index 75ec22e3528..0becb60309e 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -7,6 +7,7 @@ import { BindingPattern, BreakOrContinueStatement, CancellationToken, + canHaveDecorators, canUsePropertyAccess, CaseBlock, cast, @@ -44,6 +45,7 @@ import { createTextSpanFromRange, Debug, Declaration, + Decorator, Diagnostics, diagnosticToString, displayPart, @@ -91,6 +93,7 @@ import { getLineAndCharacterOfPosition, getLineStartPositionForPosition, getLocalSymbolForExportDefault, + getModifiers, getNameOfDeclaration, getNameTable, getNewLineCharacter, @@ -145,6 +148,7 @@ import { isConstructorDeclaration, isContextualKeyword, isDeclarationName, + isDecorator, isDeprecatedDeclaration, isEntityName, isEnumMember, @@ -276,6 +280,7 @@ import { memoizeOne, MethodDeclaration, ModifierFlags, + ModifierLike, modifiersToFlags, ModifierSyntaxKind, modifierToFlag, @@ -1609,6 +1614,7 @@ function createCompletionEntry( includeSymbol: boolean ): CompletionEntry | undefined { let insertText: string | undefined; + let filterText: string | undefined; let replacementSpan = getReplacementSpanForContextToken(replacementToken); let data: CompletionEntryData | undefined; let isSnippet: true | undefined; @@ -1682,12 +1688,16 @@ function createCompletionEntry( completionKind === CompletionKind.MemberLike && isClassLikeMemberCompletion(symbol, location, sourceFile)) { let importAdder; - ({ insertText, isSnippet, importAdder, replacementSpan } = - getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location, position, contextToken, formatContext)); - sortText = SortText.ClassMemberSnippets; // sortText has to be lower priority than the sortText for keywords. See #47852. - if (importAdder?.hasFixes()) { - hasAction = true; - source = CompletionSource.ClassMemberSnippet; + const memberCompletionEntry = getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location, position, contextToken, formatContext); + if (memberCompletionEntry) { + ({ insertText, filterText, isSnippet, importAdder } = memberCompletionEntry); + if (importAdder?.hasFixes()) { + hasAction = true; + source = CompletionSource.ClassMemberSnippet; + } + } + else { + return undefined; // Skip this entry } } @@ -1755,6 +1765,7 @@ function createCompletionEntry( hasAction: hasAction ? true : undefined, isRecommended: isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker) || undefined, insertText, + filterText, replacementSpan, sourceDisplay, labelDetails, @@ -1826,15 +1837,15 @@ function getEntryForMemberCompletion( position: number, contextToken: Node | undefined, formatContext: formatting.FormatContext | undefined, -): { insertText: string, isSnippet?: true, importAdder?: codefix.ImportAdder, replacementSpan?: TextSpan } { +): { insertText: string, filterText?: string, isSnippet?: true, importAdder?: codefix.ImportAdder, eraseRange?: TextRange } | undefined { const classLikeDeclaration = findAncestor(location, isClassLike); if (!classLikeDeclaration) { - return { insertText: name }; + return undefined; // This should never happen. } let isSnippet: true | undefined; - let replacementSpan: TextSpan | undefined; let insertText: string = name; + const filterText: string = name; const checker = program.getTypeChecker(); const sourceFile = location.getSourceFile(); @@ -1863,11 +1874,11 @@ function getEntryForMemberCompletion( } let modifiers = ModifierFlags.None; + const { modifiers: presentModifiers, range: eraseRange, decorators: presentDecorators } = getPresentModifiers(contextToken, sourceFile, position); // Whether the suggested member should be abstract. // e.g. in `abstract class C { abstract | }`, we should offer abstract method signatures at position `|`. - const { modifiers: presentModifiers, span: modifiersSpan } = getPresentModifiers(contextToken, sourceFile, position); - const isAbstract = !!(presentModifiers & ModifierFlags.Abstract); - const completionNodes: Node[] = []; + const isAbstract = presentModifiers & ModifierFlags.Abstract && classLikeDeclaration.modifierFlagsCache & ModifierFlags.Abstract; + let completionNodes: codefix.AddNode[] = []; codefix.addNewNodeForMemberSymbol( symbol, classLikeDeclaration, @@ -1896,20 +1907,49 @@ function getEntryForMemberCompletion( // This is needed when we have overloaded signatures, // so this callback will be called for multiple nodes/signatures, // and we need to make sure the modifiers are uniform for all nodes/signatures. - modifiers = node.modifierFlagsCache | requiredModifiers | presentModifiers; + modifiers = node.modifierFlagsCache | requiredModifiers; } node = factory.updateModifiers(node, modifiers); completionNodes.push(node); }, body, codefix.PreserveOptionalFlags.Property, - isAbstract); + !!isAbstract); if (completionNodes.length) { + const isMethod = symbol.flags & SymbolFlags.Method; + let allowedModifiers = modifiers | ModifierFlags.Override | ModifierFlags.Public; + if (!isMethod) { + allowedModifiers |= ModifierFlags.Ambient | ModifierFlags.Readonly; + } + else { + allowedModifiers |= ModifierFlags.Async; + } + const allowedAndPresent = presentModifiers & allowedModifiers; + if (presentModifiers & (~allowedModifiers)) { + return undefined; // This completion entry will be filtered out. + } + // If the original member is protected, we allow it to change to public. + if (modifiers & ModifierFlags.Protected && allowedAndPresent & ModifierFlags.Public) { + modifiers &= ~ModifierFlags.Protected; + } + // `public` modifier is optional and can be dropped. + if (allowedAndPresent !== ModifierFlags.None && !(allowedAndPresent & ModifierFlags.Public)) { + modifiers &= ~ModifierFlags.Public; + } + modifiers |= allowedAndPresent; + completionNodes = completionNodes.map(node => factory.updateModifiers(node, modifiers)); + // Add back the decorators that were already present. + if (presentDecorators?.length) { + const lastNode = completionNodes[completionNodes.length - 1]; + if (canHaveDecorators(lastNode)) { + completionNodes[completionNodes.length - 1] = factory.updateModifierLike(lastNode, (presentDecorators as ModifierLike[]).concat(getModifiers(lastNode) || [])); + } + } + const format = ListFormat.MultiLine | ListFormat.NoTrailingNewLine; - replacementSpan = modifiersSpan; - // If we have access to formatting settings, we print the nodes using the emitter, - // and then format the printed text. + // If we have access to formatting settings, we print the nodes using the emitter, + // and then format the printed text. if (formatContext) { insertText = printer.printAndFormatSnippetList( format, @@ -1925,21 +1965,22 @@ function getEntryForMemberCompletion( } } - return { insertText, isSnippet, importAdder, replacementSpan }; + return { insertText, filterText, isSnippet, importAdder, eraseRange }; } function getPresentModifiers( contextToken: Node | undefined, sourceFile: SourceFile, - position: number): { modifiers: ModifierFlags, span?: TextSpan } { + position: number): { modifiers: ModifierFlags, decorators?: Decorator[], range?: TextRange } { if (!contextToken || getLineAndCharacterOfPosition(sourceFile, position).line > getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line) { return { modifiers: ModifierFlags.None }; } let modifiers = ModifierFlags.None; - let span; + let decorators: Decorator[] | undefined; let contextMod; + const range: TextRange = { pos: position, end: position }; /* Cases supported: In @@ -1959,15 +2000,19 @@ function getPresentModifiers( `location.parent` is property declaration ``protected override m``, `location.parent.parent` is class declaration ``class C { ... }``. */ - if (contextMod = isModifierLike(contextToken)) { - modifiers |= modifierToFlag(contextMod); - span = createTextSpanFromNode(contextToken); - } - if (isPropertyDeclaration(contextToken.parent)) { + if (isPropertyDeclaration(contextToken.parent) && contextToken.parent.modifiers) { modifiers |= modifiersToFlags(contextToken.parent.modifiers) & ModifierFlags.Modifier; - span = createTextSpanFromNode(contextToken.parent); + decorators = contextToken.parent.modifiers.filter(isDecorator) || []; + range.pos = Math.min(range.pos, contextToken.parent.modifiers.pos); } - return { modifiers, span }; + if (contextMod = isModifierLike(contextToken)) { + const contextModifierFlag = modifierToFlag(contextMod); + if (!(modifiers & contextModifierFlag)) { + modifiers |= contextModifierFlag; + range.pos = Math.min(range.pos, contextToken.pos); + } + } + return { modifiers, decorators, range: range.pos !== position ? range : undefined }; } function isModifierLike(node: Node): ModifierSyntaxKind | undefined { @@ -2770,7 +2815,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay( } if (source === CompletionSource.ClassMemberSnippet) { - const { importAdder } = getEntryForMemberCompletion( + const { importAdder, eraseRange } = getEntryForMemberCompletion( host, program, compilerOptions, @@ -2780,11 +2825,18 @@ function getCompletionEntryCodeActionsAndSourceDisplay( location, position, contextToken, - formatContext); - if (importAdder) { + formatContext)!; + if (importAdder || eraseRange) { const changes = textChanges.ChangeTracker.with( { host, formatContext, preferences }, - importAdder.writeFixes); + tracker => { + if (importAdder) { + importAdder.writeFixes(tracker); + } + if (eraseRange) { + tracker.deleteRange(sourceFile, eraseRange); + } + }); return { sourceDisplay: undefined, codeActions: [{ diff --git a/src/services/types.ts b/src/services/types.ts index beccf81d1f1..b664d0ec123 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1406,6 +1406,7 @@ export interface CompletionEntry { kindModifiers?: string; // see ScriptElementKindModifier, comma separated sortText: string; insertText?: string; + filterText?: string; isSnippet?: true; /** * An optional span that indicates the text to be replaced by this completion item. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f39dee12ae4..4ec29e97c60 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1829,6 +1829,11 @@ declare namespace ts { * coupled with `replacementSpan` to replace a dotted access with a bracket access. */ insertText?: string; + /** + * A string that should be used when filtering a set of + * completion items. + */ + filterText?: string; /** * `insertText` should be interpreted as a snippet if true. */ @@ -10801,6 +10806,7 @@ declare namespace ts { kindModifiers?: string; sortText: string; insertText?: string; + filterText?: string; isSnippet?: true; /** * An optional span that indicates the text to be replaced by this completion item. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 13520f2ace0..a42e632284f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -6838,6 +6838,7 @@ declare namespace ts { kindModifiers?: string; sortText: string; insertText?: string; + filterText?: string; isSnippet?: true; /** * An optional span that indicates the text to be replaced by this completion item. diff --git a/tests/baselines/reference/completionsClassMembers2.baseline b/tests/baselines/reference/completionsClassMembers2.baseline index ac32be2eb45..a6afcfdbdd2 100644 --- a/tests/baselines/reference/completionsClassMembers2.baseline +++ b/tests/baselines/reference/completionsClassMembers2.baseline @@ -8,6 +8,7 @@ // // ^ // | ---------------------------------------------------------------------- +// | (method) I.method(): void // | abstract // | accessor // | async @@ -21,7 +22,6 @@ // | readonly // | set // | static -// | (method) I.method(): void // | ---------------------------------------------------------------------- // } @@ -38,6 +38,65 @@ "isMemberCompletion": true, "isNewIdentifierLocation": true, "entries": [ + { + "name": "method", + "kind": "method", + "kindModifiers": "", + "sortText": "11", + "insertText": "method(): void {\n}", + "filterText": "method", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "I", + "kind": "interfaceName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "void", + "kind": "keyword" + } + ], + "documentation": [] + }, { "name": "abstract", "kind": "keyword", @@ -193,64 +252,6 @@ "kind": "keyword" } ] - }, - { - "name": "method", - "kind": "method", - "kindModifiers": "", - "sortText": "17", - "insertText": "method(): void {\n}", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "method", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "I", - "kind": "interfaceName" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "method", - "kind": "methodName" - }, - { - "text": "(", - "kind": "punctuation" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "void", - "kind": "keyword" - } - ], - "documentation": [] } ] } diff --git a/tests/baselines/reference/completionsClassMembers4.baseline b/tests/baselines/reference/completionsClassMembers4.baseline index ecbe05f1c20..d21c0b4e78a 100644 --- a/tests/baselines/reference/completionsClassMembers4.baseline +++ b/tests/baselines/reference/completionsClassMembers4.baseline @@ -16,6 +16,7 @@ // // ^ // | ---------------------------------------------------------------------- +// | (method) Observable.pipe(): Observable (+10 overloads) // | abstract // | accessor // | async @@ -29,7 +30,6 @@ // | readonly // | set // | static -// | (method) Observable.pipe(): Observable (+10 overloads) // | ---------------------------------------------------------------------- // } @@ -46,6 +46,118 @@ "isMemberCompletion": true, "isNewIdentifierLocation": true, "entries": [ + { + "name": "pipe", + "kind": "method", + "kindModifiers": "", + "sortText": "11", + "insertText": "pipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable {\n $0\n}", + "filterText": "pipe", + "isSnippet": true, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Observable", + "kind": "className" + }, + { + "text": "<", + "kind": "punctuation" + }, + { + "text": "any", + "kind": "keyword" + }, + { + "text": ">", + "kind": "punctuation" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "pipe", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Observable", + "kind": "className" + }, + { + "text": "<", + "kind": "punctuation" + }, + { + "text": "any", + "kind": "keyword" + }, + { + "text": ">", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "+", + "kind": "operator" + }, + { + "text": "10", + "kind": "numericLiteral" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "overloads", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + } + ], + "documentation": [] + }, { "name": "abstract", "kind": "keyword", @@ -201,117 +313,6 @@ "kind": "keyword" } ] - }, - { - "name": "pipe", - "kind": "method", - "kindModifiers": "", - "sortText": "17", - "insertText": "pipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable;\npipe(): Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable | Observable {\n $0\n}", - "isSnippet": true, - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "method", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "Observable", - "kind": "className" - }, - { - "text": "<", - "kind": "punctuation" - }, - { - "text": "any", - "kind": "keyword" - }, - { - "text": ">", - "kind": "punctuation" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "pipe", - "kind": "methodName" - }, - { - "text": "(", - "kind": "punctuation" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "Observable", - "kind": "className" - }, - { - "text": "<", - "kind": "punctuation" - }, - { - "text": "any", - "kind": "keyword" - }, - { - "text": ">", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "+", - "kind": "operator" - }, - { - "text": "10", - "kind": "numericLiteral" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "overloads", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - } - ], - "documentation": [] } ] } diff --git a/tests/baselines/reference/completionsClassMembers5.baseline b/tests/baselines/reference/completionsClassMembers5.baseline index 6585e05077f..24f83a2e0f2 100644 --- a/tests/baselines/reference/completionsClassMembers5.baseline +++ b/tests/baselines/reference/completionsClassMembers5.baseline @@ -7,6 +7,7 @@ // // ^ // | ---------------------------------------------------------------------- +// | (property) Base[SOME_CONSTANT]: boolean // | abstract // | accessor // | async @@ -20,7 +21,6 @@ // | readonly // | set // | static -// | (property) Base[SOME_CONSTANT]: boolean // | ---------------------------------------------------------------------- // } @@ -37,6 +37,62 @@ "isMemberCompletion": true, "isNewIdentifierLocation": true, "entries": [ + { + "name": "[SOME_CONSTANT]", + "kind": "property", + "kindModifiers": "", + "sortText": "11", + "insertText": "[SOME_CONSTANT]: boolean;", + "filterText": "[SOME_CONSTANT]", + "isSnippet": true, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Base", + "kind": "className" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "SOME_CONSTANT", + "kind": "propertyName" + }, + { + "text": "]", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "boolean", + "kind": "keyword" + } + ], + "documentation": [] + }, { "name": "abstract", "kind": "keyword", @@ -192,61 +248,6 @@ "kind": "keyword" } ] - }, - { - "name": "[SOME_CONSTANT]", - "kind": "property", - "kindModifiers": "", - "sortText": "17", - "insertText": "[SOME_CONSTANT]: boolean;", - "isSnippet": true, - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "Base", - "kind": "className" - }, - { - "text": "[", - "kind": "punctuation" - }, - { - "text": "SOME_CONSTANT", - "kind": "propertyName" - }, - { - "text": "]", - "kind": "punctuation" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "boolean", - "kind": "keyword" - } - ], - "documentation": [] } ] } diff --git a/tests/baselines/reference/completionsOverridingMethod15.baseline b/tests/baselines/reference/completionsOverridingMethod15.baseline index 62cfd2456b6..146553bb07d 100644 --- a/tests/baselines/reference/completionsOverridingMethod15.baseline +++ b/tests/baselines/reference/completionsOverridingMethod15.baseline @@ -7,6 +7,7 @@ // // ^ // | ---------------------------------------------------------------------- +// | (property) B.foo: any // | abstract // | accessor // | async @@ -20,7 +21,6 @@ // | readonly // | set // | static -// | (property) B.foo: any // | ---------------------------------------------------------------------- // } @@ -37,6 +37,57 @@ "isMemberCompletion": true, "isNewIdentifierLocation": true, "entries": [ + { + "name": "foo", + "kind": "property", + "kindModifiers": "declare", + "sortText": "11", + "insertText": "get foo(): any {\n}\nset foo(value: any) {\n}", + "filterText": "foo", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "B", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "foo", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "documentation": [] + }, { "name": "abstract", "kind": "keyword", @@ -192,56 +243,6 @@ "kind": "keyword" } ] - }, - { - "name": "foo", - "kind": "property", - "kindModifiers": "declare", - "sortText": "17", - "insertText": "get foo(): any {\n}\nset foo(value: any) {\n}", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "B", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "foo", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "any", - "kind": "keyword" - } - ], - "documentation": [] } ] } diff --git a/tests/baselines/reference/completionsOverridingMethod16.baseline b/tests/baselines/reference/completionsOverridingMethod16.baseline index 3f414dd075a..38f7eb1b530 100644 --- a/tests/baselines/reference/completionsOverridingMethod16.baseline +++ b/tests/baselines/reference/completionsOverridingMethod16.baseline @@ -7,6 +7,7 @@ // // ^ // | ---------------------------------------------------------------------- +// | (property) B.foo: any // | abstract // | accessor // | async @@ -20,7 +21,6 @@ // | readonly // | set // | static -// | (property) B.foo: any // | ---------------------------------------------------------------------- // } @@ -37,6 +37,57 @@ "isMemberCompletion": true, "isNewIdentifierLocation": true, "entries": [ + { + "name": "foo", + "kind": "property", + "kindModifiers": "declare", + "sortText": "11", + "insertText": "set foo(value: any) {\n}\nget foo(): any {\n}", + "filterText": "foo", + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "property", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "B", + "kind": "className" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "foo", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "documentation": [] + }, { "name": "abstract", "kind": "keyword", @@ -192,56 +243,6 @@ "kind": "keyword" } ] - }, - { - "name": "foo", - "kind": "property", - "kindModifiers": "declare", - "sortText": "17", - "insertText": "set foo(value: any) {\n}\nget foo(): any {\n}", - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "property", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "B", - "kind": "className" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "foo", - "kind": "propertyName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "any", - "kind": "keyword" - } - ], - "documentation": [] } ] } diff --git a/tests/baselines/reference/tsserver/exportMapCache/invalidates-the-cache-when-a-file-is-opened-with-different-contents.js b/tests/baselines/reference/tsserver/exportMapCache/invalidates-the-cache-when-a-file-is-opened-with-different-contents.js index bec749d0635..e5dc1356cac 100644 --- a/tests/baselines/reference/tsserver/exportMapCache/invalidates-the-cache-when-a-file-is-opened-with-different-contents.js +++ b/tests/baselines/reference/tsserver/exportMapCache/invalidates-the-cache-when-a-file-is-opened-with-different-contents.js @@ -280,6 +280,16 @@ Info seq [hh:mm:ss:mss] response: } }, "entries": [ + { + "name": "render", + "kind": "method", + "kindModifiers": "abstract", + "sortText": "11", + "insertText": "render(): Element {\n}", + "filterText": "render", + "hasAction": true, + "source": "ClassMemberSnippet/" + }, { "name": "abstract", "kind": "keyword", @@ -357,15 +367,6 @@ Info seq [hh:mm:ss:mss] response: "kind": "keyword", "kindModifiers": "", "sortText": "15" - }, - { - "name": "render", - "kind": "method", - "kindModifiers": "abstract", - "sortText": "17", - "insertText": "render(): Element {\n}", - "hasAction": true, - "source": "ClassMemberSnippet/" } ] }, @@ -516,6 +517,16 @@ Info seq [hh:mm:ss:mss] response: } }, "entries": [ + { + "name": "render2", + "kind": "method", + "kindModifiers": "abstract", + "sortText": "11", + "insertText": "render2(): Element {\n}", + "filterText": "render2", + "hasAction": true, + "source": "ClassMemberSnippet/" + }, { "name": "abstract", "kind": "keyword", @@ -593,15 +604,6 @@ Info seq [hh:mm:ss:mss] response: "kind": "keyword", "kindModifiers": "", "sortText": "15" - }, - { - "name": "render2", - "kind": "method", - "kindModifiers": "abstract", - "sortText": "17", - "insertText": "render2(): Element {\n}", - "hasAction": true, - "source": "ClassMemberSnippet/" } ] }, diff --git a/tests/cases/fourslash/completionsOverridingMethod.ts b/tests/cases/fourslash/completionsOverridingMethod0.ts similarity index 86% rename from tests/cases/fourslash/completionsOverridingMethod.ts rename to tests/cases/fourslash/completionsOverridingMethod0.ts index d88abd77124..b4d462c0019 100644 --- a/tests/cases/fourslash/completionsOverridingMethod.ts +++ b/tests/cases/fourslash/completionsOverridingMethod0.ts @@ -93,7 +93,7 @@ //// ////class HSub extends HBase { //// /*h1*/ -//// [|static|] /*h2*/ +//// static /*h2*/ ////} // @Filename: i.ts @@ -123,8 +123,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(param1: string, param2: boolean): Promise {\n}", + filterText: "foo", } ], }); @@ -140,8 +141,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(a: string, b: string): string {\n}", + filterText: "foo", } ], }); @@ -157,8 +159,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(a: string): string {\n}", + filterText: "foo", } ], }); @@ -174,8 +177,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(a: string): string {\n}", + filterText: "foo", } ], }); @@ -191,8 +195,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(a: string): string {\n}", + filterText: "foo", } ], }); @@ -208,8 +213,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "foo(a: string): string {\n}", + filterText: "foo", } ], }); @@ -225,12 +231,13 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: `foo(a: string): string; foo(a: undefined, b: number): string; foo(a: unknown, b?: unknown): string { }`, + filterText: "foo", } ], }); @@ -245,6 +252,7 @@ verify.completions({ }, excludes: "met", }); + verify.completions({ marker: "h2", isNewIdentifierLocation: true, @@ -256,9 +264,9 @@ verify.completions({ includes: [ { name: "met", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], + sortText: completion.SortText.LocationPriority, insertText: "static met(n: number): number {\n}", + filterText: "met", } ], }); @@ -274,13 +282,15 @@ verify.completions({ includes: [ { name: "met", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "met(t: T): T {\n}", + filterText: "met" }, { name: "metcons", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "metcons(t: T): T {\n}", + filterText: "metcons" } ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod1.ts b/tests/cases/fourslash/completionsOverridingMethod1.ts index 5e9349bc479..03d73b18735 100644 --- a/tests/cases/fourslash/completionsOverridingMethod1.ts +++ b/tests/cases/fourslash/completionsOverridingMethod1.ts @@ -24,8 +24,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "override foo(a: string): void {\n}", + filterText: "foo" } ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod10.ts b/tests/cases/fourslash/completionsOverridingMethod10.ts index af8681ad37d..e2db3dd1f8d 100644 --- a/tests/cases/fourslash/completionsOverridingMethod10.ts +++ b/tests/cases/fourslash/completionsOverridingMethod10.ts @@ -25,24 +25,27 @@ verify.completions({ includes: [ { name: "a", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "a: string;", + filterText: "a", }, { name: "b", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: `b(a: string): void { }`, + filterText: "b", }, { name: "c", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: `c(a: string): string; c(a: number): number; c(a: unknown): string | number { }`, + filterText: "c", }, ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod11.ts b/tests/cases/fourslash/completionsOverridingMethod11.ts index 4cf3c4f606c..96cdd21cb33 100644 --- a/tests/cases/fourslash/completionsOverridingMethod11.ts +++ b/tests/cases/fourslash/completionsOverridingMethod11.ts @@ -31,24 +31,27 @@ verify.completions({ includes: [ { name: "a", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "a: string", + filterText: "a" }, { name: "b", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: `b(a: string): void { }`, + filterText: "b" }, { name: "c", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: `c(a: string): string c(a: number): number c(a: unknown): string | number { }`, + filterText: "c" }, ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod12.ts b/tests/cases/fourslash/completionsOverridingMethod12.ts index c929ad1ca40..cc1c0278092 100644 --- a/tests/cases/fourslash/completionsOverridingMethod12.ts +++ b/tests/cases/fourslash/completionsOverridingMethod12.ts @@ -10,11 +10,11 @@ ////} //// ////abstract class B extends A { -//// [|abstract|] /*a*/ +//// abstract /*a*/ ////} //// ////abstract class B1 extends A { -//// [|abstract override|] /*b*/ +//// abstract override /*b*/ ////} verify.completions({ @@ -28,9 +28,9 @@ verify.completions({ includes: [ { name: "P", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], - insertText: "public abstract get P(): string;", + sortText: completion.SortText.LocationPriority, + insertText: "abstract get P(): string;", + filterText: "P", }, ], }); @@ -46,9 +46,9 @@ verify.completions({ includes: [ { name: "P", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[1], - insertText: "public abstract override get P(): string;", + sortText: completion.SortText.LocationPriority, + insertText: "abstract override get P(): string;", + filterText: "P", }, ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod13.ts b/tests/cases/fourslash/completionsOverridingMethod13.ts index e8422a8bbc7..7afa383e77b 100644 --- a/tests/cases/fourslash/completionsOverridingMethod13.ts +++ b/tests/cases/fourslash/completionsOverridingMethod13.ts @@ -21,11 +21,12 @@ verify.completions({ includeCompletionsWithClassMemberSnippets: true, }, exact: [ - ...completion.classElementKeywords, { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "protected foo(): void {\n}", + filterText: "foo", }, + ...completion.classElementKeywords, ], }); diff --git a/tests/cases/fourslash/completionsOverridingMethod14.ts b/tests/cases/fourslash/completionsOverridingMethod14.ts index 37aeae70790..b3140cdc515 100644 --- a/tests/cases/fourslash/completionsOverridingMethod14.ts +++ b/tests/cases/fourslash/completionsOverridingMethod14.ts @@ -22,8 +22,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, - insertText: "foo(arg: string): number {\n}" + sortText: completion.SortText.LocationPriority, + insertText: "foo(arg: string): number {\n}", + filterText: "foo", }, ], }); diff --git a/tests/cases/fourslash/completionsOverridingMethod17.ts b/tests/cases/fourslash/completionsOverridingMethod17.ts index 20bf195d485..b5e84abed4f 100644 --- a/tests/cases/fourslash/completionsOverridingMethod17.ts +++ b/tests/cases/fourslash/completionsOverridingMethod17.ts @@ -26,9 +26,10 @@ verify.completions({ includes: [ { name: "method", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "method(): void {\n}", replacementSpan: undefined, + filterText: "method", }, ], }); diff --git a/tests/cases/fourslash/completionsOverridingMethod2.ts b/tests/cases/fourslash/completionsOverridingMethod2.ts index 4fc36685405..050e0439d2a 100644 --- a/tests/cases/fourslash/completionsOverridingMethod2.ts +++ b/tests/cases/fourslash/completionsOverridingMethod2.ts @@ -25,27 +25,32 @@ verify.completions({ includes: [ { name: "$usd", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, isSnippet: true, insertText: "\"\\$usd\"(a: number): number {\n $0\n}", + filterText: "$usd", }, { name: "$cad", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, isSnippet: true, insertText: "\\$cad(b: number): number {\n $0\n}", + filterText: "$cad", }, { name: "cla$$y", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, isSnippet: true, insertText: "cla\\$\\$y(c: number): number {\n $0\n}", + filterText: "cla$$y", }, { name: "isDollarAmountString", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, isSnippet: true, - insertText: "isDollarAmountString(s: string): s is `\\$\\${number}` {\n $0\n}" + insertText: "isDollarAmountString(s: string): s is `\\$\\${number}` {\n $0\n}", + filterText: "isDollarAmountString", }, + ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod3.ts b/tests/cases/fourslash/completionsOverridingMethod3.ts index e3baffe1466..4e5b41dc62b 100644 --- a/tests/cases/fourslash/completionsOverridingMethod3.ts +++ b/tests/cases/fourslash/completionsOverridingMethod3.ts @@ -23,8 +23,9 @@ verify.completions({ includes: [ { name: "boo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "boo(): string;", + filterText: "boo", } ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod4.ts b/tests/cases/fourslash/completionsOverridingMethod4.ts index 3d5fbb045e3..d665d3d7ee4 100644 --- a/tests/cases/fourslash/completionsOverridingMethod4.ts +++ b/tests/cases/fourslash/completionsOverridingMethod4.ts @@ -42,13 +42,15 @@ verify.completions({ includes: [ { name: "hint", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "protected hint(): string {\n}", + filterText: "hint", }, { name: "refuse", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "public refuse(): string {\n}", + filterText: "refuse", } ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod5.ts b/tests/cases/fourslash/completionsOverridingMethod5.ts index 3f3844567a7..8b8d9587fb8 100644 --- a/tests/cases/fourslash/completionsOverridingMethod5.ts +++ b/tests/cases/fourslash/completionsOverridingMethod5.ts @@ -12,8 +12,8 @@ //// ////abstract class Abc extends Ab { //// /*a*/ -//// [|abstract|] /*b*/ -//// [|abstract m|]/*c*/ +//// abstract /*b*/ +//// abstract m/*c*/ ////} @@ -28,13 +28,15 @@ verify.completions({ includes: [ { name: "met", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "met(n: string): void {\n}", + filterText: "met" }, { name: "met2", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "met2(n: number): void {\n}", + filterText: "met2" } ], }); @@ -50,15 +52,15 @@ verify.completions({ includes: [ { name: "met", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], + sortText: completion.SortText.LocationPriority, insertText: "abstract met(n: string): void;", + filterText: "met" }, { name: "met2", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], + sortText: completion.SortText.LocationPriority, insertText: "abstract met2(n: number): void;", + filterText: "met2" } ], }); @@ -74,15 +76,15 @@ verify.completions({ includes: [ { name: "met", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[1], + sortText: completion.SortText.LocationPriority, insertText: "abstract met(n: string): void;", + filterText: "met" }, { name: "met2", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[1], + sortText: completion.SortText.LocationPriority, insertText: "abstract met2(n: number): void;", + filterText: "met2" } ], }); diff --git a/tests/cases/fourslash/completionsOverridingMethod6.ts b/tests/cases/fourslash/completionsOverridingMethod6.ts index 6e1dd428a30..86cda5c2e09 100644 --- a/tests/cases/fourslash/completionsOverridingMethod6.ts +++ b/tests/cases/fourslash/completionsOverridingMethod6.ts @@ -2,84 +2,202 @@ // @Filename: a.ts // @newline: LF -// Case: modifier inheritance/deduplication -////class A { -//// public method(): number { -//// return 0; -//// } -////} -//// -////abstract class B extends A { -//// [|public abstract|] /*b*/ -////} -//// -////class C extends A { -//// [|public override m|]/*a*/ -////} -//// -////interface D { -//// fun(a: number): number; -//// fun(a: undefined, b: string): number; -////} -//// -////class E implements D { -//// [|public f|]/*c*/ -////} +// Case: modifiers +//// class Base { +//// method() {} +//// protected prop = 1; +//// } -verify.completions({ - marker: "a", - isNewIdentifierLocation: true, - preferences: { - includeCompletionsWithInsertText: true, - includeCompletionsWithSnippetText: false, - includeCompletionsWithClassMemberSnippets: true, - }, - includes: [ - { - name: "method", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[1], - insertText: "public override method(): number {\n}", +//// class A extends Base { +//// public abstract /*a*/ +//// } + +//// abstract class Ab extends Base { +//// public abstract /*b*/ +//// } + +//// class B extends Base { +//// public override m/*c*/ +//// } + +//// class C extends Base { +//// override /*d*/ +//// } + +//// class E extends Base { +//// protected notamodifier override /*e*/ +//// } + +//// class f extends Base { +//// protected /*f*/ +//// } + +//// declare function decorator(...args: any[]): any; + +//// class DecoratorBase { +//// protected foo(a: string): string; +//// protected foo(a: number): number; +//// protected foo(a: any): any { +//// return a; +//// } +//// } + +//// class DecoratorSub extends DecoratorBase { +//// @decorator protected /*g*/ +//// } + +verify.completions( + { + marker: "a", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, }, - ], -}); - -verify.completions({ - marker: "b", - isNewIdentifierLocation: true, - preferences: { - includeCompletionsWithInsertText: true, - includeCompletionsWithSnippetText: false, - includeCompletionsWithClassMemberSnippets: true, + excludes: ["method", "prop"], }, - includes: [ - { - name: "method", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], - insertText: "public abstract method(): number;", + { + marker: "b", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, }, - ], -}); - -verify.completions({ - marker: "c", - isNewIdentifierLocation: true, - preferences: { - includeCompletionsWithInsertText: true, - includeCompletionsWithSnippetText: false, - includeCompletionsWithClassMemberSnippets: true, + includes: [ + { + name: "method", + sortText: completion.SortText.LocationPriority, + insertText: "public abstract method(): void;", + filterText: "method", + replacementSpan: undefined, + }, + { + name: "prop", + sortText: completion.SortText.LocationPriority, + insertText: "public abstract prop: number;", + filterText: "prop", + replacementSpan: undefined, + }, + ], }, - includes: [ - { - name: "fun", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[2], - insertText: -`public fun(a: number): number; -public fun(a: undefined, b: string): number; -public fun(a: unknown, b?: unknown): number { + { + marker: "c", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, + }, + includes: [ + { + name: "method", + sortText: completion.SortText.LocationPriority, + insertText: "public override method(): void {\n}", + filterText: "method", + replacementSpan: undefined, + }, + { + name: "prop", + sortText: completion.SortText.LocationPriority, + insertText: "public override prop: number;", + filterText: "prop", + replacementSpan: undefined, + }, + ] + }, + { + marker: "d", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, + }, + includes: [ + { + name: "method", + sortText: completion.SortText.LocationPriority, + insertText: "override method(): void {\n}", + filterText: "method", + replacementSpan: undefined, + }, + { + name: "prop", + sortText: completion.SortText.LocationPriority, + insertText: "protected override prop: number;", + filterText: "prop", + replacementSpan: undefined, + }, + ] + }, + { + marker: "e", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, + }, + includes: [ + { + name: "method", + sortText: completion.SortText.LocationPriority, + insertText: "override method(): void {\n}", + filterText: "method", + replacementSpan: undefined, + }, + { + name: "prop", + sortText: completion.SortText.LocationPriority, + insertText: "protected override prop: number;", + filterText: "prop", + replacementSpan: undefined, + }, + ] + }, + { + marker: "f", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, + }, + excludes: ["method"], + includes: [ + { + name: "prop", + sortText: completion.SortText.LocationPriority, + insertText: "protected prop: number;", + filterText: "prop", + replacementSpan: undefined, + }, + ] + }, + { + marker: "g", + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: false, + includeCompletionsWithClassMemberSnippets: true, + }, + includes: [ + { + name: "foo", + sortText: completion.SortText.LocationPriority, + insertText: +`protected foo(a: string): string; +protected foo(a: number): number; +@decorator +protected foo(a: any) { }`, - }, - ], -}); \ No newline at end of file + filterText: "foo", + replacementSpan: undefined, + }, + ] + }, +); + diff --git a/tests/cases/fourslash/completionsOverridingMethod7.ts b/tests/cases/fourslash/completionsOverridingMethod7.ts index 67865a5ef34..3c42864d59a 100644 --- a/tests/cases/fourslash/completionsOverridingMethod7.ts +++ b/tests/cases/fourslash/completionsOverridingMethod7.ts @@ -9,7 +9,7 @@ ////} //// ////abstract class Derived extends Base { -//// [|abstract|] /*a*/ +//// abstract /*a*/ ////} verify.completions({ @@ -23,11 +23,11 @@ verify.completions({ includes: [ { name: "M", - sortText: completion.SortText.ClassMemberSnippets, - replacementSpan: test.ranges()[0], + sortText: completion.SortText.LocationPriority, insertText: `abstract M(t: T): void; abstract M(t: T, x: number): void;`, + filterText: "M", }, ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/completionsOverridingMethod8.ts b/tests/cases/fourslash/completionsOverridingMethod8.ts index 3e5aea9dd97..57afd66c7c3 100644 --- a/tests/cases/fourslash/completionsOverridingMethod8.ts +++ b/tests/cases/fourslash/completionsOverridingMethod8.ts @@ -26,10 +26,11 @@ verify.completions({ }, includes: [{ name: "method", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "method(p: I): void {\n}", hasAction: true, source: completion.CompletionSource.ClassMemberSnippet, + filterText: "method", }], }); diff --git a/tests/cases/fourslash/completionsOverridingMethod9.ts b/tests/cases/fourslash/completionsOverridingMethod9.ts index 204ecbbcc49..5026f3aa8aa 100644 --- a/tests/cases/fourslash/completionsOverridingMethod9.ts +++ b/tests/cases/fourslash/completionsOverridingMethod9.ts @@ -22,13 +22,15 @@ verify.completions({ includes: [ { name: "a", - sortText: completion.SortText.ClassMemberSnippets, - insertText: "a?: number;" + sortText: completion.SortText.LocationPriority, + insertText: "a?: number;", + filterText: "a", }, { name: "b", - sortText: completion.SortText.ClassMemberSnippets, - insertText: "b(x: number): void {\n}" + sortText: completion.SortText.LocationPriority, + insertText: "b(x: number): void {\n}", + filterText: "b", }, ], }); diff --git a/tests/cases/fourslash/completionsOverridingMethodCrash1.ts b/tests/cases/fourslash/completionsOverridingMethodCrash1.ts index 49233409b48..1bbecf39912 100644 --- a/tests/cases/fourslash/completionsOverridingMethodCrash1.ts +++ b/tests/cases/fourslash/completionsOverridingMethodCrash1.ts @@ -21,8 +21,9 @@ verify.completions({ includes: [ { name: "setState", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "setState(stateHandler: (oldState: {}, newState: {}) => void): void {\n}", + filterText: "setState", } ] }); diff --git a/tests/cases/fourslash/completionsOverridingMethodDefaultExported.ts b/tests/cases/fourslash/completionsOverridingMethodDefaultExported.ts index 39c78893511..f9cf830913e 100644 --- a/tests/cases/fourslash/completionsOverridingMethodDefaultExported.ts +++ b/tests/cases/fourslash/completionsOverridingMethodDefaultExported.ts @@ -29,7 +29,8 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, + filterText: "foo", insertText: "foo(): Other {\n}", hasAction: true, source: completion.CompletionSource.ClassMemberSnippet, diff --git a/tests/cases/fourslash/completionsOverridingProperties1.ts b/tests/cases/fourslash/completionsOverridingProperties1.ts index f25fee59150..1d8a95f8eb6 100644 --- a/tests/cases/fourslash/completionsOverridingProperties1.ts +++ b/tests/cases/fourslash/completionsOverridingProperties1.ts @@ -25,8 +25,9 @@ verify.completions({ includes: [ { name: "foo", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, insertText: "protected foo: string;", + filterText: "foo" } ], }); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index e948c8c5b12..5cf399800b2 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -702,6 +702,7 @@ declare namespace FourSlashInterface { readonly name: string; readonly source?: string; readonly insertText?: string; + readonly filterText?: string; readonly replacementSpan?: Range; readonly hasAction?: boolean; readonly isRecommended?: boolean; diff --git a/tests/cases/fourslash/server/completionsOverridingMethodCrash2.ts b/tests/cases/fourslash/server/completionsOverridingMethodCrash2.ts index 0f54b73e341..3f731c0c308 100644 --- a/tests/cases/fourslash/server/completionsOverridingMethodCrash2.ts +++ b/tests/cases/fourslash/server/completionsOverridingMethodCrash2.ts @@ -35,7 +35,8 @@ verify.completions({ includes: [ { name: "render", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, + filterText: "render", isSnippet: true, insertText: "render(): Element {\r\n $0\r\n}", hasAction: true, @@ -59,7 +60,8 @@ verify.completions({ includes: [ { name: "render", - sortText: completion.SortText.ClassMemberSnippets, + sortText: completion.SortText.LocationPriority, + filterText: "render", isSnippet: true, insertText: "render(): Element {\r\n $0\r\n}", hasAction: true,