@@ -155,7 +155,7 @@ function isComment (token) {
155
155
* @returns {boolean } `false` if the token is a comment.
156
156
*/
157
157
function isNotComment ( token ) {
158
- return token != null && ! token . type . endsWith ( 'Comment' )
158
+ return token != null && token . type !== 'Block' && token . type !== 'Line' && token . type !== 'Shebang' && ! token . type . startsWith ( 'Comment' )
159
159
}
160
160
161
161
/**
@@ -218,12 +218,12 @@ function create (context) {
218
218
* Process the given node list.
219
219
* The first node is offsetted from the given left token.
220
220
* Rest nodes are adjusted to the first node.
221
- * @param {NodeList } nodeList The node to process.
221
+ * @param {Node[] } nodeList The node to process.
222
222
* @param {boolean } canParenthized If `true` then the node can be parenthized.
223
223
* @returns {void }
224
224
*/
225
225
function processNodeList ( nodeList , leftToken , rightToken , offset ) {
226
- let t
226
+ let t , u
227
227
228
228
if ( nodeList . length >= 1 ) {
229
229
let lastToken = leftToken
@@ -232,31 +232,49 @@ function create (context) {
232
232
for ( let i = 0 ; i < nodeList . length ; ++ i ) {
233
233
const node = nodeList [ i ]
234
234
if ( node == null ) {
235
+ // Holes of an array.
235
236
continue
236
237
}
237
238
239
+ // Get the first token of the node. If it's parenthesized then get the outermost left parenthesis.
238
240
let elementFirstToken = template . getFirstToken ( node )
241
+ let elementLastToken = template . getLastToken ( node )
239
242
t = elementFirstToken
240
- while ( ( t = template . getTokenBefore ( t ) ) != null && isLeftParen ( t ) && t . range [ 0 ] >= lastToken . range [ 1 ] ) {
243
+ u = elementLastToken
244
+ while ( ( t = template . getTokenBefore ( t ) ) != null && ( u = template . getTokenAfter ( u ) ) != null && isLeftParen ( t ) && isRightParen ( u ) && t . range [ 0 ] >= lastToken . range [ 1 ] ) {
241
245
elementFirstToken = t
246
+ elementLastToken = u
242
247
}
243
248
249
+ // Collect related tokens.
250
+ // Commas between this and the previous, and the first token of this node.
244
251
t = lastToken
245
- while ( ( t = template . getTokenAfter ( t ) ) != null && t . range [ 1 ] <= elementFirstToken . range [ 0 ] ) {
246
- alignTokens . push ( t )
252
+ while ( ( u = template . getTokenAfter ( t ) ) != null && u . range [ 1 ] <= elementFirstToken . range [ 0 ] ) {
253
+ // This offset is smaller than the content, so it causes unintentional unindent.
254
+ // E.g.
255
+ // var obj = {
256
+ // key:
257
+ // value, // ← this comma is the same offset as `key`. It should avoid.
258
+ // }
259
+ if ( u . loc . start . line !== t . loc . end . line ) {
260
+ alignTokens . push ( u )
261
+ }
262
+ t = u
247
263
}
248
264
alignTokens . push ( elementFirstToken )
249
265
250
- lastToken = template . getLastToken ( node )
266
+ lastToken = elementLastToken
251
267
}
252
268
269
+ // Check trailing commas.
253
270
if ( rightToken != null ) {
254
271
let t = lastToken
255
272
while ( ( t = template . getTokenAfter ( t ) ) != null && t . range [ 1 ] <= rightToken . range [ 0 ] ) {
256
273
alignTokens . push ( t )
257
274
}
258
275
}
259
276
277
+ // Set offsets.
260
278
const baseToken = alignTokens . shift ( )
261
279
if ( baseToken != null ) {
262
280
setOffset ( baseToken , offset , leftToken )
@@ -465,19 +483,19 @@ function create (context) {
465
483
}
466
484
467
485
// Debug log
468
- console . log ( 'line' , line , '=' , indents [ line ] , 'from:' )
469
- for ( const token of tokens ) {
470
- const offsetInfo = offsets . get ( token )
471
- if ( offsetInfo == null ) {
472
- console . log ( ' ' , JSON . stringify ( sourceCode . getText ( token ) ) , 'is unknown.' )
473
- } else if ( offsetInfo . offset === 0 ) {
474
- console . log ( ' ' , JSON . stringify ( sourceCode . getText ( token ) ) , 'is the same as' , JSON . stringify ( sourceCode . getText ( offsetInfo . baseToken ) ) , '(line' , offsetInfo . baseToken . loc . start . line , ')' )
475
- } else if ( offsetInfo . offset === EXACT ) {
476
- console . log ( ' ' , JSON . stringify ( sourceCode . getText ( token ) ) , 'is the exactly same as' , JSON . stringify ( sourceCode . getText ( offsetInfo . baseToken ) ) , '(line' , offsetInfo . baseToken . loc . start . line , ')' )
477
- } else {
478
- console . log ( ' ' , JSON . stringify ( sourceCode . getText ( token ) ) , 'is' , offsetInfo . offset , 'offset from' , JSON . stringify ( sourceCode . getText ( offsetInfo . baseToken ) ) , '(line' , offsetInfo . baseToken . loc . start . line , ')' )
479
- }
480
- }
486
+ // console.log('line', line, '=', indents[line], 'from:')
487
+ // for (const token of tokens) {
488
+ // const offsetInfo = offsets.get(token)
489
+ // if (offsetInfo == null) {
490
+ // console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is unknown.')
491
+ // } else if (offsetInfo.offset === 0) {
492
+ // console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
493
+ // } else if (offsetInfo.offset === EXACT) {
494
+ // console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is the exactly same as', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
495
+ // } else {
496
+ // console.log(' ', JSON.stringify(sourceCode.getText(token)), 'is', offsetInfo.offset, 'offset from', JSON.stringify(sourceCode.getText(offsetInfo.baseToken)), '(line', offsetInfo.baseToken.loc.start.line, ')')
497
+ // }
498
+ // }
481
499
482
500
if ( expectedIndent === Number . MAX_SAFE_INTEGER ) {
483
501
return
@@ -666,19 +684,18 @@ function create (context) {
666
684
} ,
667
685
668
686
ConditionalExpression ( node ) {
669
- const headToken = getChainHeadToken ( node )
687
+ const firstToken = template . getFirstToken ( node )
670
688
const questionToken = template . getTokenAfter ( node . test , isNotRightParen )
671
689
const consequentToken = template . getTokenAfter ( questionToken )
672
690
const colonToken = template . getTokenAfter ( node . consequent , isNotRightParen )
673
691
const alternateToken = template . getTokenAfter ( colonToken )
674
692
const isFlat = ( node . test . loc . end . line === node . consequent . loc . start . line )
675
693
676
694
if ( isFlat ) {
677
- setOffset ( [ questionToken , consequentToken , colonToken , alternateToken ] , 0 , headToken )
695
+ setOffset ( [ questionToken , consequentToken , colonToken , alternateToken ] , 0 , firstToken )
678
696
} else {
679
- setOffset ( [ questionToken , colonToken ] , 1 , headToken )
680
- setOffset ( consequentToken , 1 , questionToken )
681
- setOffset ( alternateToken , 1 , colonToken )
697
+ setOffset ( [ questionToken , colonToken ] , 1 , firstToken )
698
+ setOffset ( [ consequentToken , alternateToken ] , 1 , questionToken )
682
699
}
683
700
} ,
684
701
@@ -707,8 +724,8 @@ function create (context) {
707
724
708
725
setOffset ( leftParenToken , 1 , forToken )
709
726
setOffset ( leftToken , 1 , leftParenToken )
710
- setOffset ( inToken , 1 , leftParenToken )
711
- setOffset ( rightToken , 1 , inToken )
727
+ setOffset ( inToken , 1 , leftToken )
728
+ setOffset ( rightToken , 1 , leftToken )
712
729
setOffset ( rightParenToken , 0 , leftParenToken )
713
730
processMaybeBlock ( node . body , forToken )
714
731
} ,
@@ -733,7 +750,7 @@ function create (context) {
733
750
const bodyToken = template . getFirstToken ( node . body )
734
751
735
752
processNodeList ( node . params , leftToken , rightToken , 1 )
736
- setOffset ( bodyToken , 0 , firstToken )
753
+ setOffset ( bodyToken , 0 , template . getFirstToken ( node . parent ) )
737
754
} else {
738
755
// Normal functions.
739
756
const functionToken = node . async ? template . getTokenAfter ( firstToken ) : firstToken
@@ -744,15 +761,15 @@ function create (context) {
744
761
const bodyToken = template . getFirstToken ( node . body )
745
762
746
763
if ( node . async ) {
747
- setOffset ( functionToken , 1 , firstToken )
764
+ setOffset ( functionToken , 0 , firstToken )
748
765
}
749
766
if ( node . generator ) {
750
- setOffset ( starToken , 1 , functionToken )
767
+ setOffset ( starToken , 1 , firstToken )
751
768
}
752
769
if ( node . id != null ) {
753
- setOffset ( idToken , 1 , starToken || functionToken )
770
+ setOffset ( idToken , 1 , firstToken )
754
771
}
755
- setOffset ( leftToken , 1 , idToken || starToken || functionToken )
772
+ setOffset ( leftToken , 1 , firstToken )
756
773
processNodeList ( node . params , leftToken , rightToken , 1 )
757
774
setOffset ( bodyToken , 0 , firstToken )
758
775
}
@@ -797,8 +814,7 @@ function create (context) {
797
814
const dotToken = template . getTokenBefore ( node . property )
798
815
const propertyToken = template . getTokenAfter ( dotToken )
799
816
800
- setOffset ( dotToken , 1 , objectToken )
801
- setOffset ( propertyToken , 1 , dotToken )
817
+ setOffset ( [ dotToken , propertyToken ] , 1 , objectToken )
802
818
}
803
819
} ,
804
820
@@ -808,7 +824,7 @@ function create (context) {
808
824
const hasPrefix = prefixTokens . length >= 1
809
825
810
826
for ( let i = 1 ; i < prefixTokens . length ; ++ i ) {
811
- setOffset ( prefixTokens [ i ] , 1 , prefixTokens [ i - 1 ] )
827
+ setOffset ( prefixTokens [ i ] , 0 , prefixTokens [ i - 1 ] )
812
828
}
813
829
814
830
let lastKeyToken = null
@@ -818,15 +834,15 @@ function create (context) {
818
834
const keyRightToken = lastKeyToken = template . getTokenAfter ( node . key , isRightBracket )
819
835
820
836
if ( hasPrefix ) {
821
- setOffset ( keyLeftToken , 1 , last ( prefixTokens ) )
837
+ setOffset ( keyLeftToken , 0 , last ( prefixTokens ) )
822
838
}
823
839
setOffset ( keyToken , 1 , keyLeftToken )
824
840
setOffset ( keyRightToken , 0 , keyLeftToken )
825
841
} else {
826
842
const idToken = lastKeyToken = template . getFirstToken ( node . key )
827
843
828
844
if ( hasPrefix ) {
829
- setOffset ( idToken , 1 , last ( prefixTokens ) )
845
+ setOffset ( idToken , 0 , last ( prefixTokens ) )
830
846
}
831
847
}
832
848
@@ -838,8 +854,7 @@ function create (context) {
838
854
const colonToken = template . getTokenAfter ( lastKeyToken )
839
855
const valueToken = template . getTokenAfter ( colonToken )
840
856
841
- setOffset ( colonToken , 1 , lastKeyToken )
842
- setOffset ( valueToken , 1 , colonToken )
857
+ setOffset ( [ colonToken , valueToken ] , 1 , lastKeyToken )
843
858
}
844
859
} ,
845
860
@@ -1033,7 +1048,7 @@ function create (context) {
1033
1048
const indents = [ ]
1034
1049
let comments = [ ]
1035
1050
let tokensOnSameLine = [ ]
1036
- let shouldSkip = false
1051
+ let isBesideMultilineToken = false
1037
1052
1038
1053
// Set the base indent.
1039
1054
{
@@ -1042,25 +1057,29 @@ function create (context) {
1042
1057
setOffset ( firstToken , 0 , firstToken )
1043
1058
}
1044
1059
1045
- // Validate indentations of tokens.
1060
+ // Validate indentation of tokens.
1046
1061
for ( const token of template . getTokens ( node , { includeComments : true , filter : isNotWhitespace } ) ) {
1047
- if ( tokensOnSameLine . length === 0 || last ( tokensOnSameLine ) . loc . start . line === token . loc . start . line ) {
1062
+ if ( tokensOnSameLine . length === 0 || tokensOnSameLine [ 0 ] . loc . start . line === token . loc . start . line ) {
1063
+ // This is on the same line (or the first token).
1048
1064
tokensOnSameLine . push ( token )
1049
1065
} else if ( tokensOnSameLine . every ( isComment ) ) {
1066
+ // New line is detected, but the all tokens of the previous line are comment.
1067
+ // Comment lines are adjusted to the next code line.
1050
1068
comments . push ( tokensOnSameLine [ 0 ] )
1051
- shouldSkip = ( last ( tokensOnSameLine ) . loc . end . line === token . loc . start . line )
1069
+ isBesideMultilineToken = last ( tokensOnSameLine ) . loc . end . line === token . loc . start . line
1052
1070
tokensOnSameLine = [ token ]
1053
1071
} else {
1054
- if ( ! shouldSkip ) {
1072
+ // New line is detected, so validate the tokens.
1073
+ if ( ! isBesideMultilineToken ) {
1055
1074
validate ( tokensOnSameLine , comments , indents )
1056
1075
}
1057
- shouldSkip = ( last ( tokensOnSameLine ) . loc . end . line === token . loc . start . line )
1076
+ isBesideMultilineToken = last ( tokensOnSameLine ) . loc . end . line === token . loc . start . line
1058
1077
tokensOnSameLine = [ token ]
1059
1078
comments = [ ]
1060
1079
}
1061
1080
}
1062
1081
if ( tokensOnSameLine . length >= 1 && tokensOnSameLine . some ( isNotComment ) ) {
1063
- validate ( tokensOnSameLine , [ ] , indents )
1082
+ validate ( tokensOnSameLine , comments , indents )
1064
1083
}
1065
1084
}
1066
1085
} )
0 commit comments