diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d96db21dc37..4a4194b1097 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -84,7 +84,6 @@ namespace ts { getIntersectionType, getTypeFromTypeReference, getReturnTypeOfSignature, - resolveStructuredTypeMembers, getNonNullableType, getSymbolsInScope, getSymbolAtLocation, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f983b8d60bf..7e788600d6f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2264,7 +2264,6 @@ namespace ts { getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): ObjectType[]; - resolveStructuredTypeMembers(type: StructuredType): ResolvedType; getReturnTypeOfSignature(signature: Signature): Type; getNonNullableType(type: Type): Type; getIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type; @@ -2849,6 +2848,7 @@ namespace ts { finalArrayType?: Type; // Final array type of evolving array type } + /* @internal */ // Resolved object, union, or intersection type export interface ResolvedType extends ObjectType, UnionOrIntersectionType { members: SymbolTable; // Properties by name diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 8a9836afb54..65a6d4aba05 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -13,9 +13,14 @@ namespace ts.codefix { const startPos = classDecl.members.pos; const InstantiatedExtendsType = checker.getTypeFromTypeReference(getClassExtendsHeritageClauseElement(classDecl)); - const resolvedExtendsType = checker.resolveStructuredTypeMembers(InstantiatedExtendsType); + const extendsSymbols = checker.getPropertiesOfType(InstantiatedExtendsType); + let extendsAbstractSymbolsMap = createMap(); + for (const symbol of extendsSymbols) { + extendsAbstractSymbolsMap[symbol.getName()] = symbol; + } + extendsAbstractSymbolsMap = filterAbstractAndNonPrivate(extendsAbstractSymbolsMap); - const insertion = getMissingAbstractMembersInsertion(classDecl, resolvedExtendsType, checker, context.newLineCharacter); + const insertion = getMissingMembersInsertion(classDecl, extendsAbstractSymbolsMap, checker, context.newLineCharacter); if (insertion.length > 0) { return [{ diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index af39da7b2d0..902ccf96b62 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -17,12 +17,16 @@ namespace ts.codefix { const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl); const implementedTypes = implementedTypeNodes.map(checker.getTypeFromTypeReference); - const resolvedImplementedTypes = implementedTypes.map(checker.resolveStructuredTypeMembers); + const implementedTypeSymbols = implementedTypes.map(checker.getPropertiesOfType); const result: CodeAction[] = []; - for (const resolvedType of resolvedImplementedTypes) { - const insertion = getMissingMembersInsertion(classDecl, resolvedType, checker, context.newLineCharacter); + for (const symbols of implementedTypeSymbols) { + const symbolMap = createMap(); + for (const symbol of symbols) { + symbolMap[symbol.getName()] = symbol; + } + const insertion = getMissingMembersInsertion(classDecl, filterNonPrivate(symbolMap), checker, context.newLineCharacter); pushAction(result, insertion, getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class)); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index ec1a6320e3e..bd7ab363f9d 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1359,17 +1359,13 @@ namespace ts { }; } - export function getMissingAbstractMembersInsertion(classDeclaration: ClassLikeDeclaration, resolvedType: ResolvedType, checker: TypeChecker, newlineChar: string): string { - const missingMembers = filterMissingMembers(filterAbstract(filterNonPrivate(resolvedType.members)), classDeclaration.symbol.members); - return getInsertionsForMembers(missingMembers, classDeclaration, checker, newlineChar); - } - /** * Finds members of the resolved type that are missing in the class pointed to by class decl * and generates source code for the missing members. + * @param possiblyMissingSymbols The collection of symbols to filter. */ - export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, resolvedType: ResolvedType, checker: TypeChecker, newlineChar: string): string { - const missingMembers = filterMissingMembers(filterNonPrivate(resolvedType.members), classDeclaration.symbol.members); + export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Map, checker: TypeChecker, newlineChar: string): string { + const missingMembers = filterMissingMembers(possiblyMissingSymbols, classDeclaration.symbol.members); return getInsertionsForMembers(missingMembers, classDeclaration, checker, newlineChar); } @@ -1398,11 +1394,11 @@ namespace ts { return result; } - function filterAbstract(symbolMap: Map) { - return filterSymbolMapByDeclaration(symbolMap, decl => !!(getModifierFlags(decl) & ModifierFlags.Abstract)); + export function filterAbstractAndNonPrivate(symbolMap: Map) { + return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private) && !!(getModifierFlags(decl) & ModifierFlags.Abstract)); } - function filterNonPrivate(symbolMap: Map) { + export function filterNonPrivate(symbolMap: Map) { return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private)); }