32
32
import com .puppycrawl .tools .checkstyle .api .AbstractCheck ;
33
33
import com .puppycrawl .tools .checkstyle .api .DetailAST ;
34
34
import com .puppycrawl .tools .checkstyle .api .TokenTypes ;
35
+ import java .util .Comparator ;
35
36
import java .util .regex .Pattern ;
37
+ import java .util .stream .StreamSupport ;
36
38
37
39
/**
38
40
* Check for empty lines inside methods and constructors.
@@ -86,6 +88,7 @@ public int[] getRequiredTokens() {
86
88
87
89
@ Override
88
90
public void visitToken (final DetailAST ast ) {
91
+ this .getLine (ast .getLastChild ().getLine ());
89
92
if (ast .getType () == TokenTypes .OBJBLOCK
90
93
&& ast .getParent () != null
91
94
&& ast .getParent ().getType () == TokenTypes .LITERAL_NEW ) {
@@ -114,8 +117,8 @@ public void finishTree(final DetailAST root) {
114
117
final String [] lines = this .getLines ();
115
118
for (int line = 0 ; line < lines .length ; ++line ) {
116
119
if (this .methods .inRange (line + 1 )
117
- && this . validInnerClassMethod ( line + 1 )
118
- && EmptyLinesCheck . PATTERN . matcher ( lines [ line ]). find ( )) {
120
+ && EmptyLinesCheck . PATTERN . matcher ( lines [ line ]). find ( )
121
+ && this . insideMethod ( line + 1 )) {
119
122
this .log (line + 1 , "Empty line inside method" );
120
123
}
121
124
}
@@ -132,8 +135,29 @@ public void finishTree(final DetailAST root) {
132
135
* @param line The line to check if it is within a method or not.
133
136
* @return True if the line is directly inside of a method.
134
137
*/
135
- private boolean validInnerClassMethod (final int line ) {
136
- return !this .anons .inRange (line )
137
- || this .methods .within (this .anons ).inRange (line );
138
+ private boolean insideMethod (final int line ) {
139
+ final int method = EmptyLinesCheck .linesBetweenBraces (
140
+ line , this .methods ::iterator , Integer .MIN_VALUE
141
+ );
142
+ final int clazz = EmptyLinesCheck .linesBetweenBraces (
143
+ line , this .anons ::iterator , Integer .MAX_VALUE
144
+ );
145
+ return method < clazz ;
146
+ }
147
+
148
+ /**
149
+ * Find number of lines between braces that contain a given line.
150
+ * @param line Line to check
151
+ * @param iterator Iterable of line ranges
152
+ * @param def Default value if line is not within ranges
153
+ * @return Number of lines between braces
154
+ */
155
+ private static int linesBetweenBraces (final int line ,
156
+ final Iterable <LineRange > iterator , final int def ) {
157
+ return StreamSupport .stream (iterator .spliterator (), false )
158
+ .filter (r -> r .within (line ))
159
+ .min (Comparator .comparingInt (r -> r .last () - r .first ()))
160
+ .map (r -> r .last () - r .first ())
161
+ .orElse (def );
138
162
}
139
163
}
0 commit comments