Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2901,6 +2901,13 @@ namespace ts {
return value;
}

export function assertEachDefined<T, A extends ReadonlyArray<T>>(value: A, message: string): A {
for (const v of value) {
assertDefined(v, message);
}
return value;
}

export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never {
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
}
Expand Down
26 changes: 11 additions & 15 deletions src/services/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ namespace ts.Completions {
getTypeScriptMemberSymbols();
}
else if (isRightOfOpenTag) {
const tagSymbols = typeChecker.getJsxIntrinsicTagNames();
const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(), "getJsxIntrinsicTagNames() should all be defined");
if (tryGetGlobalSymbols()) {
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & (SymbolFlags.Value | SymbolFlags.Alias))));
}
Expand All @@ -923,7 +923,7 @@ namespace ts.Completions {
}
else if (isStartingCloseTag) {
const tagName = (<JsxElement>contextToken.parent.parent).openingElement.tagName;
const tagSymbol = typeChecker.getSymbolAtLocation(tagName);
const tagSymbol = Debug.assertDefined(typeChecker.getSymbolAtLocation(tagName));

if (!typeChecker.isUnknownSymbol(tagSymbol)) {
symbols = [tagSymbol];
Expand Down Expand Up @@ -971,7 +971,7 @@ namespace ts.Completions {

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

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

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

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

if (typeMembers && typeMembers.length > 0) {
// Add filtered items to the completion list
symbols = filterObjectMembersList(typeMembers, existingMembers);
symbols = filterObjectMembersList(typeMembers, Debug.assertDefined(existingMembers));
}
return true;
}
Expand Down Expand Up @@ -1926,11 +1926,7 @@ namespace ts.Completions {
existingImportsOrExports.set(name.escapedText, true);
}

if (existingImportsOrExports.size === 0) {
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default);
}

return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
return exportsOfModule.filter(e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
}

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

Expand Down Expand Up @@ -1980,7 +1976,7 @@ namespace ts.Completions {
existingMemberNames.set(existingName, true);
}

return filter(contextualMemberSymbols, m => !existingMemberNames.get(m.escapedName));
return contextualMemberSymbols.filter(m => !existingMemberNames.get(m.escapedName));
}

/**
Expand Down Expand Up @@ -2066,7 +2062,7 @@ namespace ts.Completions {
}
}

return filter(symbols, a => !seenNames.get(a.escapedName));
return symbols.filter(a => !seenNames.get(a.escapedName));
}

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

const { types } = type as UnionType;
// 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.
const filteredTypes = isForAccess ? types : types.filter(memberType =>
!(memberType.flags & TypeFlags.Primitive || checker.isArrayLikeType(memberType) || typeHasCallOrConstructSignatures(memberType, checker)));
return checker.getAllPossiblePropertiesOfTypes(filteredTypes);
return Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(filteredTypes), "getAllPossiblePropertiesOfTypes() should all be defined");
}
}