ucr-riple / NullAwayAnnotator

A tool to help adapting code bases to NullAway type system.
MIT License
13 stars 6 forks source link

`Could not find class of type: Top-Level` for a record #228

Closed boris-petrov closed 6 months ago

boris-petrov commented 6 months ago

Describe the bug

Could not find class of type: Top-Level with name: Pair on Cursor:
package com.company.util;

public record Pair<F, S>(F first, S second) {

    @Override
    public String toString() {
        return "[" + first + ',' + second + ']';
    }
}

That's the error I get when running NullAwayAnnotator on my project. After that there is a NPE:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.github.javaparser.ast.NodeList.forEach(java.util.function.Consumer)" because "members" is null
        at edu.ucr.cs.riple.core.registries.field.FieldRegistry.lambda$getBuilder$4(FieldRegistry.java:112)
        at edu.ucr.cs.riple.core.registries.Registry.populateContent(Registry.java:117)
        at edu.ucr.cs.riple.core.registries.Registry.lambda$new$0(Registry.java:86)
        at java.base/java.lang.Iterable.forEach(Iterable.java:75)
        at edu.ucr.cs.riple.core.registries.Registry.<init>(Registry.java:83)
        at edu.ucr.cs.riple.core.registries.field.FieldRegistry.<init>(FieldRegistry.java:81)
        at edu.ucr.cs.riple.core.module.ModuleInfo.<init>(ModuleInfo.java:91)
        at edu.ucr.cs.riple.core.module.ModuleInfo.<init>(ModuleInfo.java:73)
        at edu.ucr.cs.riple.core.Context.<init>(Context.java:78)
        at edu.ucr.cs.riple.core.Annotator.<init>(Annotator.java:63)
        at edu.ucr.cs.riple.core.Main.main(Main.java:45)

To Reproduce The code above.

Expected behavior The record Pair to be found.

Stack trace See above.

OS (please complete the following information):

Additional context I'm not sure I'm not doing something wrong. For example, I'm not sure what the -i argument that I had to specify when running the java command is supposed to be. I just used com.company.Initializer. I don't think that's the culprit here but who knows?

nimakarimipour commented 6 months ago

Hi @boris-petrov, thank you very much for reporting this issue. This issue has been resolved within #226 which is on version 1.3.13-SNAPSHOT. We will make a release tonight and using the new version, should fix the problem you are encountering. If the issue still persists after the upgrade, please let us know and we will try to fix it ASAP.

Regarding -i argument, Annotator is able to infer @Initializer methods (for more details, please see @Initializer on NullAway's wiki). NullAway will acknowledge any annotation ending with a name Initializer on a method as an initializer annotation.

When a method is inferred to be an @Initializer method, Annotator will add the annotation (given as argument of i flag) on the detected method. In your case, it will add changes below:

+import com.company.Initializer
+@Initializer
public init(){....}

Please note that com.company.Initializer must exist on the class path before the inference start. We recommend using the annotation provided with NullAway as below:

compileOnly 'com.uber.nullaway:nullaway-annotations:0.10.10'

and passing -i com.uber.nullaway.annotations.Initializer , however, as long as the annotation is present in the classpath (and its name ends with 'Initializer'), you can select any other annotations you prefer.

If there was anything , please let me know.

Best,

Nima

boris-petrov commented 6 months ago

@nimakarimipour thanks for the time and the detailed explanation!

I saw this PR and the fix but I thought it was handling some specific case with records (as I saw in previous commits that they were supposed to generally work). I'll await the release and will let you know if there is anything else, thanks! :)

As for the @Initializer - now it makes sense, thanks! You might want to mention the same things you said here in the README so other people who aren't familiar with NullAway can also understand the point of that argument.

I'll close this issue, thanks for the time!