Skip to content
Closed
12 changes: 8 additions & 4 deletions src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5013,9 +5013,10 @@ function getCompletionData(
return isFunctionLike(contextToken.parent) && !isMethodDeclaration(contextToken.parent);
}

const tokenKind = keywordForNode(contextToken);
// If the previous token is keyword corresponding to class member completion keyword
// there will be completion available here
if (isClassMemberCompletionKeyword(keywordForNode(contextToken)) && isFromObjectTypeDeclaration(contextToken)) {
if (isClassMemberCompletionKeyword(tokenKind) && isFromObjectTypeDeclaration(contextToken)) {
return false;
}

Expand All @@ -5034,10 +5035,9 @@ function getCompletionData(
}

// Previous token may have been a keyword that was converted to an identifier.
switch (keywordForNode(contextToken)) {
switch (tokenKind) {
case SyntaxKind.AbstractKeyword:
case SyntaxKind.ClassKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.EnumKeyword:
case SyntaxKind.FunctionKeyword:
Expand Down Expand Up @@ -5075,7 +5075,7 @@ function getCompletionData(
}
else if (
contextToken.kind !== SyntaxKind.EqualsToken
// Should not block: `class C { blah = c/**/ }`
// Should not block: `class C { blah = c/**/ }
// But should block: `class C { blah = somewhat c/**/ }` and `class C { blah: SomeType c/**/ }`
&& (isInitializedProperty(ancestorPropertyDeclaraion as PropertyDeclaration)
|| hasType(ancestorPropertyDeclaraion))
Expand All @@ -5084,6 +5084,10 @@ function getCompletionData(
}
}

if (tokenKind === SyntaxKind.ConstKeyword) {
return true;
}

return isDeclarationName(contextToken)
&& !isShorthandPropertyAssignment(contextToken.parent)
&& !isJsxAttribute(contextToken.parent)
Expand Down
264 changes: 264 additions & 0 deletions tests/baselines/reference/completionsClassMembers6.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
// === Completions ===
=== /tests/cases/fourslash/completionsClassMembers6.ts ===
// interface A {
// a: number
// def: string
// }
//
// class B implements A {
// a = 1 as const
// ^
// | ----------------------------------------------------------------------
// | No completions at /*1*/.
// | ----------------------------------------------------------------------
//
// ^
// | ----------------------------------------------------------------------
// | (property) A.def: string
// | abstract
// | accessor
// | async
// | constructor
// | declare
// | get
// | override
// | private
// | protected
// | public
// | readonly
// | set
// | static
// | ----------------------------------------------------------------------
// }

[
{
"marker": {
"fileName": "/tests/cases/fourslash/completionsClassMembers6.ts",
"position": 83,
"name": "1"
},
"item": {}
},
{
"marker": {
"fileName": "/tests/cases/fourslash/completionsClassMembers6.ts",
"position": 86,
"name": "2"
},
"item": {
"flags": 0,
"isGlobalCompletion": false,
"isMemberCompletion": true,
"isNewIdentifierLocation": true,
"entries": [
{
"name": "def",
"kind": "property",
"kindModifiers": "",
"sortText": "11",
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "property",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "A",
"kind": "interfaceName"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "def",
"kind": "propertyName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "string",
"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"
}
]
}
],
"defaultCommitCharacters": []
}
}
]
13 changes: 13 additions & 0 deletions tests/cases/fourslash/completionsClassMembers6.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// <reference path="fourslash.ts" />

////interface A {
//// a: number
//// def: string
////}
////
////class B implements A {
//// a = 1 as const /*1*/
//// /*2*/
////}

verify.baselineCompletions();