ballerina-platform / ballerina-lang

The Ballerina Programming Language
https://ballerina.io/
Apache License 2.0
3.66k stars 750 forks source link

[Bug]: Getting NPE when passing an instance method to an annotation #41038

Open MohamedSabthar opened 1 year ago

MohamedSabthar commented 1 year ago

Description

Following code results in a bad sad error:

import ballerina/io;
public type ResourceConfigRec record {|
    function prefetch;
|};

# The annotation to configure the load method with batch functions.
public annotation ResourceConfigRec ResourceConfig on object function;

isolated distinct service class Author {

    @ResourceConfig {
        prefetch: self.prefetchBooks
    }
    isolated resource function get books() returns string {
        return "";
    }

    public function prefetchBooks() {
        io:println("Prefetching books");
    }
}

Getting the following:

ballerina: Oh no, something really went wrong. Bad. Sad.

We appreciate it if you can report the code that broke Ballerina in
https://github.com/ballerina-platform/ballerina-lang/issues with the
log you get below and your sample code.

We thank you for helping make us better.

[2023-07-18 09:50:52,173] SEVERE {b7a.log.crash} - null 
java.lang.NullPointerException
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:159)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRBasicBlock.accept(BIRNode.java:467)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.lambda$visit$3(BIROptimizer.java:121)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:121)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRFunction.accept(BIRNode.java:425)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.lambda$visit$1(BIROptimizer.java:107)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer$RHSTempVarOptimizer.visit(BIROptimizer.java:107)
        at org.wso2.ballerinalang.compiler.bir.model.BIRNode$BIRPackage.accept(BIRNode.java:89)
        at org.wso2.ballerinalang.compiler.bir.optimizer.BIROptimizer.optimizePackage(BIROptimizer.java:83)
        at org.wso2.ballerinalang.compiler.bir.BIRGen.genBIR(BIRGen.java:286)
        at io.ballerina.projects.internal.CompilerPhaseRunner.birGen(CompilerPhaseRunner.java:220)
        at io.ballerina.projects.internal.CompilerPhaseRunner.performBirGenPhases(CompilerPhaseRunner.java:157)
        at io.ballerina.projects.ModuleContext.generateCodeInternal(ModuleContext.java:451)
        at io.ballerina.projects.ModuleCompilationState$4.generatePlatformSpecificCode(ModuleCompilationState.java:132)
        at io.ballerina.projects.ModuleContext.generatePlatformSpecificCode(ModuleContext.java:385)
        at io.ballerina.projects.JBallerinaBackend.performCodeGen(JBallerinaBackend.java:170)
        at io.ballerina.projects.JBallerinaBackend.<init>(JBallerinaBackend.java:139)
        at io.ballerina.projects.JBallerinaBackend.lambda$from$0(JBallerinaBackend.java:117)
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1134)
        at io.ballerina.projects.PackageCompilation.getCompilerBackend(PackageCompilation.java:170)
        at io.ballerina.projects.JBallerinaBackend.from(JBallerinaBackend.java:116)
        at io.ballerina.cli.task.CompileTask.execute(CompileTask.java:165)
        at io.ballerina.cli.TaskExecutor.executeTasks(TaskExecutor.java:40)
        at io.ballerina.cli.cmd.RunCommand.execute(RunCommand.java:221)
        at java.base/java.util.Optional.ifPresent(Optional.java:183)
        at io.ballerina.cli.launcher.Main.main(Main.java:51)

ERROR [.:(1:1,1:1)] Compilation failed due to an unhandled exception
error: compilation contains errors

No response

Affected Version(s)

Tested with 2201.4.0 and 2201.6.0

OS, DB, other environment details and versions

No response

Related area

-> Compilation

Related issue(s) (optional)

No response

Suggested label(s) (optional)

No response

Suggested assignee(s) (optional)

No response

MohamedSabthar commented 1 year ago

This is a blocker for https://github.com/ballerina-platform/ballerina-standard-library/issues/4569#issuecomment-1637919661

warunalakshitha commented 1 year ago

It seems bir operand is null where it shouldn't be. This normally happens due to a issue in compiler frond phase.

MaryamZi commented 1 year ago

I'm not sure if this is valid code. Should probably have resulted in a compile-time error.

The annotation is on the object method and "An annotation occurring within a type descriptor is evaluated when the type descriptor is resolved." (spec). Basically, the annotations will be resolved once for the class (not for each instance). And therefore, at the point at which the annotation is evaluated, you wouldn't have an object instance, and therefore, access to a self which you can refer to.