1
- import type { SortingNode } from '../types/sorting-node '
1
+ import type { Options as SortUnionTypesOptions } from './sort-union-types '
2
2
3
3
import {
4
4
partitionByCommentJsonSchema ,
@@ -12,76 +12,17 @@ import {
12
12
groupsJsonSchema ,
13
13
orderJsonSchema ,
14
14
} from '../utils/common-json-schemas'
15
- import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration'
16
- import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration'
17
- import { validateGroupsConfiguration } from '../utils/validate-groups-configuration'
18
- import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines'
19
- import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled'
20
- import { hasPartitionComment } from '../utils/has-partition-comment'
21
- import { createNodeIndexMap } from '../utils/create-node-index-map'
22
- import { sortNodesByGroups } from '../utils/sort-nodes-by-groups'
23
- import { getCommentsBefore } from '../utils/get-comments-before'
24
- import { makeNewlinesFixes } from '../utils/make-newlines-fixes'
25
- import { getNewlinesErrors } from '../utils/get-newlines-errors'
15
+ import { sortUnionOrIntersectionTypes } from './sort-union-types'
26
16
import { createEslintRule } from '../utils/create-eslint-rule'
27
- import { getLinesBetween } from '../utils/get-lines-between'
28
- import { getGroupNumber } from '../utils/get-group-number'
29
- import { getSourceCode } from '../utils/get-source-code'
30
- import { toSingleLine } from '../utils/to-single-line'
31
- import { rangeToDiff } from '../utils/range-to-diff'
32
- import { getSettings } from '../utils/get-settings'
33
- import { useGroups } from '../utils/use-groups'
34
- import { makeFixes } from '../utils/make-fixes'
35
- import { complete } from '../utils/complete'
36
- import { pairwise } from '../utils/pairwise'
37
-
38
- type Options = [
39
- Partial < {
40
- partitionByComment :
41
- | {
42
- block ?: string [ ] | boolean | string
43
- line ?: string [ ] | boolean | string
44
- }
45
- | string [ ]
46
- | boolean
47
- | string
48
- groups : (
49
- | { newlinesBetween : 'ignore' | 'always' | 'never' }
50
- | Group [ ]
51
- | Group
52
- ) [ ]
53
- type : 'alphabetical' | 'line-length' | 'natural' | 'custom'
54
- newlinesBetween : 'ignore' | 'always' | 'never'
55
- specialCharacters : 'remove' | 'trim' | 'keep'
56
- locales : NonNullable < Intl . LocalesArgument >
57
- partitionByNewLine : boolean
58
- order : 'desc' | 'asc'
59
- ignoreCase : boolean
60
- alphabet : string
61
- } > ,
62
- ]
63
-
64
- type Group =
65
- | 'intersection'
66
- | 'conditional'
67
- | 'function'
68
- | 'operator'
69
- | 'keyword'
70
- | 'literal'
71
- | 'nullish'
72
- | 'unknown'
73
- | 'import'
74
- | 'object'
75
- | 'named'
76
- | 'tuple'
77
- | 'union'
78
17
79
18
type MESSAGE_ID =
80
19
| 'missedSpacingBetweenIntersectionTypes'
81
20
| 'unexpectedIntersectionTypesGroupOrder'
82
21
| 'extraSpacingBetweenIntersectionTypes'
83
22
| 'unexpectedIntersectionTypesOrder'
84
23
24
+ type Options = SortUnionTypesOptions
25
+
85
26
let defaultOptions : Required < Options [ 0 ] > = {
86
27
specialCharacters : 'keep' ,
87
28
newlinesBetween : 'ignore' ,
@@ -96,215 +37,6 @@ let defaultOptions: Required<Options[0]> = {
96
37
}
97
38
98
39
export default createEslintRule < Options , MESSAGE_ID > ( {
99
- create : context => ( {
100
- TSIntersectionType : node => {
101
- let settings = getSettings ( context . settings )
102
-
103
- let options = complete ( context . options . at ( 0 ) , settings , defaultOptions )
104
- validateCustomSortConfiguration ( options )
105
- validateGroupsConfiguration (
106
- options . groups ,
107
- [
108
- 'intersection' ,
109
- 'conditional' ,
110
- 'function' ,
111
- 'operator' ,
112
- 'keyword' ,
113
- 'literal' ,
114
- 'nullish' ,
115
- 'unknown' ,
116
- 'import' ,
117
- 'object' ,
118
- 'named' ,
119
- 'tuple' ,
120
- 'union' ,
121
- ] ,
122
- [ ] ,
123
- )
124
- validateNewlinesAndPartitionConfiguration ( options )
125
-
126
- let sourceCode = getSourceCode ( context )
127
- let eslintDisabledLines = getEslintDisabledLines ( {
128
- ruleName : context . id ,
129
- sourceCode,
130
- } )
131
-
132
- let formattedMembers : SortingNode [ ] [ ] = node . types . reduce (
133
- ( accumulator : SortingNode [ ] [ ] , type ) => {
134
- let { defineGroup, getGroup } = useGroups ( options )
135
-
136
- switch ( type . type ) {
137
- case 'TSTemplateLiteralType' :
138
- case 'TSLiteralType' :
139
- defineGroup ( 'literal' )
140
- break
141
- case 'TSIndexedAccessType' :
142
- case 'TSTypeReference' :
143
- case 'TSQualifiedName' :
144
- case 'TSArrayType' :
145
- case 'TSInferType' :
146
- defineGroup ( 'named' )
147
- break
148
- case 'TSIntersectionType' :
149
- defineGroup ( 'intersection' )
150
- break
151
- case 'TSUndefinedKeyword' :
152
- case 'TSNullKeyword' :
153
- case 'TSVoidKeyword' :
154
- defineGroup ( 'nullish' )
155
- break
156
- case 'TSConditionalType' :
157
- defineGroup ( 'conditional' )
158
- break
159
- case 'TSConstructorType' :
160
- case 'TSFunctionType' :
161
- defineGroup ( 'function' )
162
- break
163
- case 'TSBooleanKeyword' :
164
- case 'TSUnknownKeyword' :
165
- case 'TSBigIntKeyword' :
166
- case 'TSNumberKeyword' :
167
- case 'TSObjectKeyword' :
168
- case 'TSStringKeyword' :
169
- case 'TSSymbolKeyword' :
170
- case 'TSNeverKeyword' :
171
- case 'TSAnyKeyword' :
172
- case 'TSThisType' :
173
- defineGroup ( 'keyword' )
174
- break
175
- case 'TSTypeOperator' :
176
- case 'TSTypeQuery' :
177
- defineGroup ( 'operator' )
178
- break
179
- case 'TSTypeLiteral' :
180
- case 'TSMappedType' :
181
- defineGroup ( 'object' )
182
- break
183
- case 'TSImportType' :
184
- defineGroup ( 'import' )
185
- break
186
- case 'TSTupleType' :
187
- defineGroup ( 'tuple' )
188
- break
189
- case 'TSUnionType' :
190
- defineGroup ( 'union' )
191
- break
192
- }
193
-
194
- let lastGroup = accumulator . at ( - 1 )
195
- let lastSortingNode = lastGroup ?. at ( - 1 )
196
- let sortingNode : SortingNode = {
197
- isEslintDisabled : isNodeEslintDisabled ( type , eslintDisabledLines ) ,
198
- size : rangeToDiff ( type , sourceCode ) ,
199
- name : sourceCode . getText ( type ) ,
200
- group : getGroup ( ) ,
201
- node : type ,
202
- }
203
- if (
204
- hasPartitionComment ( {
205
- comments : getCommentsBefore ( {
206
- tokenValueToIgnoreBefore : '&' ,
207
- node : type ,
208
- sourceCode,
209
- } ) ,
210
- partitionByComment : options . partitionByComment ,
211
- } ) ||
212
- ( options . partitionByNewLine &&
213
- lastSortingNode &&
214
- getLinesBetween ( sourceCode , lastSortingNode , sortingNode ) )
215
- ) {
216
- lastGroup = [ ]
217
- accumulator . push ( lastGroup )
218
- }
219
-
220
- lastGroup ?. push ( sortingNode )
221
-
222
- return accumulator
223
- } ,
224
- [ [ ] ] ,
225
- )
226
-
227
- for ( let nodes of formattedMembers ) {
228
- let sortNodesExcludingEslintDisabled = (
229
- ignoreEslintDisabledNodes : boolean ,
230
- ) : SortingNode [ ] =>
231
- sortNodesByGroups ( nodes , options , { ignoreEslintDisabledNodes } )
232
-
233
- let sortedNodes = sortNodesExcludingEslintDisabled ( false )
234
- let sortedNodesExcludingEslintDisabled =
235
- sortNodesExcludingEslintDisabled ( true )
236
-
237
- let nodeIndexMap = createNodeIndexMap ( sortedNodes )
238
-
239
- pairwise ( nodes , ( left , right ) => {
240
- let leftNumber = getGroupNumber ( options . groups , left )
241
- let rightNumber = getGroupNumber ( options . groups , right )
242
-
243
- let leftIndex = nodeIndexMap . get ( left ) !
244
- let rightIndex = nodeIndexMap . get ( right ) !
245
-
246
- let indexOfRightExcludingEslintDisabled =
247
- sortedNodesExcludingEslintDisabled . indexOf ( right )
248
-
249
- let messageIds : MESSAGE_ID [ ] = [ ]
250
-
251
- if (
252
- leftIndex > rightIndex ||
253
- leftIndex >= indexOfRightExcludingEslintDisabled
254
- ) {
255
- messageIds . push (
256
- leftNumber === rightNumber
257
- ? 'unexpectedIntersectionTypesOrder'
258
- : 'unexpectedIntersectionTypesGroupOrder' ,
259
- )
260
- }
261
-
262
- messageIds = [
263
- ...messageIds ,
264
- ...getNewlinesErrors ( {
265
- missedSpacingError : 'missedSpacingBetweenIntersectionTypes' ,
266
- extraSpacingError : 'extraSpacingBetweenIntersectionTypes' ,
267
- rightNum : rightNumber ,
268
- leftNum : leftNumber ,
269
- sourceCode,
270
- options,
271
- right,
272
- left,
273
- } ) ,
274
- ]
275
-
276
- for ( let messageId of messageIds ) {
277
- context . report ( {
278
- fix : fixer => [
279
- ...makeFixes ( {
280
- sortedNodes : sortedNodesExcludingEslintDisabled ,
281
- sourceCode,
282
- options,
283
- fixer,
284
- nodes,
285
- } ) ,
286
- ...makeNewlinesFixes ( {
287
- sortedNodes : sortedNodesExcludingEslintDisabled ,
288
- sourceCode,
289
- options,
290
- fixer,
291
- nodes,
292
- } ) ,
293
- ] ,
294
- data : {
295
- right : toSingleLine ( right . name ) ,
296
- left : toSingleLine ( left . name ) ,
297
- rightGroup : right . group ,
298
- leftGroup : left . group ,
299
- } ,
300
- node : right . node ,
301
- messageId,
302
- } )
303
- }
304
- } )
305
- }
306
- } ,
307
- } ) ,
308
40
meta : {
309
41
schema : [
310
42
{
@@ -346,6 +78,21 @@ export default createEslintRule<Options, MESSAGE_ID>({
346
78
type : 'suggestion' ,
347
79
fixable : 'code' ,
348
80
} ,
81
+ create : context => ( {
82
+ TSIntersectionType : node => {
83
+ sortUnionOrIntersectionTypes ( {
84
+ availableMessageIds : {
85
+ missedSpacingBetweenMembers : 'missedSpacingBetweenIntersectionTypes' ,
86
+ extraSpacingBetweenMembers : 'extraSpacingBetweenIntersectionTypes' ,
87
+ unexpectedGroupOrder : 'unexpectedIntersectionTypesGroupOrder' ,
88
+ unexpectedOrder : 'unexpectedIntersectionTypesOrder' ,
89
+ } ,
90
+ tokenValueToIgnoreBefore : '&' ,
91
+ context,
92
+ node,
93
+ } )
94
+ } ,
95
+ } ) ,
349
96
defaultOptions : [ defaultOptions ] ,
350
97
name : 'sort-intersection-types' ,
351
98
} )
0 commit comments