mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-01 03:50:58 -06:00
Use array instead of map
This commit is contained in:
parent
680af0f782
commit
16b146f882
@ -13,14 +13,12 @@ namespace ts.codefix {
|
||||
const startPos = classDecl.members.pos;
|
||||
|
||||
const InstantiatedExtendsType = <InterfaceType>checker.getTypeFromTypeReference(getClassExtendsHeritageClauseElement(classDecl));
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
const extendsSymbols = checker.getPropertiesOfType(InstantiatedExtendsType);
|
||||
let extendsAbstractSymbolsMap = createMap<Symbol>();
|
||||
for (const symbol of extendsSymbols) {
|
||||
extendsAbstractSymbolsMap[symbol.getName()] = symbol;
|
||||
}
|
||||
extendsAbstractSymbolsMap = filterAbstractAndNonPrivate(extendsAbstractSymbolsMap);
|
||||
const abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember);
|
||||
|
||||
const insertion = getMissingMembersInsertion(classDecl, extendsAbstractSymbolsMap, checker, context.newLineCharacter);
|
||||
const insertion = getMissingMembersInsertion(classDecl, abstractAndNonPrivateExtendsSymbols, checker, context.newLineCharacter);
|
||||
|
||||
if (insertion.length > 0) {
|
||||
return [{
|
||||
@ -37,6 +35,13 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
function symbolPointsToNonPrivateAndAbstractMember(symbol: Symbol): boolean {
|
||||
const decls = symbol.getDeclarations();
|
||||
Debug.assert(!!(decls && decls.length > 0));
|
||||
const flags = getModifierFlags(decls[0]);
|
||||
return !(flags & ModifierFlags.Private) && !!(flags & ModifierFlags.Abstract);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -16,22 +16,28 @@ namespace ts.codefix {
|
||||
const startPos: number = classDecl.members.pos;
|
||||
|
||||
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl);
|
||||
const implementedTypes = implementedTypeNodes.map(checker.getTypeFromTypeReference);
|
||||
const implementedTypeSymbols = implementedTypes.map(checker.getPropertiesOfType);
|
||||
|
||||
const result: CodeAction[] = [];
|
||||
|
||||
for (const symbols of implementedTypeSymbols) {
|
||||
const symbolMap = createMap<Symbol>();
|
||||
for (const symbol of symbols) {
|
||||
symbolMap[symbol.getName()] = symbol;
|
||||
}
|
||||
const insertion = getMissingMembersInsertion(classDecl, filterNonPrivate(symbolMap), checker, context.newLineCharacter);
|
||||
for (const implementedTypeNode of implementedTypeNodes) {
|
||||
const implementedType = checker.getTypeFromTypeReference(implementedTypeNode);
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
|
||||
const nonPrivateMembers = implementedTypeSymbols.filter(symbolRefersToNonPrivateMember);
|
||||
|
||||
const insertion = getMissingMembersInsertion(classDecl, nonPrivateMembers, checker, context.newLineCharacter);
|
||||
pushAction(result, insertion, getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function symbolRefersToNonPrivateMember(symbol: Symbol): boolean {
|
||||
const decls = symbol.getDeclarations();
|
||||
Debug.assert(!!(decls && decls.length > 0));
|
||||
return !(getModifierFlags(decls[0]) & ModifierFlags.Private);
|
||||
}
|
||||
|
||||
function pushAction(result: CodeAction[], insertion: string, description: string): void {
|
||||
if (insertion && insertion.length) {
|
||||
const newAction: CodeAction = {
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
|
||||
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
|
||||
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
|
||||
///<reference path='unusedIdentifierFixes.ts' />
|
||||
///<reference path='importFixes.ts' />
|
||||
/// <reference path='unusedIdentifierFixes.ts' />
|
||||
/// <reference path='importFixes.ts' />
|
||||
|
||||
|
||||
@ -1362,51 +1362,16 @@ namespace ts {
|
||||
/**
|
||||
* 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.
|
||||
* @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
|
||||
*/
|
||||
export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Map<Symbol>, checker: TypeChecker, newlineChar: string): string {
|
||||
const missingMembers = filterMissingMembers(possiblyMissingSymbols, classDeclaration.symbol.members);
|
||||
return getInsertionsForMembers(missingMembers, classDeclaration, checker, newlineChar);
|
||||
}
|
||||
export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker, newlineChar: string): string {
|
||||
const classMembers = classDeclaration.symbol.members;
|
||||
const missingMembers = possiblyMissingSymbols.filter(symbol => !(symbol.getName() in classMembers));
|
||||
|
||||
/**
|
||||
* Finds the symbols in source but not target, generating a new map with the differences.
|
||||
*/
|
||||
function filterMissingMembers(sourceSymbols: Map<Symbol>, targetSymbols: Map<Symbol>): Map<Symbol> {
|
||||
const result: Map<Symbol> = createMap<Symbol>();
|
||||
for (const sourceName in sourceSymbols) {
|
||||
if (!(sourceName in targetSymbols)) {
|
||||
result[sourceName] = sourceSymbols[sourceName];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function filterSymbolMapByDeclaration(symbolMap: Map<Symbol>, pred: (decl: Declaration) => boolean): Map<Symbol> {
|
||||
const result = createMap<Symbol>();
|
||||
for (const key in symbolMap) {
|
||||
const declaration = symbolMap[key].getDeclarations();
|
||||
Debug.assert(!!(declaration && declaration.length));
|
||||
if (pred(declaration[0])) {
|
||||
result[key] = symbolMap[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function filterAbstractAndNonPrivate(symbolMap: Map<Symbol>) {
|
||||
return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private) && !!(getModifierFlags(decl) & ModifierFlags.Abstract));
|
||||
}
|
||||
|
||||
export function filterNonPrivate(symbolMap: Map<Symbol>) {
|
||||
return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private));
|
||||
}
|
||||
|
||||
function getInsertionsForMembers(symbolMap: MapLike<Symbol>, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string {
|
||||
let insertion = "";
|
||||
|
||||
for (const symbolName in symbolMap) {
|
||||
insertion = insertion.concat(getInsertionForMemberSymbol(symbolMap[symbolName], enclosingDeclaration, checker, newlineChar));
|
||||
for (const symbol of missingMembers) {
|
||||
insertion = insertion.concat(getInsertionForMemberSymbol(symbol, classDeclaration, checker, newlineChar));
|
||||
}
|
||||
return insertion;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user