2
2
namespace ts . codefix {
3
3
registerCodeFix ( {
4
4
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 ;
36
24
37
- return undefined ;
25
+ const classType = checker . getTypeAtLocation ( classDecl ) as InterfaceType ;
26
+ const instantiatedExtendsType = checker . getBaseTypes ( classType ) [ 0 ] ;
38
27
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
+ } ] ;
44
46
}
45
47
}
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
+ }
47
59
}
0 commit comments