Skip to content

Commit 16b146f

Browse files
author
Arthur Ozga
committed
Use array instead of map
1 parent 680af0f commit 16b146f

File tree

4 files changed

+33
-57
lines changed

4 files changed

+33
-57
lines changed

src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@ namespace ts.codefix {
1313
const startPos = classDecl.members.pos;
1414

1515
const InstantiatedExtendsType = <InterfaceType>checker.getTypeFromTypeReference(getClassExtendsHeritageClauseElement(classDecl));
16+
// Note that this is ultimately derived from a map indexed by symbol names,
17+
// so duplicates cannot occur.
1618
const extendsSymbols = checker.getPropertiesOfType(InstantiatedExtendsType);
17-
let extendsAbstractSymbolsMap = createMap<Symbol>();
18-
for (const symbol of extendsSymbols) {
19-
extendsAbstractSymbolsMap[symbol.getName()] = symbol;
20-
}
21-
extendsAbstractSymbolsMap = filterAbstractAndNonPrivate(extendsAbstractSymbolsMap);
19+
const abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember);
2220

23-
const insertion = getMissingMembersInsertion(classDecl, extendsAbstractSymbolsMap, checker, context.newLineCharacter);
21+
const insertion = getMissingMembersInsertion(classDecl, abstractAndNonPrivateExtendsSymbols, checker, context.newLineCharacter);
2422

2523
if (insertion.length > 0) {
2624
return [{
@@ -37,6 +35,13 @@ namespace ts.codefix {
3735
}
3836

3937
return undefined;
38+
39+
function symbolPointsToNonPrivateAndAbstractMember(symbol: Symbol): boolean {
40+
const decls = symbol.getDeclarations();
41+
Debug.assert(!!(decls && decls.length > 0));
42+
const flags = getModifierFlags(decls[0]);
43+
return !(flags & ModifierFlags.Private) && !!(flags & ModifierFlags.Abstract);
44+
}
4045
}
4146
});
4247
}

src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,28 @@ namespace ts.codefix {
1616
const startPos: number = classDecl.members.pos;
1717

1818
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl);
19-
const implementedTypes = implementedTypeNodes.map(checker.getTypeFromTypeReference);
20-
const implementedTypeSymbols = implementedTypes.map(checker.getPropertiesOfType);
2119

2220
const result: CodeAction[] = [];
2321

24-
for (const symbols of implementedTypeSymbols) {
25-
const symbolMap = createMap<Symbol>();
26-
for (const symbol of symbols) {
27-
symbolMap[symbol.getName()] = symbol;
28-
}
29-
const insertion = getMissingMembersInsertion(classDecl, filterNonPrivate(symbolMap), checker, context.newLineCharacter);
22+
for (const implementedTypeNode of implementedTypeNodes) {
23+
const implementedType = checker.getTypeFromTypeReference(implementedTypeNode);
24+
// Note that this is ultimately derived from a map indexed by symbol names,
25+
// so duplicates cannot occur.
26+
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
27+
const nonPrivateMembers = implementedTypeSymbols.filter(symbolRefersToNonPrivateMember);
28+
29+
const insertion = getMissingMembersInsertion(classDecl, nonPrivateMembers, checker, context.newLineCharacter);
3030
pushAction(result, insertion, getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class));
3131
}
3232

3333
return result;
3434

35+
function symbolRefersToNonPrivateMember(symbol: Symbol): boolean {
36+
const decls = symbol.getDeclarations();
37+
Debug.assert(!!(decls && decls.length > 0));
38+
return !(getModifierFlags(decls[0]) & ModifierFlags.Private);
39+
}
40+
3541
function pushAction(result: CodeAction[], insertion: string, description: string): void {
3642
if (insertion && insertion.length) {
3743
const newAction: CodeAction = {

src/services/codefixes/fixes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
44
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
55
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
6-
///<reference path='unusedIdentifierFixes.ts' />
7-
///<reference path='importFixes.ts' />
6+
/// <reference path='unusedIdentifierFixes.ts' />
7+
/// <reference path='importFixes.ts' />
88

src/services/utilities.ts

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,51 +1362,16 @@ namespace ts {
13621362
/**
13631363
* Finds members of the resolved type that are missing in the class pointed to by class decl
13641364
* and generates source code for the missing members.
1365-
* @param possiblyMissingSymbols The collection of symbols to filter.
1365+
* @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for.
13661366
*/
1367-
export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Map<Symbol>, checker: TypeChecker, newlineChar: string): string {
1368-
const missingMembers = filterMissingMembers(possiblyMissingSymbols, classDeclaration.symbol.members);
1369-
return getInsertionsForMembers(missingMembers, classDeclaration, checker, newlineChar);
1370-
}
1371-
1372-
/**
1373-
* Finds the symbols in source but not target, generating a new map with the differences.
1374-
*/
1375-
function filterMissingMembers(sourceSymbols: Map<Symbol>, targetSymbols: Map<Symbol>): Map<Symbol> {
1376-
const result: Map<Symbol> = createMap<Symbol>();
1377-
for (const sourceName in sourceSymbols) {
1378-
if (!(sourceName in targetSymbols)) {
1379-
result[sourceName] = sourceSymbols[sourceName];
1380-
}
1381-
}
1382-
return result;
1383-
}
1384-
1385-
function filterSymbolMapByDeclaration(symbolMap: Map<Symbol>, pred: (decl: Declaration) => boolean): Map<Symbol> {
1386-
const result = createMap<Symbol>();
1387-
for (const key in symbolMap) {
1388-
const declaration = symbolMap[key].getDeclarations();
1389-
Debug.assert(!!(declaration && declaration.length));
1390-
if (pred(declaration[0])) {
1391-
result[key] = symbolMap[key];
1392-
}
1393-
}
1394-
return result;
1395-
}
1396-
1397-
export function filterAbstractAndNonPrivate(symbolMap: Map<Symbol>) {
1398-
return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private) && !!(getModifierFlags(decl) & ModifierFlags.Abstract));
1399-
}
1400-
1401-
export function filterNonPrivate(symbolMap: Map<Symbol>) {
1402-
return filterSymbolMapByDeclaration(symbolMap, decl => !(getModifierFlags(decl) & ModifierFlags.Private));
1403-
}
1367+
export function getMissingMembersInsertion(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: Symbol[], checker: TypeChecker, newlineChar: string): string {
1368+
const classMembers = classDeclaration.symbol.members;
1369+
const missingMembers = possiblyMissingSymbols.filter(symbol => !(symbol.getName() in classMembers));
14041370

1405-
function getInsertionsForMembers(symbolMap: MapLike<Symbol>, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string {
14061371
let insertion = "";
14071372

1408-
for (const symbolName in symbolMap) {
1409-
insertion = insertion.concat(getInsertionForMemberSymbol(symbolMap[symbolName], enclosingDeclaration, checker, newlineChar));
1373+
for (const symbol of missingMembers) {
1374+
insertion = insertion.concat(getInsertionForMemberSymbol(symbol, classDeclaration, checker, newlineChar));
14101375
}
14111376
return insertion;
14121377
}

0 commit comments

Comments
 (0)