@@ -23,6 +23,14 @@ module.exports = {
23
23
create : function ( context ) {
24
24
const sourceCode = context . getSourceCode ( ) ;
25
25
26
+ function nodeKey ( node ) {
27
+ return `${ node . loc . start . line } ,${ node . loc . start . column } ` ;
28
+ }
29
+
30
+ function nodeDescriptor ( n ) {
31
+ return n . openingElement ? n . openingElement . name . name : sourceCode . getText ( n ) . replace ( / \n / g, '' ) ;
32
+ }
33
+
26
34
return {
27
35
JSXElement : function ( node ) {
28
36
const children = node . children ;
@@ -37,6 +45,7 @@ module.exports = {
37
45
const closingElementStartLine = closingElement . loc . start . line ;
38
46
39
47
const childrenGroupedByLine = { } ;
48
+ const fixDetailsByNode = { } ;
40
49
41
50
children . forEach ( child => {
42
51
let countNewLinesBeforeContent = 0 ;
@@ -105,28 +114,60 @@ module.exports = {
105
114
( child . type === 'Literal' && child . raw . match ( / $ / ) ) ||
106
115
sourceCode . isSpaceBetweenTokens ( child , nextChild ) ;
107
116
}
108
- const leadingSpace = prevChild && spaceBetweenPrev ( ) ? '\n{\' \'}' : '' ;
109
- const trailingSpace = nextChild && spaceBetweenNext ( ) ? '{\' \'}\n' : '' ;
110
- const leadingNewLine = prevChild ? '\n' : '' ;
111
- const trailingNewLine = nextChild ? '\n' : '' ;
112
117
113
118
if ( ! prevChild && ! nextChild ) {
114
119
return ;
115
120
}
116
121
117
122
const source = sourceCode . getText ( child ) ;
123
+ const leadingSpace = ! ! ( prevChild && spaceBetweenPrev ( ) ) ;
124
+ const trailingSpace = ! ! ( nextChild && spaceBetweenNext ( ) ) ;
125
+ const leadingNewLine = ! ! ( prevChild ) ;
126
+ const trailingNewLine = ! ! ( nextChild ) ;
127
+
128
+ const key = nodeKey ( child ) ;
129
+
130
+ if ( ! fixDetailsByNode [ key ] ) {
131
+ fixDetailsByNode [ key ] = {
132
+ node : child ,
133
+ source : source ,
134
+ descriptor : nodeDescriptor ( child )
135
+ } ;
136
+ }
118
137
119
- function nodeDescriptor ( n ) {
120
- return n . openingElement ? n . openingElement . name . name : source . replace ( / \n / g, '' ) ;
138
+ if ( leadingSpace ) {
139
+ fixDetailsByNode [ key ] . leadingSpace = true ;
140
+ }
141
+ if ( leadingNewLine ) {
142
+ fixDetailsByNode [ key ] . leadingNewLine = true ;
121
143
}
144
+ if ( trailingNewLine ) {
145
+ fixDetailsByNode [ key ] . trailingNewLine = true ;
146
+ }
147
+ if ( trailingSpace ) {
148
+ fixDetailsByNode [ key ] . trailingSpace = true ;
149
+ }
150
+ } ) ;
151
+ } ) ;
122
152
123
- context . report ( {
124
- node : child ,
125
- message : `\`${ nodeDescriptor ( child ) } \` must be placed on a new line` ,
126
- fix : function ( fixer ) {
127
- return fixer . replaceText ( child , `${ leadingSpace } ${ leadingNewLine } ${ source } ${ trailingNewLine } ${ trailingSpace } ` ) ;
128
- }
129
- } ) ;
153
+ Object . keys ( fixDetailsByNode ) . forEach ( key => {
154
+ const details = fixDetailsByNode [ key ] ;
155
+
156
+ const nodeToReport = details . node ;
157
+ const descriptor = details . descriptor ;
158
+ const source = details . source ;
159
+
160
+ const leadingSpaceString = details . leadingSpace ? '\n{\' \'}' : '' ;
161
+ const trailingSpaceString = details . trailingSpace ? '{\' \'}\n' : '' ;
162
+ const leadingNewLineString = details . leadingNewLine ? '\n' : '' ;
163
+ const trailingNewLineString = details . trailingNewLine ? '\n' : '' ;
164
+
165
+ context . report ( {
166
+ node : nodeToReport ,
167
+ message : `\`${ descriptor } \` must be placed on a new line` ,
168
+ fix : function ( fixer ) {
169
+ return fixer . replaceText ( nodeToReport , `${ leadingSpaceString } ${ leadingNewLineString } ${ source } ${ trailingNewLineString } ${ trailingSpaceString } ` ) ;
170
+ }
130
171
} ) ;
131
172
} ) ;
132
173
}
0 commit comments