@@ -46,14 +46,6 @@ module.exports = {
46
46
} , {
47
47
type : 'integer'
48
48
} ]
49
- } , {
50
- type : 'object' ,
51
- properties : {
52
- indentLogicalExpressions : {
53
- type : 'boolean'
54
- }
55
- } ,
56
- additionalProperties : false
57
49
} ]
58
50
} ,
59
51
@@ -64,7 +56,6 @@ module.exports = {
64
56
var extraColumnStart = 0 ;
65
57
var indentType = 'space' ;
66
58
var indentSize = 4 ;
67
- var indentLogicalExpressions = false ;
68
59
69
60
var sourceCode = context . getSourceCode ( ) ;
70
61
@@ -76,25 +67,24 @@ module.exports = {
76
67
indentSize = context . options [ 0 ] ;
77
68
indentType = 'space' ;
78
69
}
79
- if ( context . options [ 1 ] ) {
80
- indentLogicalExpressions = context . options [ 1 ] . indentLogicalExpressions || false ;
81
- }
82
70
}
83
71
84
72
var indentChar = indentType === 'space' ? ' ' : '\t' ;
85
73
86
74
/**
87
75
* Responsible for fixing the indentation issue fix
88
- * @param {Boolean } rangeToReplace is used to specify the range
89
- * to replace with the correct indentation.
76
+ * @param {ASTNode } node Node violating the indent rule
90
77
* @param {Number } needed Expected indentation character count
91
78
* @returns {Function } function to be executed by the fixer
92
79
* @private
93
80
*/
94
- function getFixerFunction ( rangeToReplace , needed ) {
81
+ function getFixerFunction ( node , needed ) {
95
82
return function ( fixer ) {
96
83
var indent = Array ( needed + 1 ) . join ( indentChar ) ;
97
- return fixer . replaceTextRange ( rangeToReplace , indent ) ;
84
+ return fixer . replaceTextRange (
85
+ [ node . start - node . loc . start . column , node . start ] ,
86
+ indent
87
+ ) ;
98
88
} ;
99
89
}
100
90
@@ -103,38 +93,46 @@ module.exports = {
103
93
* @param {ASTNode } node Node violating the indent rule
104
94
* @param {Number } needed Expected indentation character count
105
95
* @param {Number } gotten Indentation character count in the actual node/code
106
- * @param {Array } rangeToReplace is used in the fixer.
107
- * Defaults to the indent of the start of the node
108
- * @param {Object } loc Error line and column location (defaults to node.loc
96
+ * @param {Object } loc Error line and column location
109
97
*/
110
- function report ( node , needed , gotten , rangeToReplace , loc ) {
98
+ function report ( node , needed , gotten , loc ) {
111
99
var msgContext = {
112
100
needed : needed ,
113
101
type : indentType ,
114
102
characters : needed === 1 ? 'character' : 'characters' ,
115
103
gotten : gotten
116
104
} ;
117
- rangeToReplace = rangeToReplace || [ node . start - node . loc . start . column , node . start ] ;
118
105
119
- context . report ( {
120
- node : node ,
121
- loc : loc || node . loc ,
122
- message : MESSAGE ,
123
- data : msgContext ,
124
- fix : getFixerFunction ( rangeToReplace , needed )
125
- } ) ;
106
+ if ( loc ) {
107
+ context . report ( {
108
+ node : node ,
109
+ loc : loc ,
110
+ message : MESSAGE ,
111
+ data : msgContext ,
112
+ fix : getFixerFunction ( node , needed )
113
+ } ) ;
114
+ } else {
115
+ context . report ( {
116
+ node : node ,
117
+ message : MESSAGE ,
118
+ data : msgContext ,
119
+ fix : getFixerFunction ( node , needed )
120
+ } ) ;
121
+ }
126
122
}
127
123
128
124
/**
129
- * Get the indentation (of the proper indentType) that exists in the source
130
- * @param {String } src the source string
131
- * @param {Boolean } byLastLine whether the line checked should be the last
132
- * Defaults to the first line
133
- * @param {Boolean } excludeCommas whether to skip commas in the check
134
- * Defaults to false
135
- * @return {Number } the indentation of the indentType that exists on the line
125
+ * Get node indent
126
+ * @param {ASTNode } node Node to examine
127
+ * @param {Boolean } byLastLine get indent of node's last line
128
+ * @param {Boolean } excludeCommas skip comma on start of line
129
+ * @return {Number } Indent
136
130
*/
137
- function getIndentFromString ( src , byLastLine , excludeCommas ) {
131
+ function getNodeIndent ( node , byLastLine , excludeCommas ) {
132
+ byLastLine = byLastLine || false ;
133
+ excludeCommas = excludeCommas || false ;
134
+
135
+ var src = sourceCode . getText ( node , node . loc . start . column + extraColumnStart ) ;
138
136
var lines = src . split ( '\n' ) ;
139
137
if ( byLastLine ) {
140
138
src = lines [ lines . length - 1 ] ;
@@ -156,24 +154,7 @@ module.exports = {
156
154
}
157
155
158
156
/**
159
- * Get node indent
160
- * @param {ASTNode } node Node to examine
161
- * @param {Boolean } byLastLine get indent of node's last line
162
- * @param {Boolean } excludeCommas skip comma on start of line
163
- * @return {Number } Indent
164
- */
165
- function getNodeIndent ( node , byLastLine , excludeCommas ) {
166
- byLastLine = byLastLine || false ;
167
- excludeCommas = excludeCommas || false ;
168
-
169
- var src = sourceCode . getText ( node , node . loc . start . column + extraColumnStart ) ;
170
-
171
- return getIndentFromString ( src , byLastLine , excludeCommas ) ;
172
- }
173
-
174
- /**
175
- * Checks if the node is the first in its own start line. By default it looks by start line.
176
- * One exception is closing tags with preceeding whitespace
157
+ * Checks node is the first in its own start line. By default it looks by start line.
177
158
* @param {ASTNode } node The node to check
178
159
* @return {Boolean } true if its the first in the its start line
179
160
*/
@@ -184,9 +165,8 @@ module.exports = {
184
165
} while ( token . type === 'JSXText' && / ^ \s * $ / . test ( token . value ) ) ;
185
166
var startLine = node . loc . start . line ;
186
167
var endLine = token ? token . loc . end . line : - 1 ;
187
- var whitespaceOnly = token ? / \n \s * $ / . test ( token . value ) : false ;
188
168
189
- return startLine !== endLine || whitespaceOnly ;
169
+ return startLine !== endLine ;
190
170
}
191
171
192
172
/**
@@ -238,83 +218,41 @@ module.exports = {
238
218
}
239
219
}
240
220
241
- /**
242
- * Checks the end of the tag (>) to determine whether it's on its own line
243
- * If so, it verifies the indentation is correct and reports if it is not
244
- * @param {ASTNode } node The node to check
245
- * @param {Number } startIndent The indentation of the start of the tag
246
- */
247
- function checkTagEndIndent ( node , startIndent ) {
248
- var source = sourceCode . getText ( node ) ;
249
- var isTagEndOnOwnLine = / \n \s * \/ ? > $ / . exec ( source ) ;
250
- if ( isTagEndOnOwnLine ) {
251
- var endIndent = getIndentFromString ( source , true , false ) ;
252
- if ( endIndent !== startIndent ) {
253
- var rangeToReplace = [ node . end - node . loc . end . column , node . end - 1 ] ;
254
- report ( node , startIndent , endIndent , rangeToReplace ) ;
255
- }
256
- }
257
- }
258
-
259
- /**
260
- * Gets what the JSXOpeningElement's indentation should be
261
- * @param {ASTNode } node The JSXOpeningElement
262
- * @return {Number } the number of indentation characters it should have
263
- */
264
- function getOpeningElementIndent ( node ) {
265
- var prevToken = sourceCode . getTokenBefore ( node ) ;
266
- if ( ! prevToken ) {
267
- return 0 ;
268
- }
269
- if ( prevToken . type === 'JSXText' || prevToken . type === 'Punctuator' && prevToken . value === ',' ) {
270
- // Use the parent in a list or an array
271
- prevToken = sourceCode . getNodeByRangeIndex ( prevToken . start ) ;
272
- prevToken = prevToken . type === 'Literal' ? prevToken . parent : prevToken ;
273
- } else if ( prevToken . type === 'Punctuator' && prevToken . value === ':' ) {
274
- // Use the first non-punctuator token in a conditional expression
275
- do {
276
- prevToken = sourceCode . getTokenBefore ( prevToken ) ;
277
- } while ( prevToken . type === 'Punctuator' ) ;
278
- prevToken = sourceCode . getNodeByRangeIndex ( prevToken . range [ 0 ] ) ;
279
-
280
- while ( prevToken . parent && prevToken . parent . type !== 'ConditionalExpression' ) {
281
- prevToken = prevToken . parent ;
282
- }
283
- }
284
- prevToken = prevToken . type === 'JSXExpressionContainer' ? prevToken . expression : prevToken ;
285
-
286
- var parentElementIndent = getNodeIndent ( prevToken ) ;
287
- if ( prevToken . type === 'JSXElement' && ( ! prevToken . parent || prevToken . parent . type !== 'LogicalExpression' ) ) {
288
- parentElementIndent = getOpeningElementIndent ( prevToken . openingElement ) ;
289
- }
290
-
291
- if ( isRightInLogicalExp ( node ) && indentLogicalExpressions ) {
292
- parentElementIndent += indentSize ;
293
- }
294
-
295
- var indent = (
296
- prevToken . loc . start . line === node . loc . start . line ||
297
- isRightInLogicalExp ( node ) ||
298
- isAlternateInConditionalExp ( node )
299
- ) ? 0 : indentSize ;
300
- return parentElementIndent + indent ;
301
- }
302
-
303
221
return {
304
222
JSXOpeningElement : function ( node ) {
305
223
var prevToken = sourceCode . getTokenBefore ( node ) ;
306
224
if ( ! prevToken ) {
307
225
return ;
308
226
}
309
- var startIndent = getOpeningElementIndent ( node ) ;
310
- checkNodesIndent ( node , startIndent ) ;
311
- checkTagEndIndent ( node , startIndent ) ;
227
+ // Use the parent in a list or an array
228
+ if ( prevToken . type === 'JSXText' || prevToken . type === 'Punctuator' && prevToken . value === ',' ) {
229
+ prevToken = sourceCode . getNodeByRangeIndex ( prevToken . start ) ;
230
+ prevToken = prevToken . type === 'Literal' ? prevToken . parent : prevToken ;
231
+ // Use the first non-punctuator token in a conditional expression
232
+ } else if ( prevToken . type === 'Punctuator' && prevToken . value === ':' ) {
233
+ do {
234
+ prevToken = sourceCode . getTokenBefore ( prevToken ) ;
235
+ } while ( prevToken . type === 'Punctuator' ) ;
236
+ prevToken = sourceCode . getNodeByRangeIndex ( prevToken . range [ 0 ] ) ;
237
+ while ( prevToken . parent && prevToken . parent . type !== 'ConditionalExpression' ) {
238
+ prevToken = prevToken . parent ;
239
+ }
240
+ }
241
+ prevToken = prevToken . type === 'JSXExpressionContainer' ? prevToken . expression : prevToken ;
242
+
243
+ var parentElementIndent = getNodeIndent ( prevToken ) ;
244
+ var indent = (
245
+ prevToken . loc . start . line === node . loc . start . line ||
246
+ isRightInLogicalExp ( node ) ||
247
+ isAlternateInConditionalExp ( node )
248
+ ) ? 0 : indentSize ;
249
+ checkNodesIndent ( node , parentElementIndent + indent ) ;
312
250
} ,
313
251
JSXClosingElement : function ( node ) {
314
252
if ( ! node . parent ) {
315
253
return ;
316
254
}
317
- var peerElementIndent = getOpeningElementIndent ( node . parent . openingElement ) ;
255
+ var peerElementIndent = getNodeIndent ( node . parent . openingElement ) ;
318
256
checkNodesIndent ( node , peerElementIndent ) ;
319
257
} ,
320
258
JSXExpressionContainer : function ( node ) {
@@ -323,34 +261,6 @@ module.exports = {
323
261
}
324
262
var parentNodeIndent = getNodeIndent ( node . parent ) ;
325
263
checkNodesIndent ( node , parentNodeIndent + indentSize ) ;
326
- } ,
327
- Literal : function ( node ) {
328
- if ( ! node . parent || node . parent . type !== 'JSXElement' || node . loc . start . line === node . parent . loc . start . line ) {
329
- return ;
330
- }
331
- var parentElementIndent = getOpeningElementIndent ( node . parent . openingElement ) ;
332
- var expectedIndent = parentElementIndent + indentSize ;
333
- var source = sourceCode . getText ( node ) ;
334
- var lines = source . split ( '\n' ) ;
335
- var currentIndex = 0 ;
336
- lines . forEach ( function ( line , lineNumber ) {
337
- if ( line . trim ( ) ) {
338
- var lineIndent = getIndentFromString ( line ) ;
339
- if ( lineIndent !== expectedIndent ) {
340
- var lineStart = source . indexOf ( line , currentIndex ) ;
341
- var lineIndentStart = line . search ( / \S / ) ;
342
- var lineIndentEnd = lineStart + lineIndentStart ;
343
- var rangeToReplace = [ node . start + lineStart , node . start + lineIndentEnd ] ;
344
- var locLine = lineNumber + node . loc . start . line ;
345
- var loc = {
346
- start : { line : locLine , column : lineIndentStart } ,
347
- end : { line : locLine , column : lineIndentEnd }
348
- } ;
349
- report ( node , expectedIndent , lineIndent , rangeToReplace , loc ) ;
350
- }
351
- }
352
- currentIndex += line . length ;
353
- } ) ;
354
264
}
355
265
} ;
356
266
0 commit comments