apache / netbeans

Apache NetBeans
https://netbeans.apache.org/
Apache License 2.0
2.67k stars 855 forks source link

Warning about unused variable disappears when adding private nested record #4709

Open negora opened 2 years ago

negora commented 2 years ago

Apache NetBeans version

Apache NetBeans 15

What happened

I've a method whose body contains an unused variable. NetBeans reports about this issue right. However, if I add a private nested record to my class, then the warning disappears. By disappears I mean that is not detected as a proper warning anymore:

It's strange, because the unused variable is still underlined, but in gray color, not in yellow. And if you hover it with the mouse pointer, the IDE still shows the tip Variable X is not used.

Other odd fact: If you change the visibility of the record to public, protected or package-private, then the warning comes back.

How to reproduce

Use this so simple code to reproduce the problem:

public class MyClass {

    public void myMethod () {
        int x = 1;
        // ^^^ Unused variable.
    }

    private record MyRecord (String myField) {
    }

}

Did this work correctly in an earlier version?

No / Don't know

Operating System

Debian GNU/Linux 11.5 (Bullseye)

JDK

OpenJDK Runtime Environment (build 17.0.4+8-Debian-1deb11u1)

Apache NetBeans packaging

Apache NetBeans binary zip

Anything else

No response

Are you willing to submit a pull request?

No

Code of Conduct

Yes

mbien commented 2 years ago

I just checked and it is also reproducible in NB 14. So its not a recent regression.

negora commented 2 years ago

@mbien I just tried in NetBeans IDE 13, and it works OK. So whatever that causes this error appeared between versions 13 and 14. Thank you.

negora commented 2 years ago

@mbien I've found another case, similar to the previous one, in which the visibility of a class member affects the result of this type of check. However, this time it affects a method parameter instead of a local variable. Look at this:

public class Main {

    public Main() {
        checkParameter(1);
    }

    public static void checkParameter(int myParameter) {
                                    // ^^^ This variable should be marked as unused,
                                    // but it isn't.
    }

}

Now, if you change the visibility of the method from public to private, NetBeans correctly detects that myParameter is not used at all in the body of the method.

I've tested this in versions 13, 14 and 15 and this bug happens in all them (in contrast to the previous one, that is not reproducible in version 13).

I was tempted to open a separate issue, because I'm not sure that it's 100% related to the original issue. If you think that it deserves a separate one, please, let me know.

negora commented 9 months ago

Just a little update about the first case that I presented in this report. If I remove all the fields of the record and leave it empty, the warning appears again. Example:

public class MyClass {

    public void myMethod () {
        int x = 1;
        // ^^^ Unused variable.
    }

    private record MyRecord () {
                         // ^^^ Empty record.
    }

}

By the way, I've been testing the plug-in SonarLint for NetBeans and this issue seems not to affect it (it properly reports that the variable is unused). I know this result is obvious (it uses its own linter), but I say this just in case.

maffe commented 1 month ago

I've found another case, similar to the previous one, in which the visibility of a class member affects the result of this type of check. However, this time it affects a method parameter instead of a local variable. Look at this:

public class Main {

    public Main() {
        checkParameter(1);
    }

    public static void checkParameter(int myParameter) {
                                    // ^^^ This variable should be marked as unused,
                                    // but it isn't.
    }

}

Now, if you change the visibility of the method from public to private, NetBeans correctly detects that myParameter is not used at all in the body of the method.

I think it is intentional to not mark unused parameters in public methods since removing them would change your public API, breaking code using that method.