Skip to content

Commit dda4bd0

Browse files
author
Andy
authored
fixClassDoesnotImplementInheritedAbstractMember: Don't perform fix for same class twice (microsoft#22073)
1 parent dd47f24 commit dda4bd0

4 files changed

+20
-11
lines changed

src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,22 @@ namespace ts.codefix {
1414
return changes.length === 0 ? undefined : [{ description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class), changes, fixId }];
1515
},
1616
fixIds: [fixId],
17-
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
18-
addMissingMembers(getClass(diag.file!, diag.start!), context.sourceFile, context.program.getTypeChecker(), changes);
19-
}),
17+
getAllCodeActions: context => {
18+
const seenClassDeclarations = createMap<true>();
19+
return codeFixAll(context, errorCodes, (changes, diag) => {
20+
const classDeclaration = getClass(diag.file!, diag.start!);
21+
if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) {
22+
addMissingMembers(classDeclaration, context.sourceFile, context.program.getTypeChecker(), changes);
23+
}
24+
});
25+
},
2026
});
2127

2228
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
23-
// This is the identifier in the case of a class declaration
29+
// Token is the identifier in the case of a class declaration
2430
// or the class keyword token in the case of a class expression.
2531
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
26-
const classDeclaration = token.parent;
27-
Debug.assert(isClassLike(classDeclaration));
28-
return classDeclaration as ClassLikeDeclaration;
32+
return cast(token.parent, isClassLike);
2933
}
3034

3135
function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, checker: TypeChecker, changeTracker: textChanges.ChangeTracker): void {

src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ namespace ts.codefix {
3131
});
3232

3333
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
34-
const classDeclaration = getContainingClass(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false));
35-
Debug.assert(!!classDeclaration);
36-
return classDeclaration!;
34+
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false)));
3735
}
3836

3937
function addMissingDeclarations(

tests/cases/fourslash/codeFixClassExtendAbstractMethod_all.ts

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
////abstract class A {
44
//// abstract m(): void;
5+
//// abstract n(): void;
56
////}
67
////class B extends A {}
78
////class C extends A {}
@@ -11,15 +12,22 @@ verify.codeFixAll({
1112
newFileContent:
1213
`abstract class A {
1314
abstract m(): void;
15+
abstract n(): void;
1416
}
1517
class B extends A {
1618
m(): void {
1719
throw new Error("Method not implemented.");
1820
}
21+
n(): void {
22+
throw new Error("Method not implemented.");
23+
}
1924
}
2025
class C extends A {
2126
m(): void {
2227
throw new Error("Method not implemented.");
2328
}
29+
n(): void {
30+
throw new Error("Method not implemented.");
31+
}
2432
}`,
2533
});

tests/cases/fourslash/codeFixClassImplementInterface_all.ts

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
verify.codeFixAll({
99
fixId: "fixClassIncorrectlyImplementsInterface",
10-
// TODO: GH#20073
1110
newFileContent:
1211
`interface I { i(): void; }
1312
interface J { j(): void; }

0 commit comments

Comments
 (0)