@@ -18,7 +18,9 @@ namespace ts.codefix {
18
18
19
19
switch ( token . kind ) {
20
20
case ts . SyntaxKind . Identifier :
21
- return deleteIdentifier ( ) ;
21
+ let actions = deleteIdentifier ( < Identifier > token ) ;
22
+ ( actions || ( actions = [ ] ) ) . push ( prefixIdentifierWithUnderscore ( < Identifier > token ) ) ;
23
+ return actions ;
22
24
23
25
case SyntaxKind . PropertyDeclaration :
24
26
case SyntaxKind . NamespaceImport :
@@ -40,58 +42,68 @@ namespace ts.codefix {
40
42
}
41
43
}
42
44
43
- function deleteIdentifier ( ) : CodeAction [ ] | undefined {
44
- switch ( token . parent . kind ) {
45
+ function prefixIdentifierWithUnderscore ( identifier : Identifier ) : CodeAction {
46
+ // TODO: make sure this work with prefixing trivia.
47
+ const startPosition = identifier . getStart ( sourceFile , /*includeJsDocComment*/ false ) ;
48
+ return {
49
+ description : formatStringFromArgs ( getLocaleSpecificMessage ( Diagnostics . Prefix_0_with_an_underscore ) , { 0 : token . getText ( ) } ) ,
50
+ changes : [ {
51
+ fileName : sourceFile . path ,
52
+ textChanges : [ {
53
+ span : { start : startPosition , length : 0 } ,
54
+ newText : "_"
55
+ } ]
56
+ } ]
57
+ } ;
58
+ }
59
+
60
+ function deleteIdentifier ( identifier : Identifier ) : CodeAction [ ] | undefined {
61
+ const parent = identifier . parent ;
62
+ switch ( parent . kind ) {
45
63
case ts . SyntaxKind . VariableDeclaration :
46
- return deleteVariableDeclaration ( < ts . VariableDeclaration > token . parent ) ;
64
+ return deleteVariableDeclaration ( < ts . VariableDeclaration > parent ) ;
47
65
48
66
case SyntaxKind . TypeParameter :
49
- const typeParameters = ( < DeclarationWithTypeParameters > token . parent . parent ) . typeParameters ;
67
+ const typeParameters = ( < DeclarationWithTypeParameters > parent . parent ) . typeParameters ;
50
68
if ( typeParameters . length === 1 ) {
51
69
const previousToken = getTokenAtPosition ( sourceFile , typeParameters . pos - 1 , /*includeJsDocComment*/ false ) ;
52
- if ( ! previousToken || previousToken . kind !== SyntaxKind . LessThanToken ) {
53
- return deleteRange ( typeParameters ) ;
54
- }
55
70
const nextToken = getTokenAtPosition ( sourceFile , typeParameters . end , /*includeJsDocComment*/ false ) ;
56
- if ( ! nextToken || nextToken . kind !== SyntaxKind . GreaterThanToken ) {
57
- return deleteRange ( typeParameters ) ;
58
- }
71
+ Debug . assert ( previousToken . kind === SyntaxKind . LessThanToken ) ;
72
+ Debug . assert ( nextToken . kind === SyntaxKind . GreaterThanToken ) ;
73
+
59
74
return deleteNodeRange ( previousToken , nextToken ) ;
60
75
}
61
76
else {
62
- return deleteNodeInList ( token . parent ) ;
77
+ return deleteNodeInList ( parent ) ;
63
78
}
64
79
65
80
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
- }
81
+ const functionDeclaration = < FunctionDeclaration > parent . parent ;
82
+ return functionDeclaration . parameters . length === 1 ?
83
+ deleteNode ( parent ) :
84
+ deleteNodeInList ( parent ) ;
73
85
74
86
// handle case where 'import a = A;'
75
87
case SyntaxKind . ImportEqualsDeclaration :
76
- const importEquals = getAncestor ( token , SyntaxKind . ImportEqualsDeclaration ) ;
88
+ const importEquals = getAncestor ( identifier , SyntaxKind . ImportEqualsDeclaration ) ;
77
89
return deleteNode ( importEquals ) ;
78
90
79
91
case SyntaxKind . ImportSpecifier :
80
- const namedImports = < NamedImports > token . parent . parent ;
92
+ const namedImports = < NamedImports > parent . parent ;
81
93
if ( namedImports . elements . length === 1 ) {
82
94
// Only 1 import and it is unused. So the entire declaration should be removed.
83
- const importSpec = getAncestor ( token , SyntaxKind . ImportDeclaration ) ;
95
+ const importSpec = getAncestor ( identifier , SyntaxKind . ImportDeclaration ) ;
84
96
return deleteNode ( importSpec ) ;
85
97
}
86
98
else {
87
99
// delete import specifier
88
- return deleteNodeInList ( token . parent ) ;
100
+ return deleteNodeInList ( parent ) ;
89
101
}
90
102
91
103
// handle case where "import d, * as ns from './file'"
92
104
// or "'import {a, b as ns} from './file'"
93
105
case SyntaxKind . ImportClause : // this covers both 'import |d|' and 'import |d,| *'
94
- const importClause = < ImportClause > token . parent ;
106
+ const importClause = < ImportClause > parent ;
95
107
if ( ! importClause . namedBindings ) { // |import d from './file'| or |import * as ns from './file'|
96
108
const importDecl = getAncestor ( importClause , SyntaxKind . ImportDeclaration ) ;
97
109
return deleteNode ( importDecl ) ;
@@ -110,8 +122,8 @@ namespace ts.codefix {
110
122
}
111
123
112
124
case SyntaxKind . NamespaceImport :
113
- const namespaceImport = < NamespaceImport > token . parent ;
114
- if ( namespaceImport . name === token && ! ( < ImportClause > namespaceImport . parent ) . name ) {
125
+ const namespaceImport = < NamespaceImport > parent ;
126
+ if ( namespaceImport . name === identifier && ! ( < ImportClause > namespaceImport . parent ) . name ) {
115
127
const importDecl = getAncestor ( namespaceImport , SyntaxKind . ImportDeclaration ) ;
116
128
return deleteNode ( importDecl ) ;
117
129
}
0 commit comments