Only add completion for a symbol if it is accessible (#25096)

This commit is contained in:
Andy
2018-06-26 18:03:07 -07:00
committed by GitHub
parent ab9e913af3
commit c8c547a706
3 changed files with 60 additions and 8 deletions

View File

@@ -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);

View 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 },
});

View 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,
},
});