1
1
import {
2
2
AST_NODE_TYPES ,
3
- AST_TOKEN_TYPES ,
4
3
TSESTree ,
5
4
} from '@typescript-eslint/experimental-utils' ;
6
5
import * as util from '../util' ;
@@ -129,31 +128,6 @@ export default util.createRule<Options, MessageIds>({
129
128
const defaultOption = options . default ;
130
129
const readonlyOption = options . readonly ?? defaultOption ;
131
130
132
- const isArraySimpleOption =
133
- defaultOption === 'array-simple' && readonlyOption === 'array-simple' ;
134
- const isArrayOption =
135
- defaultOption === 'array' && readonlyOption === 'array' ;
136
- const isGenericOption =
137
- defaultOption === 'generic' && readonlyOption === 'generic' ;
138
-
139
- /**
140
- * Check if whitespace is needed before this node
141
- * @param node the node to be evaluated.
142
- */
143
- function requireWhitespaceBefore ( node : TSESTree . Node ) : boolean {
144
- const prevToken = sourceCode . getTokenBefore ( node ) ;
145
- if ( ! prevToken ) {
146
- return false ;
147
- }
148
-
149
- const nextToken = sourceCode . getTokenAfter ( prevToken ) ;
150
- if ( nextToken && sourceCode . isSpaceBetweenTokens ( prevToken , nextToken ) ) {
151
- return false ;
152
- }
153
-
154
- return prevToken . type === AST_TOKEN_TYPES . Identifier ;
155
- }
156
-
157
131
/**
158
132
* @param node the node to be evaluated.
159
133
*/
@@ -169,121 +143,80 @@ export default util.createRule<Options, MessageIds>({
169
143
return 'T' ;
170
144
}
171
145
172
- /**
173
- * @param node the node to be evaluated
174
- */
175
- function getTypeOpNodeRange (
176
- node : TSESTree . Node | null ,
177
- ) : [ number , number ] | undefined {
178
- if ( ! node ) {
179
- return undefined ;
180
- }
181
-
182
- const firstToken = sourceCode . getFirstToken ( node ) ! ;
183
- const nextToken = sourceCode . getTokenAfter ( firstToken ) ! ;
184
- return [ firstToken . range [ 0 ] , nextToken . range [ 0 ] ] ;
185
- }
186
-
187
146
return {
188
147
TSArrayType ( node ) : void {
189
- if (
190
- isArrayOption ||
191
- ( isArraySimpleOption && isSimpleType ( node . elementType ) )
192
- ) {
193
- return ;
194
- }
195
-
196
148
const isReadonly =
197
149
node . parent &&
198
150
node . parent . type === AST_NODE_TYPES . TSTypeOperator &&
199
151
node . parent . operator === 'readonly' ;
200
152
201
- const isReadonlyGeneric =
202
- readonlyOption === 'generic' && defaultOption !== 'generic' ;
203
-
204
- const isReadonlyArray =
205
- readonlyOption !== 'generic' && defaultOption === 'generic' ;
153
+ const currentOption = isReadonly ? readonlyOption : defaultOption ;
206
154
207
155
if (
208
- ( isReadonlyGeneric && ! isReadonly ) ||
209
- ( isReadonlyArray && isReadonly )
156
+ currentOption === 'array' ||
157
+ ( currentOption === 'array-simple' && isSimpleType ( node . elementType ) )
210
158
) {
211
159
return ;
212
160
}
213
161
214
162
const messageId =
215
- defaultOption === 'generic'
163
+ currentOption === 'generic'
216
164
? 'errorStringGeneric'
217
165
: 'errorStringGenericSimple' ;
218
- const typeOpNode = isReadonly ? node . parent ! : null ;
166
+ const errorNode = isReadonly ? node . parent ! : node ;
219
167
220
168
context . report ( {
221
- node : isReadonly ? node . parent ! : node ,
169
+ node : errorNode ,
222
170
messageId,
223
171
data : {
224
172
type : getMessageType ( node . elementType ) ,
225
173
} ,
226
174
fix ( fixer ) {
227
- const toFix = [
228
- fixer . replaceTextRange ( [ node . range [ 1 ] - 2 , node . range [ 1 ] ] , '>' ) ,
229
- ] ;
230
- const startText = requireWhitespaceBefore ( node ) ;
231
- const typeOpNodeRange = getTypeOpNodeRange ( typeOpNode ) ;
175
+ const typeNode =
176
+ node . elementType . type === AST_NODE_TYPES . TSParenthesizedType
177
+ ? node . elementType . typeAnnotation
178
+ : node . elementType ;
232
179
233
- if ( typeOpNodeRange ) {
234
- toFix . unshift ( fixer . removeRange ( typeOpNodeRange ) ) ;
235
- } else {
236
- toFix . push (
237
- fixer . insertTextBefore ( node , `${ startText ? ' ' : '' } ` ) ,
238
- ) ;
239
- }
180
+ const arrayType = isReadonly ? 'ReadonlyArray' : 'Array' ;
240
181
241
- toFix . push (
242
- fixer . insertTextBefore (
243
- node ,
244
- `${ isReadonly ? 'Readonly' : '' } Array <` ,
182
+ return [
183
+ fixer . replaceTextRange (
184
+ [ errorNode . range [ 0 ] , typeNode . range [ 0 ] ] ,
185
+ `${ arrayType } <` ,
245
186
) ,
246
- ) ;
247
-
248
- if ( node . elementType . type === AST_NODE_TYPES . TSParenthesizedType ) {
249
- const first = sourceCode . getFirstToken ( node . elementType ) ;
250
- const last = sourceCode . getLastToken ( node . elementType ) ;
251
- if ( ! first || ! last ) {
252
- return null ;
253
- }
254
-
255
- toFix . push ( fixer . remove ( first ) ) ;
256
- toFix . push ( fixer . remove ( last ) ) ;
257
- }
258
-
259
- return toFix ;
187
+ fixer . replaceTextRange (
188
+ [ typeNode . range [ 1 ] , errorNode . range [ 1 ] ] ,
189
+ '>' ,
190
+ ) ,
191
+ ] ;
260
192
} ,
261
193
} ) ;
262
194
} ,
263
195
264
196
TSTypeReference ( node ) : void {
265
197
if (
266
- isGenericOption ||
267
- node . typeName . type !== AST_NODE_TYPES . Identifier
198
+ node . typeName . type !== AST_NODE_TYPES . Identifier ||
199
+ ! (
200
+ node . typeName . name === 'Array' ||
201
+ node . typeName . name === 'ReadonlyArray'
202
+ )
268
203
) {
269
204
return ;
270
205
}
271
206
272
207
const isReadonlyArrayType = node . typeName . name === 'ReadonlyArray' ;
273
- const isArrayType = node . typeName . name === 'Array' ;
208
+ const currentOption = isReadonlyArrayType
209
+ ? readonlyOption
210
+ : defaultOption ;
274
211
275
- if (
276
- ! ( isArrayType || isReadonlyArrayType ) ||
277
- ( readonlyOption === 'generic' && isReadonlyArrayType ) ||
278
- ( defaultOption === 'generic' && ! isReadonlyArrayType )
279
- ) {
212
+ if ( currentOption === 'generic' ) {
280
213
return ;
281
214
}
282
215
283
216
const readonlyPrefix = isReadonlyArrayType ? 'readonly ' : '' ;
284
217
const typeParams = node . typeParameters ?. params ;
285
218
const messageId =
286
- defaultOption === 'array'
219
+ currentOption === 'array'
287
220
? 'errorStringArray'
288
221
: 'errorStringArraySimple' ;
289
222
@@ -305,7 +238,7 @@ export default util.createRule<Options, MessageIds>({
305
238
306
239
if (
307
240
typeParams . length !== 1 ||
308
- ( defaultOption === 'array-simple' && ! isSimpleType ( typeParams [ 0 ] ) )
241
+ ( currentOption === 'array-simple' && ! isSimpleType ( typeParams [ 0 ] ) )
309
242
) {
310
243
return ;
311
244
}
0 commit comments