Refactor tryGetGlobalSymbols into list of things to try (#22704)

* Refactor `tryGetGlobalSymbols` into list of things to try

* Refactor to `||` expression
This commit is contained in:
Andy
2018-03-23 08:44:21 -07:00
committed by GitHub
parent 0e9364f48e
commit 02ee11c357

View File

@@ -24,6 +24,8 @@ namespace ts.Completions {
TypeKeywords,
}
const enum GlobalsSearch { Continue, Success, Fail }
export function getCompletionsAtPosition(
host: LanguageServiceHost,
typeChecker: TypeChecker,
@@ -1046,52 +1048,38 @@ namespace ts.Completions {
}
function tryGetGlobalSymbols(): boolean {
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
let namedImportsOrExports: NamedImportsOrExports;
let classLikeContainer: ClassLikeDeclaration;
let jsxContainer: JsxOpeningLikeElement;
const result: GlobalsSearch = tryGetObjectLikeCompletionSymbols()
|| tryGetImportOrExportClauseCompletionSymbols()
|| tryGetConstructorCompletion()
|| tryGetClassLikeCompletionSymbols()
|| tryGetJsxCompletionSymbols()
|| (getGlobalCompletions(), GlobalsSearch.Success);
return result === GlobalsSearch.Success;
}
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
return tryGetObjectLikeCompletionSymbols(objectLikeContainer);
}
function tryGetConstructorCompletion(): GlobalsSearch {
if (!tryGetConstructorLikeCompletionContainer(contextToken)) return GlobalsSearch.Continue;
// no members, only keywords
completionKind = CompletionKind.None;
// Declaring new property/method/accessor
isNewIdentifierLocation = true;
// Has keywords for constructor parameter
keywordFilters = KeywordCompletionFilters.ConstructorParameterKeywords;
return GlobalsSearch.Success;
}
if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) {
// cursor is in an import clause
// try to show exported member for imported module
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
}
if (tryGetConstructorLikeCompletionContainer(contextToken)) {
// no members, only keywords
completionKind = CompletionKind.None;
// Declaring new property/method/accessor
isNewIdentifierLocation = true;
// Has keywords for constructor parameter
keywordFilters = KeywordCompletionFilters.ConstructorParameterKeywords;
return true;
}
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
// cursor inside class declaration
getGetClassLikeCompletionSymbols(classLikeContainer);
return true;
}
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
let attrsType: Type;
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
// Cursor is inside a JSX self-closing element or opening element
attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
if (attrsType) {
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
completionKind = CompletionKind.MemberLike;
isNewIdentifierLocation = false;
return true;
}
}
}
function tryGetJsxCompletionSymbols(): GlobalsSearch {
const jsxContainer = tryGetContainingJsxElement(contextToken);
// Cursor is inside a JSX self-closing element or opening element
const attrsType = jsxContainer && typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
if (!attrsType) return GlobalsSearch.Continue;
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
completionKind = CompletionKind.MemberLike;
isNewIdentifierLocation = false;
return GlobalsSearch.Success;
}
function getGlobalCompletions(): void {
if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) {
keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords;
}
@@ -1155,8 +1143,6 @@ namespace ts.Completions {
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target);
}
filterGlobalCompletion(symbols);
return true;
}
function isSnippetScope(scopeNode: Node): boolean {
@@ -1434,7 +1420,10 @@ namespace ts.Completions {
*
* @returns true if 'symbols' was successfully populated; false otherwise.
*/
function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean {
function tryGetObjectLikeCompletionSymbols(): GlobalsSearch | undefined {
const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
if (!objectLikeContainer) return GlobalsSearch.Continue;
// We're looking up possible property names from contextual/inferred/declared type.
completionKind = CompletionKind.ObjectPropertyDeclaration;
@@ -1446,7 +1435,7 @@ namespace ts.Completions {
// other than those within the declared type.
isNewIdentifierLocation = true;
const typeForObject = typeChecker.getContextualType(objectLikeContainer);
if (!typeForObject) return false;
if (!typeForObject) return GlobalsSearch.Fail;
typeMembers = getPropertiesForCompletion(typeForObject, typeChecker, /*isForAccess*/ false);
existingMembers = objectLikeContainer.properties;
}
@@ -1474,7 +1463,7 @@ namespace ts.Completions {
}
if (canGetType) {
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
if (!typeForObject) return false;
if (!typeForObject) return GlobalsSearch.Fail;
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter((symbol) => !(getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.NonPublicAccessibilityModifier));
existingMembers = objectLikeContainer.elements;
@@ -1485,7 +1474,7 @@ namespace ts.Completions {
// Add filtered items to the completion list
symbols = filterObjectMembersList(typeMembers, Debug.assertDefined(existingMembers));
}
return true;
return GlobalsSearch.Success;
}
/**
@@ -1503,7 +1492,12 @@ namespace ts.Completions {
*
* @returns true if 'symbols' was successfully populated; false otherwise.
*/
function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean {
function tryGetImportOrExportClauseCompletionSymbols(): GlobalsSearch {
const namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken);
if (!namedImportsOrExports) return undefined;
// cursor is in an import clause
// try to show exported member for imported module
const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ?
SyntaxKind.ImportDeclaration :
SyntaxKind.ExportDeclaration;
@@ -1511,7 +1505,7 @@ namespace ts.Completions {
const moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
if (!moduleSpecifier) {
return false;
return GlobalsSearch.Fail;
}
completionKind = CompletionKind.MemberLike;
@@ -1520,19 +1514,22 @@ namespace ts.Completions {
const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier);
if (!moduleSpecifierSymbol) {
symbols = emptyArray;
return true;
return GlobalsSearch.Fail;
}
const exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements);
return true;
return GlobalsSearch.Success;
}
/**
* Aggregates relevant symbols for completion in class declaration
* Relevant symbols are stored in the captured 'symbols' variable.
*/
function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) {
function tryGetClassLikeCompletionSymbols(): GlobalsSearch {
const classLikeDeclaration = tryGetClassLikeCompletionContainer(contextToken);
if (!classLikeDeclaration) return GlobalsSearch.Continue;
// We're looking up possible property names from parent type.
completionKind = CompletionKind.MemberLike;
// Declaring new property/method/accessor
@@ -1582,6 +1579,7 @@ namespace ts.Completions {
classElementModifierFlags);
}
}
return GlobalsSearch.Success;
}
/**