ballerina-platform / ballerina-lang

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

[Bug]: Getting error when getting the symbol for a class definition which is defined in a separate module #42159

Closed TharmiganK closed 8 months ago

TharmiganK commented 9 months ago

Description

When I call SemanticModel.symbol(ClassDefinitionNode) I am getting a Bad Sad error. This is happening only when the class is defined in a separate module.

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.

[2024-02-14 17:01:36,200] SEVERE {b7a.log.crash} - No value present 
java.util.NoSuchElementException: No value present
        at java.base/java.util.Optional.get(Optional.java:143)
        at io.ballerina.compiler.api.impl.BallerinaSemanticModel.getCompilationUnit(BallerinaSemanticModel.java:495)
        at io.ballerina.compiler.api.impl.BallerinaSemanticModel.symbol(BallerinaSemanticModel.java:181)

Steps to Reproduce

  1. Create a Ballerina project
  2. Add a module in the project
  3. Define a simple Ballerina class inside the new module
    class Client {}
  4. Try to get the symbol related to this ClassDefinitionNode using the semantic model

Affected Version(s)

Ballerina SwanLake 2201.8.4

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

TharmiganK commented 9 months ago

Adding more context to this issue:

dulajdilshan commented 8 months ago

After proper investigation to this, I found that: The way we access the semantic model is not correct in the openapi-tools: https://github.com/ballerina-platform/openapi-tools/blob/e84b6a9f6eaecf7f628fc9ab0a89578f2b5c6c42/ballerina-to-openapi/src/main/java/io/ballerina/openapi/service/mapper/ServiceToOpenAPIMapper.java#L259,

The correct way to find the compiler symbol for the given node is as follows.

Module module = project.currentPackage().module(project.currentPackage().moduleIds().stream().toList().get(1)); // get the `representations` module
DocumentId documentId = module.documentIds().stream().findFirst().get();    // contains only `representations.bal` document
SyntaxTree syntaxTree = module.document(documentId).syntaxTree();   // get the syntax tree of the `representations.bal` document
ModuleMemberDeclarationNode classDefNode = ((ModulePartNode) syntaxTree.rootNode()).members().get(0); // get the class-def node

SemanticModel semanticModel_1 = project.currentPackage().getCompilation().getSemanticModel(module.moduleId());   // initialize semantic model
semanticModel_1.symbol(classDefNode).get();
image

The reason for this is. The semantic Model is a per-module construct and we assume that compiler plugin developer access the semantic APIs using nodes or locations from matching modules. @TharmiganK Please check.


Related ballerina source code as structured below

image

representations.bal

import ballerina/http;
import 'service.types;

public service class RequestErrorInterceptor {
    *http:RequestErrorInterceptor;

    resource function 'default [string... path](error err, http:RequestContext ctx) returns types:Post|http:NextService|error? {
        return ctx.next();
    }
}

main.bal

import ballerina/http;

service /api on new http:Listener(9090) {

}
dulajdilshan commented 8 months ago

However, we are sending a bad sad error since we have let semantic API throw an error if incorrect usage.

TharmiganK commented 8 months ago

Ack. Thanks for the help. I will correct this from openapi-tool side.

Please close this issue once you fix throwing the bad sad error for such scenarios. Better to throw a proper error in this case

github-actions[bot] commented 8 months ago

This issue is NOT closed with a proper Reason/ label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.

      - Reason/EngineeringMistake - The issue occurred due to a mistake made in the past.
      - Reason/Regression - The issue has introduced a regression.
      - Reason/MultipleComponentInteraction - Issue occured due to interactions in multiple components.
      - Reason/Complex - Issue occurred due to complex scenario.
      - Reason/Invalid - Issue is invalid.
      - Reason/Other - None of the above cases.