1
- /* @internal */
1
+ /* @internal */
2
2
namespace ts . codefix {
3
3
registerCodeFix ( {
4
4
errorCodes : [ Diagnostics . Property_0_does_not_exist_on_type_1 . code ] ,
@@ -13,22 +13,27 @@ namespace ts.codefix {
13
13
// this.missing = 1;
14
14
// ^^^^^^^
15
15
const token = getTokenAtPosition ( sourceFile , start ) ;
16
-
17
16
if ( token . kind != SyntaxKind . Identifier ) {
18
17
return undefined ;
19
18
}
20
19
21
- const classDeclaration = getContainingClass ( token ) ;
22
- if ( ! classDeclaration ) {
20
+ if ( ! isPropertyAccessExpression ( token . parent ) || token . parent . expression . kind !== SyntaxKind . ThisKeyword ) {
23
21
return undefined ;
24
22
}
25
23
26
- if ( ! isPropertyAccessExpression ( token . parent ) || token . parent . expression . kind !== SyntaxKind . ThisKeyword ) {
24
+ const classMemberDeclaration = getThisContainer ( token , /*includeArrowFunctions*/ false ) ;
25
+ if ( ! isClassElement ( classMemberDeclaration ) ) {
27
26
return undefined ;
28
27
}
29
28
30
- return isInJavaScriptFile ( sourceFile ) ? getActionsForAddMissingMemberInJavaScriptFile ( ) : getActionsForAddMissingMemberInTypeScriptFile ( ) ;
29
+ const classDeclaration = < ClassLikeDeclaration > classMemberDeclaration . parent ;
30
+ if ( ! classDeclaration || ! isClassLike ( classDeclaration ) ) {
31
+ return undefined ;
32
+ }
31
33
34
+ const isStatic = hasModifier ( getThisContainer ( token , /*includeArrowFunctions*/ false ) , ModifierFlags . Static ) ;
35
+
36
+ return isInJavaScriptFile ( sourceFile ) ? getActionsForAddMissingMemberInJavaScriptFile ( ) : getActionsForAddMissingMemberInTypeScriptFile ( ) ;
32
37
33
38
function getActionsForAddMissingMemberInTypeScriptFile ( ) : CodeAction [ ] | undefined {
34
39
let typeString = "any" ;
@@ -43,47 +48,71 @@ namespace ts.codefix {
43
48
44
49
const startPos = classDeclaration . members . pos ;
45
50
46
- return [ {
51
+ const actions = [ {
47
52
description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Add_declaration_for_missing_property_0 ) , [ token . getText ( ) ] ) ,
48
53
changes : [ {
49
54
fileName : sourceFile . fileName ,
50
55
textChanges : [ {
51
56
span : { start : startPos , length : 0 } ,
52
- newText : `${ token . getFullText ( sourceFile ) } : ${ typeString } ;`
53
- } ]
54
- } ]
55
- } ,
56
- {
57
- description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Add_index_signature_for_missing_property_0 ) , [ token . getText ( ) ] ) ,
58
- changes : [ {
59
- fileName : sourceFile . fileName ,
60
- textChanges : [ {
61
- span : { start : startPos , length : 0 } ,
62
- newText : `[name: string]: ${ typeString } ;`
57
+ newText : `${ isStatic ? "static " : "" } ${ token . getFullText ( sourceFile ) } : ${ typeString } ;`
63
58
} ]
64
59
} ]
65
60
} ] ;
66
- }
67
61
68
- function getActionsForAddMissingMemberInJavaScriptFile ( ) : CodeAction [ ] | undefined {
69
- const classConstructor = getFirstConstructorWithBody ( classDeclaration ) ;
70
- if ( ! classConstructor ) {
71
- return undefined ;
62
+ if ( ! isStatic ) {
63
+ actions . push ( {
64
+ description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Add_index_signature_for_missing_property_0 ) , [ token . getText ( ) ] ) ,
65
+ changes : [ {
66
+ fileName : sourceFile . fileName ,
67
+ textChanges : [ {
68
+ span : { start : startPos , length : 0 } ,
69
+ newText : `[x: string]: ${ typeString } ;`
70
+ } ]
71
+ } ]
72
+ } ) ;
72
73
}
73
74
75
+ return actions ;
76
+ }
77
+
78
+ function getActionsForAddMissingMemberInJavaScriptFile ( ) : CodeAction [ ] | undefined {
74
79
const memberName = token . getText ( ) ;
75
- const startPos = classConstructor . body . getEnd ( ) - 1 ;
76
80
77
- return [ {
78
- description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Initialize_property_0_in_the_constructor ) , [ memberName ] ) ,
79
- changes : [ {
80
- fileName : sourceFile . fileName ,
81
- textChanges : [ {
82
- span : { start : startPos , length : 0 } ,
83
- newText : `this.${ memberName } = undefined;`
81
+ if ( isStatic ) {
82
+ if ( classDeclaration . kind === SyntaxKind . ClassExpression ) {
83
+ return undefined ;
84
+ }
85
+
86
+ const className = classDeclaration . name . getText ( ) ;
87
+
88
+ return [ {
89
+ description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Initialize_static_property_0 ) , [ memberName ] ) ,
90
+ changes : [ {
91
+ fileName : sourceFile . fileName ,
92
+ textChanges : [ {
93
+ span : { start : classDeclaration . getEnd ( ) , length : 0 } ,
94
+ newText : `${ context . newLineCharacter } ${ className } .${ memberName } = undefined;${ context . newLineCharacter } `
95
+ } ]
84
96
} ]
85
- } ]
86
- } ] ;
97
+ } ] ;
98
+ }
99
+ else {
100
+ const classConstructor = getFirstConstructorWithBody ( classDeclaration ) ;
101
+ if ( ! classConstructor ) {
102
+ return undefined ;
103
+ }
104
+
105
+ return [ {
106
+ description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Initialize_property_0_in_the_constructor ) , [ memberName ] ) ,
107
+ changes : [ {
108
+ fileName : sourceFile . fileName ,
109
+ textChanges : [ {
110
+ span : { start : classConstructor . body . getEnd ( ) - 1 , length : 0 } ,
111
+ newText : `this.${ memberName } = undefined;${ context . newLineCharacter } `
112
+ } ]
113
+ } ]
114
+ } ] ;
115
+ }
87
116
}
88
117
}
89
118
}
0 commit comments