From 7406ee9c145cd7d6117391818d5a1eca2d66ca8f Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 17 Oct 2022 23:14:23 +0300 Subject: [PATCH] fix(51170): Completing an unimplemented property overwrites rest of line (#51175) * fix(51170): skip insertText for class members with existing initializer * skip insertText for class members with existing tokens --- src/services/completions.ts | 5 +++-- ...ts => completionsOverridingProperties1.ts} | 0 .../completionsOverridingProperties2.ts | 21 +++++++++++++++++++ .../completionsOverridingProperties3.ts | 21 +++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) rename tests/cases/fourslash/{completionsOverridingProperties.ts => completionsOverridingProperties1.ts} (100%) create mode 100644 tests/cases/fourslash/completionsOverridingProperties2.ts create mode 100644 tests/cases/fourslash/completionsOverridingProperties3.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index bff90e2d3e7c5..9bdc38195da54 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -764,7 +764,7 @@ namespace ts.Completions { if (preferences.includeCompletionsWithClassMemberSnippets && preferences.includeCompletionsWithInsertText && completionKind === CompletionKind.MemberLike && - isClassLikeMemberCompletion(symbol, location)) { + isClassLikeMemberCompletion(symbol, location, sourceFile)) { let importAdder; ({ insertText, isSnippet, importAdder, replacementSpan } = getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location, contextToken, formatContext)); sortText = SortText.ClassMemberSnippets; // sortText has to be lower priority than the sortText for keywords. See #47852. @@ -846,7 +846,7 @@ namespace ts.Completions { }; } - function isClassLikeMemberCompletion(symbol: Symbol, location: Node): boolean { + function isClassLikeMemberCompletion(symbol: Symbol, location: Node, sourceFile: SourceFile): boolean { // TODO: support JS files. if (isInJSFile(location)) { return false; @@ -884,6 +884,7 @@ namespace ts.Completions { location.parent.parent && isClassElement(location.parent) && location === location.parent.name && + location.parent.getLastToken(sourceFile) === location.parent.name && isClassLike(location.parent.parent) ) || ( diff --git a/tests/cases/fourslash/completionsOverridingProperties.ts b/tests/cases/fourslash/completionsOverridingProperties1.ts similarity index 100% rename from tests/cases/fourslash/completionsOverridingProperties.ts rename to tests/cases/fourslash/completionsOverridingProperties1.ts diff --git a/tests/cases/fourslash/completionsOverridingProperties2.ts b/tests/cases/fourslash/completionsOverridingProperties2.ts new file mode 100644 index 0000000000000..8938b8bb7fe68 --- /dev/null +++ b/tests/cases/fourslash/completionsOverridingProperties2.ts @@ -0,0 +1,21 @@ +/// + +////interface I { +//// prop: string; +////} +////class C implements I { +//// public pr/**/: string = 'foo'; +////} + +verify.completions({ + marker: "", + includes: [ + { name: "prop", isSnippet: undefined, insertText: undefined } + ], + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + includeCompletionsWithClassMemberSnippets: true, + } +}); diff --git a/tests/cases/fourslash/completionsOverridingProperties3.ts b/tests/cases/fourslash/completionsOverridingProperties3.ts new file mode 100644 index 0000000000000..c13ddadd90b89 --- /dev/null +++ b/tests/cases/fourslash/completionsOverridingProperties3.ts @@ -0,0 +1,21 @@ +/// + +////interface I { +//// prop: string; +////} +////class C implements I { +//// public pr/**/: string | number; +////} + +verify.completions({ + marker: "", + includes: [ + { name: "prop", isSnippet: undefined, insertText: undefined } + ], + isNewIdentifierLocation: true, + preferences: { + includeCompletionsWithInsertText: true, + includeCompletionsWithSnippetText: true, + includeCompletionsWithClassMemberSnippets: true, + } +});