Coverage Report - com.puppycrawl.tools.checkstyle.checks.whitespace.EmptyLineSeparatorCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
EmptyLineSeparatorCheck
100%
132/132
100%
114/114
3.12
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 
 20  
 package com.puppycrawl.tools.checkstyle.checks.whitespace;
 21  
 
 22  
 import java.util.ArrayList;
 23  
 import java.util.List;
 24  
 
 25  
 import com.puppycrawl.tools.checkstyle.StatelessCheck;
 26  
 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
 27  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 28  
 import com.puppycrawl.tools.checkstyle.api.FileContents;
 29  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 30  
 import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
 31  
 import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
 32  
 
 33  
 /**
 34  
  * Checks for empty line separators after header, package, all import declarations,
 35  
  * fields, constructors, methods, nested classes,
 36  
  * static initializers and instance initializers.
 37  
  *
 38  
  * <p> By default the check will check the following statements:
 39  
  *  {@link TokenTypes#PACKAGE_DEF PACKAGE_DEF},
 40  
  *  {@link TokenTypes#IMPORT IMPORT},
 41  
  *  {@link TokenTypes#CLASS_DEF CLASS_DEF},
 42  
  *  {@link TokenTypes#INTERFACE_DEF INTERFACE_DEF},
 43  
  *  {@link TokenTypes#STATIC_INIT STATIC_INIT},
 44  
  *  {@link TokenTypes#INSTANCE_INIT INSTANCE_INIT},
 45  
  *  {@link TokenTypes#METHOD_DEF METHOD_DEF},
 46  
  *  {@link TokenTypes#CTOR_DEF CTOR_DEF},
 47  
  *  {@link TokenTypes#VARIABLE_DEF VARIABLE_DEF}.
 48  
  * </p>
 49  
  *
 50  
  * <p>
 51  
  * Example of declarations without empty line separator:
 52  
  * </p>
 53  
  *
 54  
  * <pre>
 55  
  * ///////////////////////////////////////////////////
 56  
  * //HEADER
 57  
  * ///////////////////////////////////////////////////
 58  
  * package com.puppycrawl.tools.checkstyle.whitespace;
 59  
  * import java.io.Serializable;
 60  
  * class Foo
 61  
  * {
 62  
  *     public static final int FOO_CONST = 1;
 63  
  *     public void foo() {} //should be separated from previous statement.
 64  
  * }
 65  
  * </pre>
 66  
  *
 67  
  * <p> An example of how to configure the check with default parameters is:
 68  
  * </p>
 69  
  *
 70  
  * <pre>
 71  
  * &lt;module name="EmptyLineSeparator"/&gt;
 72  
  * </pre>
 73  
  *
 74  
  * <p>
 75  
  * Example of declarations with empty line separator
 76  
  * that is expected by the Check by default:
 77  
  * </p>
 78  
  *
 79  
  * <pre>
 80  
  * ///////////////////////////////////////////////////
 81  
  * //HEADER
 82  
  * ///////////////////////////////////////////////////
 83  
  *
 84  
  * package com.puppycrawl.tools.checkstyle.whitespace;
 85  
  *
 86  
  * import java.io.Serializable;
 87  
  *
 88  
  * class Foo
 89  
  * {
 90  
  *     public static final int FOO_CONST = 1;
 91  
  *
 92  
  *     public void foo() {}
 93  
  * }
 94  
  * </pre>
 95  
  * <p> An example how to check empty line after
 96  
  * {@link TokenTypes#VARIABLE_DEF VARIABLE_DEF} and
 97  
  * {@link TokenTypes#METHOD_DEF METHOD_DEF}:
 98  
  * </p>
 99  
  *
 100  
  * <pre>
 101  
  * &lt;module name="EmptyLineSeparator"&gt;
 102  
  *    &lt;property name="tokens" value="VARIABLE_DEF, METHOD_DEF"/&gt;
 103  
  * &lt;/module&gt;
 104  
  * </pre>
 105  
  *
 106  
  * <p>
 107  
  * An example how to allow no empty line between fields:
 108  
  * </p>
 109  
  * <pre>
 110  
  * &lt;module name="EmptyLineSeparator"&gt;
 111  
  *    &lt;property name="allowNoEmptyLineBetweenFields" value="true"/&gt;
 112  
  * &lt;/module&gt;
 113  
  * </pre>
 114  
  *
 115  
  * <p>
 116  
  * Example of declarations with multiple empty lines between class members (allowed by default):
 117  
  * </p>
 118  
  *
 119  
  * <pre>
 120  
  * ///////////////////////////////////////////////////
 121  
  * //HEADER
 122  
  * ///////////////////////////////////////////////////
 123  
  *
 124  
  *
 125  
  * package com.puppycrawl.tools.checkstyle.whitespace;
 126  
  *
 127  
  *
 128  
  *
 129  
  * import java.io.Serializable;
 130  
  *
 131  
  *
 132  
  * class Foo
 133  
  * {
 134  
  *     public static final int FOO_CONST = 1;
 135  
  *
 136  
  *
 137  
  *
 138  
  *     public void foo() {}
 139  
  * }
 140  
  * </pre>
 141  
  * <p>
 142  
  * An example how to disallow multiple empty lines between class members:
 143  
  * </p>
 144  
  * <pre>
 145  
  * &lt;module name="EmptyLineSeparator"&gt;
 146  
  *    &lt;property name="allowMultipleEmptyLines" value="false"/&gt;
 147  
  * &lt;/module&gt;
 148  
  * </pre>
 149  
  *
 150  
  * <p>
 151  
  * An example how to disallow multiple empty line inside methods, constructors, etc.:
 152  
  * </p>
 153  
  * <pre>
 154  
  * &lt;module name="EmptyLineSeparator"&gt;
 155  
  *    &lt;property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/&gt;
 156  
  * &lt;/module&gt;
 157  
  * </pre>
 158  
  *
 159  
  * <p> The check is valid only for statements that have body:
 160  
  * {@link TokenTypes#CLASS_DEF},
 161  
  * {@link TokenTypes#INTERFACE_DEF},
 162  
  * {@link TokenTypes#ENUM_DEF},
 163  
  * {@link TokenTypes#STATIC_INIT},
 164  
  * {@link TokenTypes#INSTANCE_INIT},
 165  
  * {@link TokenTypes#METHOD_DEF},
 166  
  * {@link TokenTypes#CTOR_DEF}
 167  
  * </p>
 168  
  * <p>
 169  
  * Example of declarations with multiple empty lines inside method:
 170  
  * </p>
 171  
  *
 172  
  * <pre>
 173  
  * ///////////////////////////////////////////////////
 174  
  * //HEADER
 175  
  * ///////////////////////////////////////////////////
 176  
  *
 177  
  * package com.puppycrawl.tools.checkstyle.whitespace;
 178  
  *
 179  
  * class Foo
 180  
  * {
 181  
  *
 182  
  *     public void foo() {
 183  
  *
 184  
  *
 185  
  *          System.out.println(1); // violation since method has 2 empty lines subsequently
 186  
  *     }
 187  
  * }
 188  
  * </pre>
 189  
  * @author maxvetrenko
 190  
  * @author <a href="mailto:nesterenko-aleksey@list.ru">Aleksey Nesterenko</a>
 191  
  */
 192  
 @StatelessCheck
 193  40
 public class EmptyLineSeparatorCheck extends AbstractCheck {
 194  
 
 195  
     /**
 196  
      * A key is pointing to the warning message empty.line.separator in "messages.properties"
 197  
      * file.
 198  
      */
 199  
     public static final String MSG_SHOULD_BE_SEPARATED = "empty.line.separator";
 200  
 
 201  
     /**
 202  
      * A key is pointing to the warning message empty.line.separator.multiple.lines
 203  
      *  in "messages.properties"
 204  
      * file.
 205  
      */
 206  
     public static final String MSG_MULTIPLE_LINES = "empty.line.separator.multiple.lines";
 207  
 
 208  
     /**
 209  
      * A key is pointing to the warning message empty.line.separator.lines.after
 210  
      * in "messages.properties" file.
 211  
      */
 212  
     public static final String MSG_MULTIPLE_LINES_AFTER =
 213  
             "empty.line.separator.multiple.lines.after";
 214  
 
 215  
     /**
 216  
      * A key is pointing to the warning message empty.line.separator.multiple.lines.inside
 217  
      * in "messages.properties" file.
 218  
      */
 219  
     public static final String MSG_MULTIPLE_LINES_INSIDE =
 220  
             "empty.line.separator.multiple.lines.inside";
 221  
 
 222  
     /** Allows no empty line between fields. */
 223  
     private boolean allowNoEmptyLineBetweenFields;
 224  
 
 225  
     /** Allows multiple empty lines between class members. */
 226  40
     private boolean allowMultipleEmptyLines = true;
 227  
 
 228  
     /** Allows multiple empty lines inside class members. */
 229  40
     private boolean allowMultipleEmptyLinesInsideClassMembers = true;
 230  
 
 231  
     /**
 232  
      * Allow no empty line between fields.
 233  
      * @param allow
 234  
      *        User's value.
 235  
      */
 236  
     public final void setAllowNoEmptyLineBetweenFields(boolean allow) {
 237  4
         allowNoEmptyLineBetweenFields = allow;
 238  4
     }
 239  
 
 240  
     /**
 241  
      * Allow multiple empty lines between class members.
 242  
      * @param allow User's value.
 243  
      */
 244  
     public void setAllowMultipleEmptyLines(boolean allow) {
 245  6
         allowMultipleEmptyLines = allow;
 246  6
     }
 247  
 
 248  
     /**
 249  
      * Allow multiple empty lines inside class members.
 250  
      * @param allow User's value.
 251  
      */
 252  
     public void setAllowMultipleEmptyLinesInsideClassMembers(boolean allow) {
 253  3
         allowMultipleEmptyLinesInsideClassMembers = allow;
 254  3
     }
 255  
 
 256  
     @Override
 257  
     public boolean isCommentNodesRequired() {
 258  344
         return true;
 259  
     }
 260  
 
 261  
     @Override
 262  
     public int[] getDefaultTokens() {
 263  37
         return getAcceptableTokens();
 264  
     }
 265  
 
 266  
     @Override
 267  
     public int[] getAcceptableTokens() {
 268  45
         return new int[] {
 269  
             TokenTypes.PACKAGE_DEF,
 270  
             TokenTypes.IMPORT,
 271  
             TokenTypes.CLASS_DEF,
 272  
             TokenTypes.INTERFACE_DEF,
 273  
             TokenTypes.ENUM_DEF,
 274  
             TokenTypes.STATIC_INIT,
 275  
             TokenTypes.INSTANCE_INIT,
 276  
             TokenTypes.METHOD_DEF,
 277  
             TokenTypes.CTOR_DEF,
 278  
             TokenTypes.VARIABLE_DEF,
 279  
         };
 280  
     }
 281  
 
 282  
     @Override
 283  
     public int[] getRequiredTokens() {
 284  41
         return CommonUtils.EMPTY_INT_ARRAY;
 285  
     }
 286  
 
 287  
     @Override
 288  
     public void visitToken(DetailAST ast) {
 289  172
         if (hasMultipleLinesBefore(ast)) {
 290  7
             log(ast.getLineNo(), MSG_MULTIPLE_LINES, ast.getText());
 291  
         }
 292  172
         if (!allowMultipleEmptyLinesInsideClassMembers) {
 293  18
             processMultipleLinesInside(ast);
 294  
         }
 295  
 
 296  172
         DetailAST nextToken = ast.getNextSibling();
 297  188
         while (nextToken != null && isComment(nextToken)) {
 298  16
             nextToken = nextToken.getNextSibling();
 299  
         }
 300  172
         if (nextToken != null) {
 301  147
             final int astType = ast.getType();
 302  147
             switch (astType) {
 303  
                 case TokenTypes.VARIABLE_DEF:
 304  42
                     processVariableDef(ast, nextToken);
 305  42
                     break;
 306  
                 case TokenTypes.IMPORT:
 307  27
                     processImport(ast, nextToken, astType);
 308  27
                     break;
 309  
                 case TokenTypes.PACKAGE_DEF:
 310  24
                     processPackage(ast, nextToken);
 311  24
                     break;
 312  
                 default:
 313  54
                     if (nextToken.getType() == TokenTypes.RCURLY) {
 314  10
                         if (hasNotAllowedTwoEmptyLinesBefore(nextToken)) {
 315  1
                             log(ast.getLineNo(), MSG_MULTIPLE_LINES_AFTER, ast.getText());
 316  
                         }
 317  
                     }
 318  44
                     else if (!hasEmptyLineAfter(ast)) {
 319  22
                         log(nextToken.getLineNo(), MSG_SHOULD_BE_SEPARATED,
 320  11
                             nextToken.getText());
 321  
                     }
 322  
             }
 323  
         }
 324  172
     }
 325  
 
 326  
     /**
 327  
      * Log violation in case there are multiple empty lines inside constructor,
 328  
      * initialization block or method.
 329  
      * @param ast the ast to check.
 330  
      */
 331  
     private void processMultipleLinesInside(DetailAST ast) {
 332  18
         final int astType = ast.getType();
 333  18
         if (astType != TokenTypes.CLASS_DEF && isClassMemberBlock(astType)) {
 334  10
             final List<Integer> emptyLines = getEmptyLines(ast);
 335  10
             final List<Integer> emptyLinesToLog = getEmptyLinesToLog(emptyLines);
 336  
 
 337  10
             for (Integer lineNo : emptyLinesToLog) {
 338  
                 // Checkstyle counts line numbers from 0 but IDE from 1
 339  10
                 log(lineNo + 1, MSG_MULTIPLE_LINES_INSIDE);
 340  10
             }
 341  
         }
 342  18
     }
 343  
 
 344  
     /**
 345  
      * Whether the AST is a class member block.
 346  
      * @param astType the AST to check.
 347  
      * @return true if the AST is a class member block.
 348  
      */
 349  
     private static boolean isClassMemberBlock(int astType) {
 350  16
         return astType == TokenTypes.STATIC_INIT
 351  
                 || astType == TokenTypes.INSTANCE_INIT
 352  
                 || astType == TokenTypes.METHOD_DEF
 353  
                 || astType == TokenTypes.CTOR_DEF;
 354  
     }
 355  
 
 356  
     /**
 357  
      * Get list of empty lines.
 358  
      * @param ast the ast to check.
 359  
      * @return list of line numbers for empty lines.
 360  
      */
 361  
     private List<Integer> getEmptyLines(DetailAST ast) {
 362  10
         final DetailAST lastToken = ast.getLastChild().getLastChild();
 363  10
         int lastTokenLineNo = 0;
 364  10
         if (lastToken != null) {
 365  
             // -1 as count starts from 0
 366  
             // -2 as last token line cannot be empty, because it is a RCURLY
 367  9
             lastTokenLineNo = lastToken.getLineNo() - 2;
 368  
         }
 369  10
         final List<Integer> emptyLines = new ArrayList<>();
 370  10
         final FileContents fileContents = getFileContents();
 371  
 
 372  40
         for (int lineNo = ast.getLineNo(); lineNo <= lastTokenLineNo; lineNo++) {
 373  30
             if (fileContents.lineIsBlank(lineNo)) {
 374  20
                 emptyLines.add(lineNo);
 375  
             }
 376  
         }
 377  10
         return emptyLines;
 378  
     }
 379  
 
 380  
     /**
 381  
      * Get list of empty lines to log.
 382  
      * @param emptyLines list of empty lines.
 383  
      * @return list of empty lines to log.
 384  
      */
 385  
     private static List<Integer> getEmptyLinesToLog(List<Integer> emptyLines) {
 386  10
         final List<Integer> emptyLinesToLog = new ArrayList<>();
 387  10
         if (emptyLines.size() >= 2) {
 388  8
             int previousEmptyLineNo = emptyLines.get(0);
 389  8
             for (int emptyLineNo : emptyLines) {
 390  20
                 if (previousEmptyLineNo + 1 == emptyLineNo) {
 391  10
                     emptyLinesToLog.add(emptyLineNo);
 392  
                 }
 393  20
                 previousEmptyLineNo = emptyLineNo;
 394  20
             }
 395  
         }
 396  10
         return emptyLinesToLog;
 397  
     }
 398  
 
 399  
     /**
 400  
      * Whether the token has not allowed multiple empty lines before.
 401  
      * @param ast the ast to check.
 402  
      * @return true if the token has not allowed multiple empty lines before.
 403  
      */
 404  
     private boolean hasMultipleLinesBefore(DetailAST ast) {
 405  172
         boolean result = false;
 406  172
         if ((ast.getType() != TokenTypes.VARIABLE_DEF
 407  42
             || isTypeField(ast))
 408  164
                 && hasNotAllowedTwoEmptyLinesBefore(ast)) {
 409  7
             result = true;
 410  
         }
 411  172
         return result;
 412  
     }
 413  
 
 414  
     /**
 415  
      * Process Package.
 416  
      * @param ast token
 417  
      * @param nextToken next token
 418  
      */
 419  
     private void processPackage(DetailAST ast, DetailAST nextToken) {
 420  24
         if (ast.getLineNo() > 1 && !hasEmptyLineBefore(ast)) {
 421  5
             if (getFileContents().getFileName().endsWith("package-info.java")) {
 422  4
                 if (ast.getFirstChild().getChildCount() == 0 && !isPrecededByJavadoc(ast)) {
 423  2
                     log(ast.getLineNo(), MSG_SHOULD_BE_SEPARATED, ast.getText());
 424  
                 }
 425  
             }
 426  
             else {
 427  1
                 log(ast.getLineNo(), MSG_SHOULD_BE_SEPARATED, ast.getText());
 428  
             }
 429  
         }
 430  24
         if (!hasEmptyLineAfter(ast)) {
 431  4
             log(nextToken.getLineNo(), MSG_SHOULD_BE_SEPARATED, nextToken.getText());
 432  
         }
 433  24
     }
 434  
 
 435  
     /**
 436  
      * Process Import.
 437  
      * @param ast token
 438  
      * @param nextToken next token
 439  
      * @param astType token Type
 440  
      */
 441  
     private void processImport(DetailAST ast, DetailAST nextToken, int astType) {
 442  27
         if (astType != nextToken.getType() && !hasEmptyLineAfter(ast)) {
 443  2
             log(nextToken.getLineNo(), MSG_SHOULD_BE_SEPARATED, nextToken.getText());
 444  
         }
 445  27
     }
 446  
 
 447  
     /**
 448  
      * Process Variable.
 449  
      * @param ast token
 450  
      * @param nextToken next Token
 451  
      */
 452  
     private void processVariableDef(DetailAST ast, DetailAST nextToken) {
 453  42
         if (isTypeField(ast) && !hasEmptyLineAfter(ast)
 454  18
                 && isViolatingEmptyLineBetweenFieldsPolicy(nextToken)) {
 455  8
             log(nextToken.getLineNo(), MSG_SHOULD_BE_SEPARATED,
 456  4
                     nextToken.getText());
 457  
         }
 458  42
     }
 459  
 
 460  
     /**
 461  
      * Checks whether token placement violates policy of empty line between fields.
 462  
      * @param detailAST token to be analyzed
 463  
      * @return true if policy is violated and warning should be raised; false otherwise
 464  
      */
 465  
     private boolean isViolatingEmptyLineBetweenFieldsPolicy(DetailAST detailAST) {
 466  36
         return allowNoEmptyLineBetweenFields
 467  6
                     && detailAST.getType() != TokenTypes.VARIABLE_DEF
 468  4
                     && detailAST.getType() != TokenTypes.RCURLY
 469  
                 || !allowNoEmptyLineBetweenFields
 470  12
                     && detailAST.getType() != TokenTypes.RCURLY;
 471  
     }
 472  
 
 473  
     /**
 474  
      * Checks if a token has empty two previous lines and multiple empty lines is not allowed.
 475  
      * @param token DetailAST token
 476  
      * @return true, if token has empty two lines before and allowMultipleEmptyLines is false
 477  
      */
 478  
     private boolean hasNotAllowedTwoEmptyLinesBefore(DetailAST token) {
 479  348
         return !allowMultipleEmptyLines && hasEmptyLineBefore(token)
 480  18
                 && isPrePreviousLineEmpty(token);
 481  
     }
 482  
 
 483  
     /**
 484  
      * Checks if a token has empty pre-previous line.
 485  
      * @param token DetailAST token.
 486  
      * @return true, if token has empty lines before.
 487  
      */
 488  
     private boolean isPrePreviousLineEmpty(DetailAST token) {
 489  18
         boolean result = false;
 490  18
         final int lineNo = token.getLineNo();
 491  
         // 3 is the number of the pre-previous line because the numbering starts from zero.
 492  18
         final int number = 3;
 493  18
         if (lineNo >= number) {
 494  17
             final String prePreviousLine = getLines()[lineNo - number];
 495  17
             result = CommonUtils.isBlank(prePreviousLine);
 496  
         }
 497  18
         return result;
 498  
     }
 499  
 
 500  
     /**
 501  
      * Checks if token have empty line after.
 502  
      * @param token token.
 503  
      * @return true if token have empty line after.
 504  
      */
 505  
     private boolean hasEmptyLineAfter(DetailAST token) {
 506  106
         DetailAST lastToken = token.getLastChild().getLastChild();
 507  106
         if (lastToken == null) {
 508  64
             lastToken = token.getLastChild();
 509  
         }
 510  106
         DetailAST nextToken = token.getNextSibling();
 511  106
         if (isComment(nextToken)) {
 512  5
             nextToken = nextToken.getNextSibling();
 513  
         }
 514  
         // Start of the next token
 515  106
         final int nextBegin = nextToken.getLineNo();
 516  
         // End of current token.
 517  106
         final int currentEnd = lastToken.getLineNo();
 518  106
         return hasEmptyLine(currentEnd + 1, nextBegin - 1);
 519  
     }
 520  
 
 521  
     /**
 522  
      * Checks, whether there are empty lines within the specified line range. Line numbering is
 523  
      * started from 1 for parameter values
 524  
      * @param startLine number of the first line in the range
 525  
      * @param endLine number of the second line in the range
 526  
      * @return {@code true} if found any blank line within the range, {@code false}
 527  
      *         otherwise
 528  
      */
 529  
     private boolean hasEmptyLine(int startLine, int endLine) {
 530  
         // Initial value is false - blank line not found
 531  106
         boolean result = false;
 532  106
         if (startLine <= endLine) {
 533  80
             final FileContents fileContents = getFileContents();
 534  121
             for (int line = startLine; line <= endLine; line++) {
 535  
                 // Check, if the line is blank. Lines are numbered from 0, so subtract 1
 536  112
                 if (fileContents.lineIsBlank(line - 1)) {
 537  71
                     result = true;
 538  71
                     break;
 539  
                 }
 540  
             }
 541  
         }
 542  106
         return result;
 543  
     }
 544  
 
 545  
     /**
 546  
      * Checks if a token has a empty line before.
 547  
      * @param token token.
 548  
      * @return true, if token have empty line before.
 549  
      */
 550  
     private boolean hasEmptyLineBefore(DetailAST token) {
 551  37
         boolean result = false;
 552  37
         final int lineNo = token.getLineNo();
 553  37
         if (lineNo != 1) {
 554  
             // [lineNo - 2] is the number of the previous line as the numbering starts from zero.
 555  33
             final String lineBefore = getLines()[lineNo - 2];
 556  33
             result = CommonUtils.isBlank(lineBefore);
 557  
         }
 558  37
         return result;
 559  
     }
 560  
 
 561  
     /**
 562  
      * Check if token is preceded by javadoc comment.
 563  
      * @param token token for check.
 564  
      * @return true, if token is preceded by javadoc comment.
 565  
      */
 566  
     private static boolean isPrecededByJavadoc(DetailAST token) {
 567  3
         boolean result = false;
 568  3
         final DetailAST previous = token.getPreviousSibling();
 569  3
         if (previous.getType() == TokenTypes.BLOCK_COMMENT_BEGIN
 570  2
                 && JavadocUtils.isJavadocComment(previous.getFirstChild().getText())) {
 571  1
             result = true;
 572  
         }
 573  3
         return result;
 574  
     }
 575  
 
 576  
     /**
 577  
      * Check if token is a comment.
 578  
      * @param ast ast node
 579  
      * @return true, if given ast is comment.
 580  
      */
 581  
     private static boolean isComment(DetailAST ast) {
 582  538
         return ast.getType() == TokenTypes.SINGLE_LINE_COMMENT
 583  254
                    || ast.getType() == TokenTypes.BLOCK_COMMENT_BEGIN;
 584  
     }
 585  
 
 586  
     /**
 587  
      * If variable definition is a type field.
 588  
      * @param variableDef variable definition.
 589  
      * @return true variable definition is a type field.
 590  
      */
 591  
     private static boolean isTypeField(DetailAST variableDef) {
 592  84
         final int parentType = variableDef.getParent().getParent().getType();
 593  84
         return parentType == TokenTypes.CLASS_DEF;
 594  
     }
 595  
 }