22namespace ts . codefix {
33 registerCodeFix ( {
44 errorCodes : [ Diagnostics . Class_0_incorrectly_implements_interface_1 . 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 ( ) ;
5+ getCodeActions : getActionForClassLikeIncorrectImplementsInterface
6+ } ) ;
107
11- const classDecl = getContainingClass ( token ) ;
12- if ( ! classDecl ) {
13- return undefined ;
14- }
8+ function getActionForClassLikeIncorrectImplementsInterface ( context : CodeFixContext ) : CodeAction [ ] | undefined {
9+ const sourceFile = context . sourceFile ;
10+ const start = context . span . start ;
11+ const token = getTokenAtPosition ( sourceFile , start ) ;
12+ const checker = context . program . getTypeChecker ( ) ;
13+
14+ const classDecl = getContainingClass ( token ) ;
15+ if ( ! classDecl ) {
16+ return undefined ;
17+ }
1518
16- const startPos : number = classDecl . members . pos ;
17- const classType = checker . getTypeAtLocation ( classDecl ) ;
18- const implementedTypeNodes = getClassImplementsHeritageClauseElements ( classDecl ) ;
19- const result : CodeAction [ ] = [ ] ;
19+ const startPos : number = classDecl . members . pos ;
20+ const classType = checker . getTypeAtLocation ( classDecl ) ;
21+ const implementedTypeNodes = getClassImplementsHeritageClauseElements ( classDecl ) ;
2022
21- const hasNumericIndexSignature = ! ! checker . getIndexTypeOfType ( classType , IndexKind . Number ) ;
22- const hasStringIndexSignature = ! ! checker . getIndexTypeOfType ( classType , IndexKind . String ) ;
23+ const hasNumericIndexSignature = ! ! checker . getIndexTypeOfType ( classType , IndexKind . Number ) ;
24+ const hasStringIndexSignature = ! ! checker . getIndexTypeOfType ( classType , IndexKind . String ) ;
2325
24- for ( const implementedTypeNode of implementedTypeNodes ) {
25- const implementedType = checker . getTypeFromTypeReference ( implementedTypeNode ) as InterfaceType ;
26- // Note that this is ultimately derived from a map indexed by symbol names,
27- // so duplicates cannot occur.
28- const implementedTypeSymbols = checker . getPropertiesOfType ( implementedType ) ;
29- const nonPrivateMembers = implementedTypeSymbols . filter ( symbolRefersToNonPrivateMember ) ;
26+ const result : CodeAction [ ] = [ ] ;
27+ for ( const implementedTypeNode of implementedTypeNodes ) {
28+ const implementedType = checker . getTypeFromTypeReference ( implementedTypeNode ) as InterfaceType ;
29+ // Note that this is ultimately derived from a map indexed by symbol names,
30+ // so duplicates cannot occur.
31+ const implementedTypeSymbols = checker . getPropertiesOfType ( implementedType ) ;
32+ const nonPrivateMembers = implementedTypeSymbols . filter ( symbolRefersToNonPrivateMember ) ;
3033
31- let insertion = getMissingIndexSignatureInsertion ( implementedType , IndexKind . Number , classDecl , hasNumericIndexSignature ) ;
32- insertion += getMissingIndexSignatureInsertion ( implementedType , IndexKind . String , classDecl , hasStringIndexSignature ) ;
33- insertion += getMissingMembersInsertion ( classDecl , nonPrivateMembers , checker , context . newLineCharacter ) ;
34+ let insertion = getMissingIndexSignatureInsertion ( implementedType , IndexKind . Number , classDecl , hasNumericIndexSignature ) ;
35+ insertion += getMissingIndexSignatureInsertion ( implementedType , IndexKind . String , classDecl , hasStringIndexSignature ) ;
36+ insertion += getMissingMembersInsertion ( classDecl , nonPrivateMembers , checker , context . newLineCharacter ) ;
3437
35- const message = formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Implement_interface_0 ) , [ implementedTypeNode . getText ( ) ] ) ;
36- if ( insertion ) {
37- pushAction ( result , insertion , message ) ;
38- }
38+ const message = formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Implement_interface_0 ) , [ implementedTypeNode . getText ( ) ] ) ;
39+ if ( insertion ) {
40+ pushAction ( result , insertion , message ) ;
3941 }
42+ }
4043
41- return result ;
44+ return result ;
4245
43- function getMissingIndexSignatureInsertion ( type : InterfaceType , kind : IndexKind , enclosingDeclaration : ClassLikeDeclaration , hasIndexSigOfKind : boolean ) {
44- if ( ! hasIndexSigOfKind ) {
45- const IndexInfoOfKind = checker . getIndexInfoOfType ( type , kind ) ;
46- if ( IndexInfoOfKind ) {
47- return checker . indexSignatureToString ( IndexInfoOfKind , kind , enclosingDeclaration ) ;
48- }
46+ function getMissingIndexSignatureInsertion ( type : InterfaceType , kind : IndexKind , enclosingDeclaration : ClassLikeDeclaration , hasIndexSigOfKind : boolean ) {
47+ if ( ! hasIndexSigOfKind ) {
48+ const IndexInfoOfKind = checker . getIndexInfoOfType ( type , kind ) ;
49+ if ( IndexInfoOfKind ) {
50+ return checker . indexSignatureToString ( IndexInfoOfKind , kind , enclosingDeclaration ) ;
4951 }
50- return "" ;
5152 }
53+ return "" ;
54+ }
5255
53- function symbolRefersToNonPrivateMember ( symbol : Symbol ) : boolean {
54- const decls = symbol . getDeclarations ( ) ;
55- Debug . assert ( ! ! ( decls && decls . length > 0 ) ) ;
56- return ! ( getModifierFlags ( decls [ 0 ] ) & ModifierFlags . Private ) ;
57- }
56+ function symbolRefersToNonPrivateMember ( symbol : Symbol ) : boolean {
57+ const decls = symbol . getDeclarations ( ) ;
58+ Debug . assert ( ! ! ( decls && decls . length > 0 ) ) ;
59+ return ! ( getModifierFlags ( decls [ 0 ] ) & ModifierFlags . Private ) ;
60+ }
5861
59- function pushAction ( result : CodeAction [ ] , insertion : string , description : string ) : void {
60- const newAction : CodeAction = {
61- description : description ,
62- changes : [ {
63- fileName : sourceFile . fileName ,
64- textChanges : [ {
65- span : { start : startPos , length : 0 } ,
66- newText : insertion
67- } ]
62+ function pushAction ( result : CodeAction [ ] , insertion : string , description : string ) : void {
63+ const newAction : CodeAction = {
64+ description : description ,
65+ changes : [ {
66+ fileName : sourceFile . fileName ,
67+ textChanges : [ {
68+ span : { start : startPos , length : 0 } ,
69+ newText : insertion
6870 } ]
69- } ;
70- result . push ( newAction ) ;
71- }
71+ } ]
72+ } ;
73+ result . push ( newAction ) ;
7274 }
73- } ) ;
75+ }
7476}
0 commit comments