Skip to content

False positive: EmptyLineSeparator report wrong violation in the case of anonymous class #18858

@Praveen7294

Description

@Praveen7294

detected at #18545 (comment)

I have read check documentation: https://checkstyle.org/checks/whitespace/emptylineseparator.html#EmptyLineSeparator
I have downloaded the latest checkstyle from: https://checkstyle.org/cmdline.html#Download_and_Run
I have executed the cli and showed it below, as cli describes the problem better than 1,000 words

EmptyLineSeparatorCheck reports wrong violation or two violation pointing to same line in the case of anonymous class.

Config:

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
   "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">

<module name="Checker">
  <module name="TreeWalker">
    <module name="EmptyLineSeparator">
      <property name="tokens"
               value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                    STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
                    COMPACT_CTOR_DEF"/>
      <property name="allowNoEmptyLineBetweenFields" value="true"/>
      <property name="allowMultipleEmptyLines" value="false"/>
      <property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
    </module>
  </module>
</module>

Taking three input example with anonymous class for better understanding:

Case 1:

Anonymous class with mutiple chained method call

Test.java

import java.util.Stack;

public class Test {

    public static void foo1() {
        Stack<Integer> stack = new Stack<>();
        stack.push(5);
 	    new EarlyTerminatingScanner() {
             @Override
             protected void visit(Object role, Object element) {
                 // violation 'There is more than 1 empty line after this line.'
             }       // line  12


 	    }
 	    .setEnabled(true)
 	    .scan("ROLE", new Object());     // line 17
    }

    static abstract class EarlyTerminatingScanner {

        private boolean enabled;

        public EarlyTerminatingScanner setEnabled(boolean value) {
            enabled = value;
            return this;
        }

        public void scan(Object role, Object element) {
            if (enabled) {
                visit(role, element);
            }
        }

        protected abstract void visit(Object role, Object element);
    }
}

cli:

$ java -jar checkstyle-13.1.0-all.jar -c config_check.xml Test.java
Starting audit...
[ERROR] F:\GitHub\headhtmltagname\Test.java:12:14: '}' has more than 1 empty lines after. [EmptyLineSeparator]
[ERROR] F:\GitHub\headhtmltagname\Test.java:17:13: There is more than 1 empty line after this line. [EmptyLineSeparator]
Audit done.
Checkstyle ends with 2 errors.

Case 2:

Anonymous class with single chained method call

Test.java

import java.util.Stack;

public class Test {

    public static void foo1() {
        Stack<Integer> stack = new Stack<>();
        stack.push(5);
 	    new EarlyTerminatingScanner() {
             @Override
             protected void visit(Object role, Object element) {
                 // violation 'There is more than 1 empty line after this line.'
             }      // line 12


 	    }
 	    .setEnabled(true);
    }

    static abstract class EarlyTerminatingScanner {

        private boolean enabled;

        public EarlyTerminatingScanner setEnabled(boolean value) {
            enabled = value;
            return this;
        }

        protected abstract void visit(Object role, Object element);
    }
}

cli:

$ java -jar checkstyle-13.1.0-all.jar -c config_check.xml Test.java
Starting audit...
[ERROR] F:\GitHub\headhtmltagname\Test.java:12:14: '}' has more than 1 empty lines after. [EmptyLineSeparator]
[ERROR] F:\GitHub\headhtmltagname\Test.java:12:14: There is more than 1 empty line after this line. [EmptyLineSeparator]
Audit done.
Checkstyle ends with 2 errors.

Case 3:

Only anonymous class, no chained method calls

Test.java

import java.util.Stack;

public class Test {

    public static void foo1() {
        Stack<Integer> stack = new Stack<>();
        stack.push(5);
 	    new EarlyTerminatingScanner() {
             @Override
             protected void visit(Object role, Object element) {
                 // violation 'There is more than 1 empty line after this line.'
             }      // line 12


 	    };
    }

    static abstract class EarlyTerminatingScanner {

        protected abstract void visit(Object role, Object element);
    }
}

cli:

$ java -jar checkstyle-13.1.0-all.jar -c config_check.xml Test.java
Starting audit...
[ERROR] F:\GitHub\headhtmltagname\Test.java:12:14: '}' has more than 1 empty lines after. [EmptyLineSeparator]
[ERROR] F:\GitHub\headhtmltagname\Test.java:12:14: There is more than 1 empty line after this line. [EmptyLineSeparator]
Audit done.
Checkstyle ends with 2 errors.

EmptyLineSeparatorCheck report wrong violation on case 1 and two violation pointing to the same line in case 2 & case 3. In my opinion, EmptyLineSeparatorCheck with <property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/> have no handling case of anonymous class.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions