@@ -54,62 +54,45 @@ module.exports = {
5454 const sourceCode = context . getSourceCode ( ) ;
5555
5656 /**
57- * Checks if there is padding between two tokens
58- * @param {Token } first The first token
59- * @param {Token } second The second token
60- * @returns {boolean } True if there is at least a line between the tokens
57+ * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member.
58+ * @param {Token } prevLastToken The last token in the previous member node.
59+ * @param {Token } nextFirstToken The first token in the next member node.
60+ * @param {number } maxLine The maximum number of allowed line difference between consecutive tokens.
61+ * @returns {Token } The last token among the consecutive tokens.
6162 */
62- function isPaddingBetweenTokens ( first , second ) {
63- const comments = sourceCode . getCommentsBefore ( second ) ;
64- const len = comments . length ;
63+ function findLastConsecutiveTokenAfter ( prevLastToken , nextFirstToken , maxLine ) {
64+ const after = sourceCode . getTokenAfter ( prevLastToken , { includeComments : true } ) ;
6565
66- // If there is no comments
67- if ( len === 0 ) {
68- const linesBetweenFstAndSnd = second . loc . start . line - first . loc . end . line - 1 ;
69-
70- return linesBetweenFstAndSnd >= 1 ;
71- }
72-
73-
74- // If there are comments
75- let sumOfCommentLines = 0 ; // the numbers of lines of comments
76- let prevCommentLineNum = - 1 ; // line number of the end of the previous comment
77-
78- for ( let i = 0 ; i < len ; i ++ ) {
79- const commentLinesOfThisComment = comments [ i ] . loc . end . line - comments [ i ] . loc . start . line + 1 ;
80-
81- sumOfCommentLines += commentLinesOfThisComment ;
82-
83- /*
84- * If this comment and the previous comment are in the same line,
85- * the count of comment lines is duplicated. So decrement sumOfCommentLines.
86- */
87- if ( prevCommentLineNum === comments [ i ] . loc . start . line ) {
88- sumOfCommentLines -= 1 ;
89- }
90-
91- prevCommentLineNum = comments [ i ] . loc . end . line ;
66+ if ( after !== nextFirstToken && after . loc . start . line - prevLastToken . loc . end . line <= maxLine ) {
67+ return findLastConsecutiveTokenAfter ( after , nextFirstToken , maxLine ) ;
9268 }
69+ return prevLastToken ;
70+ }
9371
94- /*
95- * If the first block and the first comment are in the same line,
96- * the count of comment lines is duplicated. So decrement sumOfCommentLines.
97- */
98- if ( first . loc . end . line === comments [ 0 ] . loc . start . line ) {
99- sumOfCommentLines -= 1 ;
100- }
72+ /**
73+ * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member.
74+ * @param {Token } nextFirstToken The first token in the next member node.
75+ * @param {Token } prevLastToken The last token in the previous member node.
76+ * @param {number } maxLine The maximum number of allowed line difference between consecutive tokens.
77+ * @returns {Token } The first token among the consecutive tokens.
78+ */
79+ function findFirstConsecutiveTokenBefore ( nextFirstToken , prevLastToken , maxLine ) {
80+ const before = sourceCode . getTokenBefore ( nextFirstToken , { includeComments : true } ) ;
10181
102- /*
103- * If the last comment and the second block are in the same line,
104- * the count of comment lines is duplicated. So decrement sumOfCommentLines.
105- */
106- if ( comments [ len - 1 ] . loc . end . line === second . loc . start . line ) {
107- sumOfCommentLines -= 1 ;
82+ if ( before !== prevLastToken && nextFirstToken . loc . start . line - before . loc . end . line <= maxLine ) {
83+ return findFirstConsecutiveTokenBefore ( before , prevLastToken , maxLine ) ;
10884 }
85+ return nextFirstToken ;
86+ }
10987
110- const linesBetweenFstAndSnd = second . loc . start . line - first . loc . end . line - 1 ;
111-
112- return linesBetweenFstAndSnd - sumOfCommentLines >= 1 ;
88+ /**
89+ * Checks if there is a token or comment between two tokens.
90+ * @param {Token } before The token before.
91+ * @param {Token } after The token after.
92+ * @returns {boolean } True if there is a token or comment between two tokens.
93+ */
94+ function hasTokenOrCommentBetween ( before , after ) {
95+ return sourceCode . getTokensBetween ( before , after , { includeComments : true } ) . length !== 0 ;
11396 }
11497
11598 return {
@@ -120,20 +103,26 @@ module.exports = {
120103 const curFirst = sourceCode . getFirstToken ( body [ i ] ) ;
121104 const curLast = sourceCode . getLastToken ( body [ i ] ) ;
122105 const nextFirst = sourceCode . getFirstToken ( body [ i + 1 ] ) ;
123- const isPadded = isPaddingBetweenTokens ( curLast , nextFirst ) ;
124106 const isMulti = ! astUtils . isTokenOnSameLine ( curFirst , curLast ) ;
125107 const skip = ! isMulti && options [ 1 ] . exceptAfterSingleLine ;
126-
108+ const beforePadding = findLastConsecutiveTokenAfter ( curLast , nextFirst , 1 ) ;
109+ const afterPadding = findFirstConsecutiveTokenBefore ( nextFirst , curLast , 1 ) ;
110+ const isPadded = afterPadding . loc . start . line - beforePadding . loc . end . line > 1 ;
111+ const hasTokenInPadding = hasTokenOrCommentBetween ( beforePadding , afterPadding ) ;
112+ const curLineLastToken = findLastConsecutiveTokenAfter ( curLast , nextFirst , 0 ) ;
127113
128114 if ( ( options [ 0 ] === "always" && ! skip && ! isPadded ) ||
129115 ( options [ 0 ] === "never" && isPadded ) ) {
130116 context . report ( {
131117 node : body [ i + 1 ] ,
132118 messageId : isPadded ? "never" : "always" ,
133119 fix ( fixer ) {
120+ if ( hasTokenInPadding ) {
121+ return null ;
122+ }
134123 return isPadded
135- ? fixer . replaceTextRange ( [ curLast . range [ 1 ] , nextFirst . range [ 0 ] ] , "\n" )
136- : fixer . insertTextAfter ( curLast , "\n" ) ;
124+ ? fixer . replaceTextRange ( [ beforePadding . range [ 1 ] , afterPadding . range [ 0 ] ] , "\n" )
125+ : fixer . insertTextAfter ( curLineLastToken , "\n" ) ;
137126 }
138127 } ) ;
139128 }
0 commit comments