Skip to content

Commit 2a17825

Browse files
author
Andy
authored
completions: Add assertions that symbols are defined (#21764)
* completions: Add assertions that symbols are defined * Add assertion messages
1 parent 353cfbd commit 2a17825

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

src/compiler/core.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,6 +2901,13 @@ namespace ts {
29012901
return value;
29022902
}
29032903

2904+
export function assertEachDefined<T, A extends ReadonlyArray<T>>(value: A, message: string): A {
2905+
for (const v of value) {
2906+
assertDefined(v, message);
2907+
}
2908+
return value;
2909+
}
2910+
29042911
export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never {
29052912
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
29062913
}

src/services/completions.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ namespace ts.Completions {
912912
getTypeScriptMemberSymbols();
913913
}
914914
else if (isRightOfOpenTag) {
915-
const tagSymbols = typeChecker.getJsxIntrinsicTagNames();
915+
const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(), "getJsxIntrinsicTagNames() should all be defined");
916916
if (tryGetGlobalSymbols()) {
917917
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & (SymbolFlags.Value | SymbolFlags.Alias))));
918918
}
@@ -923,7 +923,7 @@ namespace ts.Completions {
923923
}
924924
else if (isStartingCloseTag) {
925925
const tagName = (<JsxElement>contextToken.parent.parent).openingElement.tagName;
926-
const tagSymbol = typeChecker.getSymbolAtLocation(tagName);
926+
const tagSymbol = Debug.assertDefined(typeChecker.getSymbolAtLocation(tagName));
927927

928928
if (!typeChecker.isUnknownSymbol(tagSymbol)) {
929929
symbols = [tagSymbol];
@@ -971,7 +971,7 @@ namespace ts.Completions {
971971

972972
if (symbol.flags & (SymbolFlags.Module | SymbolFlags.Enum)) {
973973
// Extract module or enum members
974-
const exportedSymbols = typeChecker.getExportsOfModule(symbol);
974+
const exportedSymbols = Debug.assertEachDefined(typeChecker.getExportsOfModule(symbol), "getExportsOfModule() should all be defined");
975975
const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess(<PropertyAccessExpression>(node.parent), symbol.name);
976976
const isValidTypeAccess = (symbol: Symbol) => symbolCanBeReferencedAtTypeLocation(symbol);
977977
const isValidAccess = isRhsOfImportDeclaration ?
@@ -1111,7 +1111,7 @@ namespace ts.Completions {
11111111

11121112
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
11131113

1114-
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
1114+
symbols = Debug.assertEachDefined(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings), "getSymbolsInScope() should all be defined");
11151115

11161116
// Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
11171117
if (options.includeInsertTextCompletions && scopeNode.kind !== SyntaxKind.SourceFile) {
@@ -1452,7 +1452,7 @@ namespace ts.Completions {
14521452

14531453
if (typeMembers && typeMembers.length > 0) {
14541454
// Add filtered items to the completion list
1455-
symbols = filterObjectMembersList(typeMembers, existingMembers);
1455+
symbols = filterObjectMembersList(typeMembers, Debug.assertDefined(existingMembers));
14561456
}
14571457
return true;
14581458
}
@@ -1926,11 +1926,7 @@ namespace ts.Completions {
19261926
existingImportsOrExports.set(name.escapedText, true);
19271927
}
19281928

1929-
if (existingImportsOrExports.size === 0) {
1930-
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default);
1931-
}
1932-
1933-
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
1929+
return exportsOfModule.filter(e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
19341930
}
19351931

19361932
/**
@@ -1940,7 +1936,7 @@ namespace ts.Completions {
19401936
* do not occur at the current position and have not otherwise been typed.
19411937
*/
19421938
function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: ReadonlyArray<Declaration>): Symbol[] {
1943-
if (!existingMembers || existingMembers.length === 0) {
1939+
if (existingMembers.length === 0) {
19441940
return contextualMemberSymbols;
19451941
}
19461942

@@ -1980,7 +1976,7 @@ namespace ts.Completions {
19801976
existingMemberNames.set(existingName, true);
19811977
}
19821978

1983-
return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.escapedName));
1979+
return contextualMemberSymbols.filter(m => !existingMemberNames.get(m.escapedName));
19841980
}
19851981

19861982
/**
@@ -2066,7 +2062,7 @@ namespace ts.Completions {
20662062
}
20672063
}
20682064

2069-
return filter(symbols, a => !seenNames.get(a.escapedName));
2065+
return symbols.filter(a => !seenNames.get(a.escapedName));
20702066
}
20712067

20722068
function isCurrentlyEditingNode(node: Node): boolean {
@@ -2248,13 +2244,13 @@ namespace ts.Completions {
22482244
*/
22492245
function getPropertiesForCompletion(type: Type, checker: TypeChecker, isForAccess: boolean): Symbol[] {
22502246
if (!(type.flags & TypeFlags.Union)) {
2251-
return type.getApparentProperties();
2247+
return Debug.assertEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined");
22522248
}
22532249

22542250
const { types } = type as UnionType;
22552251
// If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals.
22562252
const filteredTypes = isForAccess ? types : types.filter(memberType =>
22572253
!(memberType.flags & TypeFlags.Primitive || checker.isArrayLikeType(memberType) || typeHasCallOrConstructSignatures(memberType, checker)));
2258-
return checker.getAllPossiblePropertiesOfTypes(filteredTypes);
2254+
return Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(filteredTypes), "getAllPossiblePropertiesOfTypes() should all be defined");
22592255
}
22602256
}

0 commit comments

Comments
 (0)