mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-22 02:35:48 -05:00
Only add completion for a symbol if it is accessible (#25096)
This commit is contained in:
@@ -1117,15 +1117,19 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function addPropertySymbol(symbol: Symbol) {
|
||||
// For a computed property with an accessible name like `Symbol.iterator`,
|
||||
// we'll add a completion for the *name* `Symbol` instead of for the property.
|
||||
// If this is e.g. [Symbol.iterator], add a completion for `Symbol`.
|
||||
const symbolSymbol = firstDefined(symbol.declarations, decl => {
|
||||
const name = getNameOfDeclaration(decl);
|
||||
const leftName = name && name.kind === SyntaxKind.ComputedPropertyName ? getLeftMostName(name.expression) : undefined;
|
||||
return leftName && typeChecker.getSymbolAtLocation(leftName);
|
||||
});
|
||||
if (symbolSymbol) {
|
||||
symbols.push(symbolSymbol);
|
||||
symbolToOriginInfoMap[getSymbolId(symbolSymbol)] = { type: "symbol-member" };
|
||||
const computedPropertyName = firstDefined(symbol.declarations, decl => tryCast(getNameOfDeclaration(decl), isComputedPropertyName));
|
||||
if (computedPropertyName) {
|
||||
const leftMostName = getLeftMostName(computedPropertyName.expression); // The completion is for `Symbol`, not `iterator`.
|
||||
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 && !symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)]) {
|
||||
symbols.push(firstAccessibleSymbol);
|
||||
symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)] = { type: "symbol-member" };
|
||||
}
|
||||
}
|
||||
else {
|
||||
symbols.push(symbol);
|
||||
|
||||
22
tests/cases/fourslash/completionsUniqueSymbol.ts
Normal file
22
tests/cases/fourslash/completionsUniqueSymbol.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////declare const Symbol: () => symbol;
|
||||
////namespace M {
|
||||
//// export const sym = Symbol();
|
||||
////}
|
||||
////namespace N {
|
||||
//// const sym = Symbol();
|
||||
//// export interface I {
|
||||
//// [sym]: number;
|
||||
//// [M.sym]: number;
|
||||
//// }
|
||||
////}
|
||||
////
|
||||
////declare const i: N.I;
|
||||
////i[|./**/|];
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: { name: "M", insertText: "[M]", replacementSpan: test.ranges()[0] },
|
||||
preferences: { includeInsertTextCompletions: true },
|
||||
});
|
||||
26
tests/cases/fourslash/completionsUniqueSymbol_import.ts
Normal file
26
tests/cases/fourslash/completionsUniqueSymbol_import.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////declare const Symbol: () => symbol;
|
||||
////const privateSym = Symbol();
|
||||
////export const publicSym = Symbol();
|
||||
////export interface I {
|
||||
//// [privateSym]: number;
|
||||
//// [publicSym]: number;
|
||||
//// n: number;
|
||||
////}
|
||||
////export const i: I;
|
||||
|
||||
// @Filename: /user.ts
|
||||
////import { i } from "./a";
|
||||
////i[|./**/|];
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
// TODO: GH#25095 Should include `publicSym`
|
||||
exact: "n",
|
||||
preferences: {
|
||||
includeInsertTextCompletions: true,
|
||||
includeCompletionsForModuleExports: true,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user