@@ -18,14 +18,14 @@ namespace ts.codefix {
18
18
19
19
switch ( token . kind ) {
20
20
case ts . SyntaxKind . Identifier :
21
- return deleteIdentifier ( ) ;
21
+ return deleteIdentifierOrPrefixWithUnderscore ( < Identifier > token ) ;
22
22
23
23
case SyntaxKind . PropertyDeclaration :
24
24
case SyntaxKind . NamespaceImport :
25
- return deleteNode ( token . parent ) ;
25
+ return [ deleteNode ( token . parent ) ] ;
26
26
27
27
default :
28
- return deleteDefault ( ) ;
28
+ return [ deleteDefault ( ) ] ;
29
29
}
30
30
31
31
function deleteDefault ( ) {
@@ -40,126 +40,132 @@ namespace ts.codefix {
40
40
}
41
41
}
42
42
43
- function deleteIdentifier ( ) : CodeAction [ ] | undefined {
44
- switch ( token . parent . kind ) {
43
+ function prefixIdentifierWithUnderscore ( identifier : Identifier ) : CodeAction {
44
+ const startPosition = identifier . getStart ( sourceFile , /*includeJsDocComment*/ false ) ;
45
+ return {
46
+ description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Prefix_0_with_an_underscore ) , { 0 : token . getText ( ) } ) ,
47
+ changes : [ {
48
+ fileName : sourceFile . path ,
49
+ textChanges : [ {
50
+ span : { start : startPosition , length : 0 } ,
51
+ newText : "_"
52
+ } ]
53
+ } ]
54
+ } ;
55
+ }
56
+
57
+ function deleteIdentifierOrPrefixWithUnderscore ( identifier : Identifier ) : CodeAction [ ] | undefined {
58
+ const parent = identifier . parent ;
59
+ switch ( parent . kind ) {
45
60
case ts . SyntaxKind . VariableDeclaration :
46
- return deleteVariableDeclaration ( < ts . VariableDeclaration > token . parent ) ;
61
+ return deleteVariableDeclarationOrPrefixWithUnderscore ( identifier , < ts . VariableDeclaration > parent ) ;
47
62
48
63
case SyntaxKind . TypeParameter :
49
- const typeParameters = ( < DeclarationWithTypeParameters > token . parent . parent ) . typeParameters ;
64
+ const typeParameters = ( < DeclarationWithTypeParameters > parent . parent ) . typeParameters ;
50
65
if ( typeParameters . length === 1 ) {
51
66
const previousToken = getTokenAtPosition ( sourceFile , typeParameters . pos - 1 , /*includeJsDocComment*/ false ) ;
52
- if ( ! previousToken || previousToken . kind !== SyntaxKind . LessThanToken ) {
53
- return deleteRange ( typeParameters ) ;
54
- }
55
67
const nextToken = getTokenAtPosition ( sourceFile , typeParameters . end , /*includeJsDocComment*/ false ) ;
56
- if ( ! nextToken || nextToken . kind !== SyntaxKind . GreaterThanToken ) {
57
- return deleteRange ( typeParameters ) ;
58
- }
59
- return deleteNodeRange ( previousToken , nextToken ) ;
68
+ Debug . assert ( previousToken . kind === SyntaxKind . LessThanToken ) ;
69
+ Debug . assert ( nextToken . kind === SyntaxKind . GreaterThanToken ) ;
70
+
71
+ return [ deleteNodeRange ( previousToken , nextToken ) ] ;
60
72
}
61
73
else {
62
- return deleteNodeInList ( token . parent ) ;
74
+ return [ deleteNodeInList ( parent ) ] ;
63
75
}
64
76
65
77
case ts . SyntaxKind . Parameter :
66
- const functionDeclaration = < FunctionDeclaration > token . parent . parent ;
67
- if ( functionDeclaration . parameters . length === 1 ) {
68
- return deleteNode ( token . parent ) ;
69
- }
70
- else {
71
- return deleteNodeInList ( token . parent ) ;
72
- }
78
+ const functionDeclaration = < FunctionDeclaration > parent . parent ;
79
+ return [ functionDeclaration . parameters . length === 1 ? deleteNode ( parent ) : deleteNodeInList ( parent ) ,
80
+ prefixIdentifierWithUnderscore ( identifier ) ] ;
73
81
74
82
// handle case where 'import a = A;'
75
83
case SyntaxKind . ImportEqualsDeclaration :
76
- const importEquals = getAncestor ( token , SyntaxKind . ImportEqualsDeclaration ) ;
77
- return deleteNode ( importEquals ) ;
84
+ const importEquals = getAncestor ( identifier , SyntaxKind . ImportEqualsDeclaration ) ;
85
+ return [ deleteNode ( importEquals ) ] ;
78
86
79
87
case SyntaxKind . ImportSpecifier :
80
- const namedImports = < NamedImports > token . parent . parent ;
88
+ const namedImports = < NamedImports > parent . parent ;
81
89
if ( namedImports . elements . length === 1 ) {
82
90
// Only 1 import and it is unused. So the entire declaration should be removed.
83
- const importSpec = getAncestor ( token , SyntaxKind . ImportDeclaration ) ;
84
- return deleteNode ( importSpec ) ;
91
+ const importSpec = getAncestor ( identifier , SyntaxKind . ImportDeclaration ) ;
92
+ return [ deleteNode ( importSpec ) ] ;
85
93
}
86
94
else {
87
95
// delete import specifier
88
- return deleteNodeInList ( token . parent ) ;
96
+ return [ deleteNodeInList ( parent ) ] ;
89
97
}
90
98
91
99
// handle case where "import d, * as ns from './file'"
92
100
// or "'import {a, b as ns} from './file'"
93
101
case SyntaxKind . ImportClause : // this covers both 'import |d|' and 'import |d,| *'
94
- const importClause = < ImportClause > token . parent ;
102
+ const importClause = < ImportClause > parent ;
95
103
if ( ! importClause . namedBindings ) { // |import d from './file'| or |import * as ns from './file'|
96
104
const importDecl = getAncestor ( importClause , SyntaxKind . ImportDeclaration ) ;
97
- return deleteNode ( importDecl ) ;
105
+ return [ deleteNode ( importDecl ) ] ;
98
106
}
99
107
else {
100
108
// import |d,| * as ns from './file'
101
109
const start = importClause . name . getStart ( sourceFile ) ;
102
110
const nextToken = getTokenAtPosition ( sourceFile , importClause . name . end , /*includeJsDocComment*/ false ) ;
103
111
if ( nextToken && nextToken . kind === SyntaxKind . CommaToken ) {
104
112
// shift first non-whitespace position after comma to the start position of the node
105
- return deleteRange ( { pos : start , end : skipTrivia ( sourceFile . text , nextToken . end , /*stopAfterLineBreaks*/ false , /*stopAtComments*/ true ) } ) ;
113
+ return [ deleteRange ( { pos : start , end : skipTrivia ( sourceFile . text , nextToken . end , /*stopAfterLineBreaks*/ false , /*stopAtComments*/ true ) } ) ] ;
106
114
}
107
115
else {
108
- return deleteNode ( importClause . name ) ;
116
+ return [ deleteNode ( importClause . name ) ] ;
109
117
}
110
118
}
111
119
112
120
case SyntaxKind . NamespaceImport :
113
- const namespaceImport = < NamespaceImport > token . parent ;
114
- if ( namespaceImport . name === token && ! ( < ImportClause > namespaceImport . parent ) . name ) {
121
+ const namespaceImport = < NamespaceImport > parent ;
122
+ if ( namespaceImport . name === identifier && ! ( < ImportClause > namespaceImport . parent ) . name ) {
115
123
const importDecl = getAncestor ( namespaceImport , SyntaxKind . ImportDeclaration ) ;
116
- return deleteNode ( importDecl ) ;
124
+ return [ deleteNode ( importDecl ) ] ;
117
125
}
118
126
else {
119
127
const previousToken = getTokenAtPosition ( sourceFile , namespaceImport . pos - 1 , /*includeJsDocComment*/ false ) ;
120
128
if ( previousToken && previousToken . kind === SyntaxKind . CommaToken ) {
121
129
const startPosition = textChanges . getAdjustedStartPosition ( sourceFile , previousToken , { } , textChanges . Position . FullStart ) ;
122
- return deleteRange ( { pos : startPosition , end : namespaceImport . end } ) ;
130
+ return [ deleteRange ( { pos : startPosition , end : namespaceImport . end } ) ] ;
123
131
}
124
- return deleteRange ( namespaceImport ) ;
132
+ return [ deleteRange ( namespaceImport ) ] ;
125
133
}
126
134
127
135
default :
128
- return deleteDefault ( ) ;
136
+ return [ deleteDefault ( ) ] ;
129
137
}
130
138
}
131
139
132
140
// token.parent is a variableDeclaration
133
- function deleteVariableDeclaration ( varDecl : ts . VariableDeclaration ) : CodeAction [ ] | undefined {
141
+ function deleteVariableDeclarationOrPrefixWithUnderscore ( identifier : Identifier , varDecl : ts . VariableDeclaration ) : CodeAction [ ] | undefined {
134
142
switch ( varDecl . parent . parent . kind ) {
135
143
case SyntaxKind . ForStatement :
136
144
const forStatement = < ForStatement > varDecl . parent . parent ;
137
145
const forInitializer = < VariableDeclarationList > forStatement . initializer ;
138
- if ( forInitializer . declarations . length === 1 ) {
139
- return deleteNode ( forInitializer ) ;
140
- }
141
- else {
142
- return deleteNodeInList ( varDecl ) ;
143
- }
146
+ return [ forInitializer . declarations . length === 1 ? deleteNode ( forInitializer ) : deleteNodeInList ( varDecl ) ] ;
144
147
145
148
case SyntaxKind . ForOfStatement :
146
149
const forOfStatement = < ForOfStatement > varDecl . parent . parent ;
147
150
Debug . assert ( forOfStatement . initializer . kind === SyntaxKind . VariableDeclarationList ) ;
148
151
const forOfInitializer = < VariableDeclarationList > forOfStatement . initializer ;
149
- return replaceNode ( forOfInitializer . declarations [ 0 ] , createObjectLiteral ( ) ) ;
152
+ return [
153
+ replaceNode ( forOfInitializer . declarations [ 0 ] , createObjectLiteral ( ) ) ,
154
+ prefixIdentifierWithUnderscore ( identifier )
155
+ ] ;
150
156
151
157
case SyntaxKind . ForInStatement :
152
158
// There is no valid fix in the case of:
153
159
// for .. in
154
- return undefined ;
160
+ return [ prefixIdentifierWithUnderscore ( identifier ) ] ;
155
161
156
162
default :
157
163
const variableStatement = < VariableStatement > varDecl . parent . parent ;
158
164
if ( variableStatement . declarationList . declarations . length === 1 ) {
159
- return deleteNode ( variableStatement ) ;
165
+ return [ deleteNode ( variableStatement ) ] ;
160
166
}
161
167
else {
162
- return deleteNodeInList ( varDecl ) ;
168
+ return [ deleteNodeInList ( varDecl ) ] ;
163
169
}
164
170
}
165
171
}
@@ -184,11 +190,11 @@ namespace ts.codefix {
184
190
return makeChange ( textChanges . ChangeTracker . fromCodeFixContext ( context ) . replaceNode ( sourceFile , n , newNode ) ) ;
185
191
}
186
192
187
- function makeChange ( changeTracker : textChanges . ChangeTracker ) {
188
- return [ {
193
+ function makeChange ( changeTracker : textChanges . ChangeTracker ) : CodeAction {
194
+ return {
189
195
description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Remove_declaration_for_Colon_0 ) , { 0 : token . getText ( ) } ) ,
190
196
changes : changeTracker . getChanges ( )
191
- } ] ;
197
+ } ;
192
198
}
193
199
}
194
200
} ) ;
0 commit comments