Skip to content

Commit cb9f8b8

Browse files
author
Andy Hanson
committed
completions: Add assertions that symbols are defined
1 parent 384527a commit cb9f8b8

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
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): A {
2905+
for (const v of value) {
2906+
assertDefined(v);
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: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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));
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));
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) {
@@ -2248,13 +2248,13 @@ namespace ts.Completions {
22482248
*/
22492249
function getPropertiesForCompletion(type: Type, checker: TypeChecker, isForAccess: boolean): Symbol[] {
22502250
if (!(type.flags & TypeFlags.Union)) {
2251-
return type.getApparentProperties();
2251+
return Debug.assertEachDefined(type.getApparentProperties());
22522252
}
22532253

22542254
const { types } = type as UnionType;
22552255
// 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.
22562256
const filteredTypes = isForAccess ? types : types.filter(memberType =>
22572257
!(memberType.flags & TypeFlags.Primitive || checker.isArrayLikeType(memberType) || typeHasCallOrConstructSignatures(memberType, checker)));
2258-
return checker.getAllPossiblePropertiesOfTypes(filteredTypes);
2258+
return Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(filteredTypes));
22592259
}
22602260
}

0 commit comments

Comments
 (0)