diff --git a/src/services/completions.ts b/src/services/completions.ts index c0e58f01b8e..2ff43467979 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -3585,7 +3585,8 @@ function getCompletionData( const nameSymbol = leftMostName && typeChecker.getSymbolAtLocation(leftMostName); // If this is nested like for `namespace N { export const sym = Symbol(); }`, we'll add the completion for `N`. const firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain(nameSymbol, contextToken, typeChecker); - if (firstAccessibleSymbol && addToSeen(seenPropertySymbols, getSymbolId(firstAccessibleSymbol))) { + const firstAccessibleSymbolId = firstAccessibleSymbol && getSymbolId(firstAccessibleSymbol); + if (firstAccessibleSymbolId && addToSeen(seenPropertySymbols, firstAccessibleSymbolId)) { const index = symbols.length; symbols.push(firstAccessibleSymbol); const moduleSymbol = firstAccessibleSymbol.parent; @@ -3621,6 +3622,9 @@ function getCompletionData( } } else if (preferences.includeCompletionsWithInsertText) { + if (firstAccessibleSymbolId && seenPropertySymbols.has(firstAccessibleSymbolId)) { + return; + } addSymbolOriginInfo(symbol); addSymbolSortInfo(symbol); symbols.push(symbol); diff --git a/tests/baselines/reference/completionsUniqueSymbol2.baseline b/tests/baselines/reference/completionsUniqueSymbol2.baseline new file mode 100644 index 00000000000..d873364a57d --- /dev/null +++ b/tests/baselines/reference/completionsUniqueSymbol2.baseline @@ -0,0 +1,365 @@ +=== /tests/cases/fourslash/completionsUniqueSymbol2.ts === +// const a = { +// KEY_1: 'key_1', +// KEY_2: 'key_2', +// KEY_3: 'key_3', +// } as const; +// +// const b = { +// KEY_1: 'key_1', +// KEY_2: 'key_2', +// KEY_3: 'key_3', +// } as const; +// +// interface I { +// [b.KEY_1]: string, +// [a.KEY_2]: string, +// [a.KEY_3]: string +// } +// +// const foo: I = { +// key_1: 'value_1', +// key_2: 'value_2', +// key_3: 'value_3', +// } +// +// foo. +// ^ +// | ---------------------------------------------------------------------- +// | const a: { +// | readonly KEY_1: "key_1"; +// | readonly KEY_2: "key_2"; +// | readonly KEY_3: "key_3"; +// | } +// | const b: { +// | readonly KEY_1: "key_1"; +// | readonly KEY_2: "key_2"; +// | readonly KEY_3: "key_3"; +// | } +// | ---------------------------------------------------------------------- + +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/completionsUniqueSymbol2.ts", + "position": 345, + "name": "" + }, + "item": { + "flags": 0, + "isGlobalCompletion": false, + "isMemberCompletion": true, + "isNewIdentifierLocation": false, + "entries": [ + { + "name": "a", + "kind": "const", + "kindModifiers": "", + "sortText": "11", + "insertText": "[a]", + "replacementSpan": { + "start": 344, + "length": 1 + }, + "displayParts": [ + { + "text": "const", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a", + "kind": "localName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_1", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_1\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_2", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_2\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_3", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_3\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [] + }, + { + "name": "b", + "kind": "const", + "kindModifiers": "", + "sortText": "11", + "insertText": "[b]", + "replacementSpan": { + "start": 344, + "length": 1 + }, + "displayParts": [ + { + "text": "const", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "b", + "kind": "localName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_1", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_1\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_2", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_2\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "readonly", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "KEY_3", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "\"key_3\"", + "kind": "stringLiteral" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [] + } + ] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/completionsUniqueSymbol.ts b/tests/cases/fourslash/completionsUniqueSymbol1.ts similarity index 100% rename from tests/cases/fourslash/completionsUniqueSymbol.ts rename to tests/cases/fourslash/completionsUniqueSymbol1.ts diff --git a/tests/cases/fourslash/completionsUniqueSymbol2.ts b/tests/cases/fourslash/completionsUniqueSymbol2.ts new file mode 100644 index 00000000000..0038d9be2a7 --- /dev/null +++ b/tests/cases/fourslash/completionsUniqueSymbol2.ts @@ -0,0 +1,31 @@ +/// + +////const a = { +//// KEY_1: 'key_1', +//// KEY_2: 'key_2', +//// KEY_3: 'key_3', +////} as const; +//// +////const b = { +//// KEY_1: 'key_1', +//// KEY_2: 'key_2', +//// KEY_3: 'key_3', +////} as const; +//// +////interface I { +//// [b.KEY_1]: string, +//// [a.KEY_2]: string, +//// [a.KEY_3]: string +////} +//// +////const foo: I = { +//// key_1: 'value_1', +//// key_2: 'value_2', +//// key_3: 'value_3', +////} +//// +////foo./**/ + +verify.baselineCompletions({ + includeCompletionsWithInsertText: true, +});