22namespace ts . codefix {
33 registerCodeFix ( {
44 errorCodes : [ Diagnostics . Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2 . code ] ,
5- getCodeActions : ( context : CodeFixContext ) => {
6- const sourceFile = context . sourceFile ;
7- const start = context . span . start ;
8- const token = getTokenAtPosition ( sourceFile , start ) ;
9- const checker = context . program . getTypeChecker ( ) ;
10-
11- if ( token . kind === SyntaxKind . Identifier && isClassLike ( token . parent ) ) {
12- const classDecl = < ClassDeclaration > token . parent ;
13- const startPos = classDecl . members . pos ;
14-
15- const InstantiatedExtendsType = checker . getTypeFromTypeReference ( getClassExtendsHeritageClauseElement ( classDecl ) ) as InterfaceType ;
16- // Note that this is ultimately derived from a map indexed by symbol names,
17- // so duplicates cannot occur.
18- const extendsSymbols = checker . getPropertiesOfType ( InstantiatedExtendsType ) ;
19- const abstractAndNonPrivateExtendsSymbols = extendsSymbols . filter ( symbolPointsToNonPrivateAndAbstractMember ) ;
20-
21- const insertion = getMissingMembersInsertion ( classDecl , abstractAndNonPrivateExtendsSymbols , checker , context . newLineCharacter ) ;
22-
23- if ( insertion . length ) {
24- return [ {
25- description : getLocaleSpecificMessage ( Diagnostics . Implement_inherited_abstract_class ) ,
26- changes : [ {
27- fileName : sourceFile . fileName ,
28- textChanges : [ {
29- span : { start : startPos , length : 0 } ,
30- newText : insertion
31- } ]
32- } ]
33- } ] ;
34- }
35- }
5+ getCodeActions : getActionForClassLikeMissingAbstractMember
6+ } ) ;
7+
8+ registerCodeFix ( {
9+ errorCodes : [ Diagnostics . Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1 . code ] ,
10+ getCodeActions : getActionForClassLikeMissingAbstractMember
11+ } ) ;
12+
13+ function getActionForClassLikeMissingAbstractMember ( context : CodeFixContext ) : CodeAction [ ] | undefined {
14+ const sourceFile = context . sourceFile ;
15+ const start = context . span . start ;
16+ // This is the identifier in the case of a class declaration
17+ // or the class keyword token in the case of a class expression.
18+ const token = getTokenAtPosition ( sourceFile , start ) ;
19+ const checker = context . program . getTypeChecker ( ) ;
20+
21+ if ( isClassLike ( token . parent ) ) {
22+ const classDecl = token . parent as ClassLikeDeclaration ;
23+ const startPos = classDecl . members . pos ;
3624
37- return undefined ;
25+ const classType = checker . getTypeAtLocation ( classDecl ) as InterfaceType ;
26+ const instantiatedExtendsType = checker . getBaseTypes ( classType ) [ 0 ] ;
3827
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 ) ;
28+ // Note that this is ultimately derived from a map indexed by symbol names,
29+ // so duplicates cannot occur.
30+ const extendsSymbols = checker . getPropertiesOfType ( instantiatedExtendsType ) ;
31+ const abstractAndNonPrivateExtendsSymbols = extendsSymbols . filter ( symbolPointsToNonPrivateAndAbstractMember ) ;
32+
33+ const insertion = getMissingMembersInsertion ( classDecl , abstractAndNonPrivateExtendsSymbols , checker , context . newLineCharacter ) ;
34+
35+ if ( insertion . length ) {
36+ return [ {
37+ description : getLocaleSpecificMessage ( Diagnostics . Implement_inherited_abstract_class ) ,
38+ changes : [ {
39+ fileName : sourceFile . fileName ,
40+ textChanges : [ {
41+ span : { start : startPos , length : 0 } ,
42+ newText : insertion
43+ } ]
44+ } ]
45+ } ] ;
4446 }
4547 }
46- } ) ;
48+
49+ return undefined ;
50+
51+ }
52+
53+ function symbolPointsToNonPrivateAndAbstractMember ( symbol : Symbol ) : boolean {
54+ const decls = symbol . getDeclarations ( ) ;
55+ Debug . assert ( ! ! ( decls && decls . length > 0 ) ) ;
56+ const flags = getModifierFlags ( decls [ 0 ] ) ;
57+ return ! ( flags & ModifierFlags . Private ) && ! ! ( flags & ModifierFlags . Abstract ) ;
58+ }
4759}
0 commit comments