Skip to content

Commit 02ee11c

Browse files
author
Andy
authored
Refactor tryGetGlobalSymbols into list of things to try (microsoft#22704)
* Refactor `tryGetGlobalSymbols` into list of things to try * Refactor to `||` expression
1 parent 0e9364f commit 02ee11c

File tree

1 file changed

+53
-55
lines changed

1 file changed

+53
-55
lines changed

src/services/completions.ts

+53-55
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ namespace ts.Completions {
2424
TypeKeywords,
2525
}
2626

27+
const enum GlobalsSearch { Continue, Success, Fail }
28+
2729
export function getCompletionsAtPosition(
2830
host: LanguageServiceHost,
2931
typeChecker: TypeChecker,
@@ -1046,52 +1048,38 @@ namespace ts.Completions {
10461048
}
10471049

10481050
function tryGetGlobalSymbols(): boolean {
1049-
let objectLikeContainer: ObjectLiteralExpression | BindingPattern;
1050-
let namedImportsOrExports: NamedImportsOrExports;
1051-
let classLikeContainer: ClassLikeDeclaration;
1052-
let jsxContainer: JsxOpeningLikeElement;
1053-
1054-
if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) {
1055-
return tryGetObjectLikeCompletionSymbols(objectLikeContainer);
1056-
}
1057-
1058-
if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) {
1059-
// cursor is in an import clause
1060-
// try to show exported member for imported module
1061-
return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports);
1062-
}
1063-
1064-
if (tryGetConstructorLikeCompletionContainer(contextToken)) {
1065-
// no members, only keywords
1066-
completionKind = CompletionKind.None;
1067-
// Declaring new property/method/accessor
1068-
isNewIdentifierLocation = true;
1069-
// Has keywords for constructor parameter
1070-
keywordFilters = KeywordCompletionFilters.ConstructorParameterKeywords;
1071-
return true;
1072-
}
1073-
1074-
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
1075-
// cursor inside class declaration
1076-
getGetClassLikeCompletionSymbols(classLikeContainer);
1077-
return true;
1078-
}
1079-
1080-
if (jsxContainer = tryGetContainingJsxElement(contextToken)) {
1081-
let attrsType: Type;
1082-
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
1083-
// Cursor is inside a JSX self-closing element or opening element
1084-
attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
1051+
const result: GlobalsSearch = tryGetObjectLikeCompletionSymbols()
1052+
|| tryGetImportOrExportClauseCompletionSymbols()
1053+
|| tryGetConstructorCompletion()
1054+
|| tryGetClassLikeCompletionSymbols()
1055+
|| tryGetJsxCompletionSymbols()
1056+
|| (getGlobalCompletions(), GlobalsSearch.Success);
1057+
return result === GlobalsSearch.Success;
1058+
}
1059+
1060+
function tryGetConstructorCompletion(): GlobalsSearch {
1061+
if (!tryGetConstructorLikeCompletionContainer(contextToken)) return GlobalsSearch.Continue;
1062+
// no members, only keywords
1063+
completionKind = CompletionKind.None;
1064+
// Declaring new property/method/accessor
1065+
isNewIdentifierLocation = true;
1066+
// Has keywords for constructor parameter
1067+
keywordFilters = KeywordCompletionFilters.ConstructorParameterKeywords;
1068+
return GlobalsSearch.Success;
1069+
}
10851070

1086-
if (attrsType) {
1087-
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
1088-
completionKind = CompletionKind.MemberLike;
1089-
isNewIdentifierLocation = false;
1090-
return true;
1091-
}
1092-
}
1093-
}
1071+
function tryGetJsxCompletionSymbols(): GlobalsSearch {
1072+
const jsxContainer = tryGetContainingJsxElement(contextToken);
1073+
// Cursor is inside a JSX self-closing element or opening element
1074+
const attrsType = jsxContainer && typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer);
1075+
if (!attrsType) return GlobalsSearch.Continue;
1076+
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties);
1077+
completionKind = CompletionKind.MemberLike;
1078+
isNewIdentifierLocation = false;
1079+
return GlobalsSearch.Success;
1080+
}
10941081

1082+
function getGlobalCompletions(): void {
10951083
if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) {
10961084
keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords;
10971085
}
@@ -1155,8 +1143,6 @@ namespace ts.Completions {
11551143
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target);
11561144
}
11571145
filterGlobalCompletion(symbols);
1158-
1159-
return true;
11601146
}
11611147

11621148
function isSnippetScope(scopeNode: Node): boolean {
@@ -1434,7 +1420,10 @@ namespace ts.Completions {
14341420
*
14351421
* @returns true if 'symbols' was successfully populated; false otherwise.
14361422
*/
1437-
function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean {
1423+
function tryGetObjectLikeCompletionSymbols(): GlobalsSearch | undefined {
1424+
const objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken);
1425+
if (!objectLikeContainer) return GlobalsSearch.Continue;
1426+
14381427
// We're looking up possible property names from contextual/inferred/declared type.
14391428
completionKind = CompletionKind.ObjectPropertyDeclaration;
14401429

@@ -1446,7 +1435,7 @@ namespace ts.Completions {
14461435
// other than those within the declared type.
14471436
isNewIdentifierLocation = true;
14481437
const typeForObject = typeChecker.getContextualType(objectLikeContainer);
1449-
if (!typeForObject) return false;
1438+
if (!typeForObject) return GlobalsSearch.Fail;
14501439
typeMembers = getPropertiesForCompletion(typeForObject, typeChecker, /*isForAccess*/ false);
14511440
existingMembers = objectLikeContainer.properties;
14521441
}
@@ -1474,7 +1463,7 @@ namespace ts.Completions {
14741463
}
14751464
if (canGetType) {
14761465
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
1477-
if (!typeForObject) return false;
1466+
if (!typeForObject) return GlobalsSearch.Fail;
14781467
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
14791468
typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter((symbol) => !(getDeclarationModifierFlagsFromSymbol(symbol) & ModifierFlags.NonPublicAccessibilityModifier));
14801469
existingMembers = objectLikeContainer.elements;
@@ -1485,7 +1474,7 @@ namespace ts.Completions {
14851474
// Add filtered items to the completion list
14861475
symbols = filterObjectMembersList(typeMembers, Debug.assertDefined(existingMembers));
14871476
}
1488-
return true;
1477+
return GlobalsSearch.Success;
14891478
}
14901479

14911480
/**
@@ -1503,15 +1492,20 @@ namespace ts.Completions {
15031492
*
15041493
* @returns true if 'symbols' was successfully populated; false otherwise.
15051494
*/
1506-
function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean {
1495+
function tryGetImportOrExportClauseCompletionSymbols(): GlobalsSearch {
1496+
const namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken);
1497+
if (!namedImportsOrExports) return undefined;
1498+
1499+
// cursor is in an import clause
1500+
// try to show exported member for imported module
15071501
const declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ?
15081502
SyntaxKind.ImportDeclaration :
15091503
SyntaxKind.ExportDeclaration;
15101504
const importOrExportDeclaration = <ImportDeclaration | ExportDeclaration>getAncestor(namedImportsOrExports, declarationKind);
15111505
const moduleSpecifier = importOrExportDeclaration.moduleSpecifier;
15121506

15131507
if (!moduleSpecifier) {
1514-
return false;
1508+
return GlobalsSearch.Fail;
15151509
}
15161510

15171511
completionKind = CompletionKind.MemberLike;
@@ -1520,19 +1514,22 @@ namespace ts.Completions {
15201514
const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier);
15211515
if (!moduleSpecifierSymbol) {
15221516
symbols = emptyArray;
1523-
return true;
1517+
return GlobalsSearch.Fail;
15241518
}
15251519

15261520
const exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol);
15271521
symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements);
1528-
return true;
1522+
return GlobalsSearch.Success;
15291523
}
15301524

15311525
/**
15321526
* Aggregates relevant symbols for completion in class declaration
15331527
* Relevant symbols are stored in the captured 'symbols' variable.
15341528
*/
1535-
function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) {
1529+
function tryGetClassLikeCompletionSymbols(): GlobalsSearch {
1530+
const classLikeDeclaration = tryGetClassLikeCompletionContainer(contextToken);
1531+
if (!classLikeDeclaration) return GlobalsSearch.Continue;
1532+
15361533
// We're looking up possible property names from parent type.
15371534
completionKind = CompletionKind.MemberLike;
15381535
// Declaring new property/method/accessor
@@ -1582,6 +1579,7 @@ namespace ts.Completions {
15821579
classElementModifierFlags);
15831580
}
15841581
}
1582+
return GlobalsSearch.Success;
15851583
}
15861584

15871585
/**

0 commit comments

Comments
 (0)