ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
136 stars 58 forks source link

Compiler crash in persist for model with few records #4745

Open SasinduDilshara opened 1 year ago

SasinduDilshara commented 1 year ago

Persist occurs a compiler. crash for program with following content inside the model.bal file.

import ballerina/persist as _;
import ballerina/time;

type ShipmentEntry record {|
    readonly string shipmentId;
    string status;
    string origin;
    string destination;
    string eta;
|};

public type Order record {
    int orderId;
    string destination;
    OrderItems[] items;
    string? shipmentId = ();
};

type OrderItems record {|
    string name;
    int quantity = 0;
    float? estimatedPrice;
    string country;
    time:Date manufacturedDate;
    time:Date? expiredDate;
|};

The compiler crash error message is

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-08-22 11:55:00,309] SEVERE {b7a.log.crash} - The compiler extension in package 'ballerina:persist:1.0.0' failed to complete. class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app') 
io.ballerina.projects.ProjectException: The compiler extension in package 'ballerina:persist:1.0.0' failed to complete. class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app')
        at io.ballerina.projects.SyntaxNodeAnalysisTask.perform(SyntaxNodeAnalysisTask.java:62)
        at io.ballerina.projects.SyntaxTreeVisitor.runAnalysisTasks(SyntaxTreeVisitor.java:93)
        at io.ballerina.projects.SyntaxTreeVisitor.visitSyntaxNode(SyntaxTreeVisitor.java:80)
        at io.ballerina.compiler.syntax.tree.NodeVisitor.visit(NodeVisitor.java:43)
        at io.ballerina.projects.SyntaxTreeVisitor.runAnalysisTasks(SyntaxTreeVisitor.java:68)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:76)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:59)
        at io.ballerina.projects.SyntaxNodeAnalysisTaskRunner.runTasks(SyntaxNodeAnalysisTaskRunner.java:51)
        at io.ballerina.projects.CodeAnalyzerManager.runSyntaxNodeAnalysisTasks(CodeAnalyzerManager.java:108)
        at io.ballerina.projects.CodeAnalyzerManager.runCodeAnalyzerTasks(CodeAnalyzerManager.java:61)
        at io.ballerina.projects.PackageCompilation.compile(PackageCompilation.java:118)
        at io.ballerina.projects.PackageCompilation.from(PackageCompilation.java:94)
        at io.ballerina.projects.PackageContext.getPackageCompilation(PackageContext.java:222)
        at io.ballerina.projects.Package.getCompilation(Package.java:146)
        at io.ballerina.persist.utils.BalProjectUtils.validateSchemaFile(BalProjectUtils.java:114)
        at io.ballerina.persist.cmd.Generate.execute(Generate.java:153)
        at java.base/java.util.Optional.ifPresent(Optional.java:183)
        at io.ballerina.cli.launcher.Main.main(Main.java:53)
Caused by: java.lang.ClassCastException: class io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode cannot be cast to class io.ballerina.compiler.syntax.tree.RecordFieldNode (io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode and io.ballerina.compiler.syntax.tree.RecordFieldNode are in unnamed module of loader 'app')
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.reportMandatoryCorrespondingFieldDiagnostic(PersistModelDefinitionValidator.java:773)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.validateRelation(PersistModelDefinitionValidator.java:546)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.perform(PersistModelDefinitionValidator.java:196)
        at io.ballerina.stdlib.persist.compiler.PersistModelDefinitionValidator.perform(PersistModelDefinitionValidator.java:112)
        at io.ballerina.projects.SyntaxNodeAnalysisTask.perform(SyntaxNodeAnalysisTask.java:46)
        ... 17 more
SasinduDilshara commented 1 year ago

If we put following content to the model.bal. it will resolve the issue.

import ballerina/persist as _;
import ballerina/time;

type ShipmentEntry record {|
    readonly string shipmentId;
    string status;
    string origin;
    string destination;
    string eta;
|};

public type Order record {|
    readonly int orderId;
    string destination;
    OrderItems[] items;
    string? shipmentId;
|};

public type OrderItems record {|
    readonly string name;
    Order orderId;
    int quantity;
    float? estimatedPrice;
    string country;
    time:Date manufacturedDate;
    time:Date? expiredDate;
|};