diff --git a/src/services/completions.ts b/src/services/completions.ts
index 343a323f34544..02427425fdf1f 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -4829,7 +4829,7 @@ function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile,
return cls;
}
break;
- case SyntaxKind.Identifier: {
+ case SyntaxKind.Identifier: {
const originalKeywordKind = identifierToKeywordKind(location as Identifier);
if (originalKeywordKind) {
return undefined;
@@ -4868,16 +4868,17 @@ function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile,
case SyntaxKind.CommaToken: // class c {getValue(): number, | }
return tryCast(contextToken.parent, isObjectTypeDeclaration);
default:
- if (!isFromObjectTypeDeclaration(contextToken)) {
- // class c extends React.Component { a: () => 1\n| }
- if (getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== getLineAndCharacterOfPosition(sourceFile, position).line && isObjectTypeDeclaration(location)) {
+ if (isObjectTypeDeclaration(location)) {
+ // class C extends React.Component { a: () => 1\n| }
+ // class C { prop = ""\n | }
+ if (getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line !== getLineAndCharacterOfPosition(sourceFile, position).line) {
return location;
}
- return undefined;
+ const isValidKeyword = isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword;
+ return (isValidKeyword(contextToken.kind) || contextToken.kind === SyntaxKind.AsteriskToken || isIdentifier(contextToken) && isValidKeyword(identifierToKeywordKind(contextToken) ?? SyntaxKind.Unknown))
+ ? contextToken.parent.parent as ObjectTypeDeclaration : undefined;
}
- const isValidKeyword = isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword;
- return (isValidKeyword(contextToken.kind) || contextToken.kind === SyntaxKind.AsteriskToken || isIdentifier(contextToken) && isValidKeyword(identifierToKeywordKind(contextToken) ?? SyntaxKind.Unknown))
- ? contextToken.parent.parent as ObjectTypeDeclaration : undefined;
+ return undefined;
}
}
diff --git a/tests/baselines/reference/completionsClassMembers1.baseline b/tests/baselines/reference/completionsClassMembers1.baseline
new file mode 100644
index 0000000000000..e08c00fcc4481
--- /dev/null
+++ b/tests/baselines/reference/completionsClassMembers1.baseline
@@ -0,0 +1,230 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/completionsClassMembers1.ts",
+ "position": 93,
+ "name": ""
+ },
+ "completionList": {
+ "flags": 0,
+ "isGlobalCompletion": false,
+ "isMemberCompletion": true,
+ "isNewIdentifierLocation": true,
+ "entries": [
+ {
+ "name": "method",
+ "kind": "method",
+ "kindModifiers": "",
+ "sortText": "11",
+ "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",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "abstract",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "accessor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "accessor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "async",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "async",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "constructor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "constructor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "declare",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "declare",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "get",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "get",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "override",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "override",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "private",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "private",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "protected",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "protected",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "public",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "public",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "readonly",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "readonly",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "set",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "set",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "static",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "static",
+ "kind": "keyword"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/completionsClassMembers2.baseline b/tests/baselines/reference/completionsClassMembers2.baseline
new file mode 100644
index 0000000000000..eb68eaf45a2ea
--- /dev/null
+++ b/tests/baselines/reference/completionsClassMembers2.baseline
@@ -0,0 +1,235 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/completionsClassMembers2.ts",
+ "position": 93,
+ "name": ""
+ },
+ "completionList": {
+ "flags": 0,
+ "isGlobalCompletion": false,
+ "isMemberCompletion": true,
+ "isNewIdentifierLocation": true,
+ "entries": [
+ {
+ "name": "abstract",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "abstract",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "accessor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "accessor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "async",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "async",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "constructor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "constructor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "declare",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "declare",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "get",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "get",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "override",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "override",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "private",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "private",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "protected",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "protected",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "public",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "public",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "readonly",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "readonly",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "set",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "set",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "static",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "static",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "method",
+ "kind": "method",
+ "kindModifiers": "",
+ "sortText": "17",
+ "insertText": "method(): void {\r\n}",
+ "replacementSpan": {
+ "start": 71,
+ "length": 16
+ },
+ "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": []
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/completionsClassMembers3.baseline b/tests/baselines/reference/completionsClassMembers3.baseline
new file mode 100644
index 0000000000000..4d83c1f170378
--- /dev/null
+++ b/tests/baselines/reference/completionsClassMembers3.baseline
@@ -0,0 +1,230 @@
+[
+ {
+ "marker": {
+ "fileName": "/tests/cases/fourslash/completionsClassMembers3.ts",
+ "position": 101,
+ "name": ""
+ },
+ "completionList": {
+ "flags": 0,
+ "isGlobalCompletion": false,
+ "isMemberCompletion": true,
+ "isNewIdentifierLocation": true,
+ "entries": [
+ {
+ "name": "method",
+ "kind": "method",
+ "kindModifiers": "",
+ "sortText": "11",
+ "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",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "abstract",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "accessor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "accessor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "async",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "async",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "constructor",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "constructor",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "declare",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "declare",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "get",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "get",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "override",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "override",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "private",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "private",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "protected",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "protected",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "public",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "public",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "readonly",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "readonly",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "set",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "set",
+ "kind": "keyword"
+ }
+ ]
+ },
+ {
+ "name": "static",
+ "kind": "keyword",
+ "kindModifiers": "",
+ "sortText": "15",
+ "displayParts": [
+ {
+ "text": "static",
+ "kind": "keyword"
+ }
+ ]
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/cases/fourslash/completionsClassMembers1.ts b/tests/cases/fourslash/completionsClassMembers1.ts
new file mode 100644
index 0000000000000..094039a61853c
--- /dev/null
+++ b/tests/cases/fourslash/completionsClassMembers1.ts
@@ -0,0 +1,13 @@
+///
+
+////interface I {
+//// method(): void;
+////}
+////
+////export class C implements I {
+//// property = "foo"
+////
+//// /**/
+////}
+
+verify.baselineCompletions();
diff --git a/tests/cases/fourslash/completionsClassMembers2.ts b/tests/cases/fourslash/completionsClassMembers2.ts
new file mode 100644
index 0000000000000..039334e14c735
--- /dev/null
+++ b/tests/cases/fourslash/completionsClassMembers2.ts
@@ -0,0 +1,16 @@
+///
+
+////interface I {
+//// method(): void;
+////}
+////
+////export class C implements I {
+//// property = "foo"
+////
+//// /**/
+////}
+
+verify.baselineCompletions({
+ includeCompletionsWithInsertText: true,
+ includeCompletionsWithClassMemberSnippets: true,
+});
diff --git a/tests/cases/fourslash/completionsClassMembers3.ts b/tests/cases/fourslash/completionsClassMembers3.ts
new file mode 100644
index 0000000000000..f648ef0ab433d
--- /dev/null
+++ b/tests/cases/fourslash/completionsClassMembers3.ts
@@ -0,0 +1,13 @@
+///
+
+////interface I {
+//// method(): void;
+////}
+////
+////export class C implements I {
+//// property = "foo" + "foo"
+////
+//// /**/
+////}
+
+verify.baselineCompletions();