6
6
'use strict' ;
7
7
8
8
const propName = require ( 'jsx-ast-utils/propName' ) ;
9
+ //const astUtils = require(".node_modules\eslint\lib\rules\utils\ast-utils.js");
9
10
const includes = require ( 'array-includes' ) ;
10
11
const docsUrl = require ( '../util/docsUrl' ) ;
11
12
const jsxUtil = require ( '../util/jsx' ) ;
@@ -28,7 +29,7 @@ const messages = {
28
29
listIsEmpty : 'A customized reserved first list must not be empty' ,
29
30
listReservedPropsFirst : 'Reserved props must be listed before all other props' ,
30
31
listCallbacksLast : 'Callbacks must be listed after all other props' ,
31
- listShorthandFirst : 'Shorthand props must be listed before all other props' ,
32
+ listShorthandFirst : 'S horthand props must be listed before all other props' ,
32
33
listShorthandLast : 'Shorthand props must be listed after all other props' ,
33
34
listMultilineFirst : 'Multiline props must be listed before all other props' ,
34
35
listMultilineLast : 'Multiline props must be listed after all other props' ,
@@ -46,6 +47,12 @@ function isReservedPropName(name, list) {
46
47
return list . indexOf ( name ) >= 0 ;
47
48
}
48
49
50
+ function sorttoend ( node ) {
51
+ if ( attributemap . get ( node ) && attributemap . get ( node ) [ 1 ] ) {
52
+ return true
53
+ }
54
+ }
55
+
49
56
function contextCompare ( a , b , options ) {
50
57
let aProp = propName ( a ) ;
51
58
let bProp = propName ( b ) ;
@@ -98,6 +105,17 @@ function contextCompare(a, b, options) {
98
105
return 0 ;
99
106
}
100
107
108
+ if ( options . commentbetween ) {
109
+ const asorttoend = sorttoend ( a ) ;
110
+ const bsorttoend = sorttoend ( b ) ;
111
+ if ( asorttoend && ! bsorttoend ) {
112
+ return 1 ;
113
+ }
114
+ if ( ! asorttoend && bsorttoend ) {
115
+ return - 1 ;
116
+ }
117
+ }
118
+
101
119
const actualLocale = options . locale === 'auto' ? undefined : options . locale ;
102
120
103
121
if ( options . ignoreCase ) {
@@ -120,24 +138,67 @@ function contextCompare(a, b, options) {
120
138
* @param {Array<JSXSpreadAttribute|JSXAttribute> } attributes
121
139
* @return {Array<Array<JSXAttribute>> }
122
140
*/
123
- function getGroupsOfSortableAttributes ( attributes ) {
141
+
142
+ const attributemap = new WeakMap ( )
143
+ // attributemap = [endrange, true||false if comment inbetween nodes exists, it needs to be sorted to end ]
144
+ function getGroupsOfSortableAttributes ( attributes , context ) {
124
145
const sortableAttributeGroups = [ ] ;
146
+ const sourceCode = context . getSourceCode ( ) ;
147
+
125
148
let groupCount = 0 ;
126
149
for ( let i = 0 ; i < attributes . length ; i ++ ) {
150
+ const attribute = attributes [ i ] ;
151
+ const nextattribute = attributes [ i + 1 ] ;
152
+ const attributeline = attribute . loc . start . line ;
153
+ const comment = sourceCode . getCommentsAfter ( attribute ) ;
127
154
const lastAttr = attributes [ i - 1 ] ;
155
+ function addtoSortableAttributeGroups ( ) { sortableAttributeGroups [ groupCount - 1 ] . push ( attribute ) } ;
128
156
// If we have no groups or if the last attribute was JSXSpreadAttribute
129
157
// then we start a new group. Append attributes to the group until we
130
158
// come across another JSXSpreadAttribute or exhaust the array.
131
159
if (
132
160
! lastAttr
133
161
|| ( lastAttr . type === 'JSXSpreadAttribute'
134
- && attributes [ i ] . type !== 'JSXSpreadAttribute' )
162
+ && attribute . type !== 'JSXSpreadAttribute' )
135
163
) {
136
164
groupCount += 1 ;
137
165
sortableAttributeGroups [ groupCount - 1 ] = [ ] ;
138
166
}
139
- if ( attributes [ i ] . type !== 'JSXSpreadAttribute' ) {
140
- sortableAttributeGroups [ groupCount - 1 ] . push ( attributes [ i ] ) ;
167
+ if ( attribute . type !== 'JSXSpreadAttribute' ) {
168
+ if ( comment . length > 0 ) {
169
+ const commentline = comment [ 0 ] . loc . start . line
170
+ if ( attributeline + 1 == commentline && comment . length == 1 && nextattribute ) {
171
+ attributemap . set ( attribute , [ nextattribute . range [ 1 ] , true ] )
172
+ addtoSortableAttributeGroups ( )
173
+ i ++
174
+ continue
175
+ }
176
+ if ( attributeline == commentline && comment . length == 1 ) {
177
+ if ( comment [ 0 ] . type == 'Block' ) {
178
+ attributemap . set ( attribute , [ nextattribute . range [ 1 ] , true ] )
179
+ addtoSortableAttributeGroups ( )
180
+ i ++
181
+ continue
182
+ }
183
+ attributemap . set ( attribute , [ comment [ 0 ] . range [ 1 ] , false ] )
184
+ addtoSortableAttributeGroups ( )
185
+ }
186
+ if ( comment . length > 1 ) {
187
+ if ( attributeline + 1 == comment [ 1 ] . loc . start . line && nextattribute ) {
188
+ const commentnextattribute = sourceCode . getCommentsAfter ( nextattribute ) ;
189
+ attributemap . set ( attribute , [ nextattribute . range [ 1 ] , true ] )
190
+ if ( commentnextattribute . length == 1 && nextattribute . loc . start . line == commentnextattribute [ 0 ] . loc . start . line ) {
191
+ attributemap . set ( attribute , [ commentnextattribute [ 0 ] . range [ 1 ] , true ] )
192
+ }
193
+ addtoSortableAttributeGroups ( )
194
+ i ++
195
+ continue
196
+ }
197
+ }
198
+ } else {
199
+ attributemap . set ( attribute , [ attribute . range [ 1 ] , false ] )
200
+ addtoSortableAttributeGroups ( )
201
+ }
141
202
}
142
203
}
143
204
return sortableAttributeGroups ;
@@ -155,6 +216,7 @@ const generateFixerFunction = (node, context, reservedList) => {
155
216
const noSortAlphabetically = configuration . noSortAlphabetically || false ;
156
217
const reservedFirst = configuration . reservedFirst || false ;
157
218
const locale = configuration . locale || 'auto' ;
219
+ const commentbetween = configuration . commentbetween || true ;
158
220
159
221
// Sort props according to the context. Only supports ignoreCase.
160
222
// Since we cannot safely move JSXSpreadAttribute (due to potential variable overrides),
@@ -169,23 +231,24 @@ const generateFixerFunction = (node, context, reservedList) => {
169
231
reservedFirst,
170
232
reservedList,
171
233
locale,
234
+ commentbetween,
172
235
} ;
173
- const sortableAttributeGroups = getGroupsOfSortableAttributes ( attributes ) ;
236
+ const sortableAttributeGroups = getGroupsOfSortableAttributes ( attributes , context ) ;
174
237
const sortedAttributeGroups = sortableAttributeGroups
175
238
. slice ( 0 )
176
- . map ( ( group ) => group . slice ( 0 ) . sort ( ( a , b ) => contextCompare ( a , b , options ) ) ) ;
239
+ . map ( ( group ) => group . slice ( 0 ) . sort ( ( a , b ) => contextCompare ( a , b , options ) ) ) ;
177
240
178
241
return function fixFunction ( fixer ) {
179
242
const fixers = [ ] ;
180
243
let source = sourceCode . getText ( ) ;
181
244
182
- // Replace each unsorted attribute with the sorted one.
183
245
sortableAttributeGroups . forEach ( ( sortableGroup , ii ) => {
184
246
sortableGroup . forEach ( ( attr , jj ) => {
185
247
const sortedAttr = sortedAttributeGroups [ ii ] [ jj ] ;
186
- const sortedAttrText = sourceCode . getText ( sortedAttr ) ;
248
+ const sortedAttrText = source . substring ( sortedAttr . range [ 0 ] , attributemap . get ( sortedAttr ) [ 0 ] )
249
+ const attrrangeEnd = attributemap . get ( attr ) [ 0 ]
187
250
fixers . push ( {
188
- range : [ attr . range [ 0 ] , attr . range [ 1 ] ] ,
251
+ range : [ attr . range [ 0 ] , attrrangeEnd ] ,
189
252
text : sortedAttrText ,
190
253
} ) ;
191
254
} ) ;
@@ -194,7 +257,7 @@ const generateFixerFunction = (node, context, reservedList) => {
194
257
fixers . sort ( ( a , b ) => b . range [ 0 ] - a . range [ 0 ] ) ;
195
258
196
259
const rangeStart = fixers [ fixers . length - 1 ] . range [ 0 ] ;
197
- const rangeEnd = fixers [ 0 ] . range [ 1 ] ;
260
+ const rangeEnd = fixers [ 0 ] . range [ 1 ] ;
198
261
199
262
fixers . forEach ( ( fix ) => {
200
263
source = `${ source . substr ( 0 , fix . range [ 0 ] ) } ${ fix . text } ${ source . substr ( fix . range [ 1 ] ) } ` ;
@@ -262,10 +325,11 @@ function reportNodeAttribute(nodeAttribute, errorType, node, context, reservedLi
262
325
errors . push ( errorType ) ;
263
326
264
327
reportedNodeAttributes . set ( nodeAttribute , errors ) ;
265
-
328
+
266
329
report ( context , messages [ errorType ] , errorType , {
267
330
node : nodeAttribute . name ,
268
331
fix : generateFixerFunction ( node , context , reservedList ) ,
332
+
269
333
} ) ;
270
334
}
271
335
0 commit comments