芭蕾舞女演员注释处理无法按预期进行

时间:2019-12-14 18:28:19

标签: wso2 annotation-processing ballerina

我正在尝试使用芭蕾舞演员(在MacOS Catalina上为jBallerina-1.0.5)实现一个简单的注释处理器。在此示例中,我需要:

  1. 遍历给定resource的可用service函数
  2. 对于每次迭代,获取@annotation中注释的给定resource的值

例如:

...
service my_service on new http:Listener(8080) {
    @my_annonatation {
        value: "my-value-for-resource-1"
    }
    resource function my_resource_1() {}

    @my_annonatation {
        value: "my-value-for-resource-2"
    }
    resource function my_resource_2() {}
}

根据上面的service代码段,我需要将resource的名称命名为["my_resource_1", "my_resource_2"],将@annotation的值命名为my-value-for-resource-1my-value-for-resource-2 my_resource_1my_resource_2

我的问题是:

  1. 我如何与芭蕾舞女演员一起在给定的resource中定义的service
  2. 我尝试使用function getServiceAnnotations(service serviceType, string annotName, string? moduleName = ()) returns any模块的ballerina/reflect获得@annotation的值。但是它没有任何回报(显然它返回了一个空字符串,或者可能为null)。

除旧的芭蕾舞女演员0.x预发行版1外,我没有看到任何有关芭蕾舞女演员注释处理的好文章。我发现ballerina/reflect模块现在已更新2 3,因为我将0.x预发行版与芭蕾舞女演员源代码进行了比较(但芭蕾舞女演员发行说明{{中并未提及3}})。

“ Extending Ballerina” 4文章也提到了通过编译器扩展进行注释处理的另一种方法,该扩展将操作委托给Java。但是,我们存在将Java依赖关系推入ballerina central的局限性。

请向我建议一种解决方法,以获得预期的结果,并且非常感谢纯芭蕾舞演员编写的代码。

参考

  1. 5
  2. Ballerina Annotation Processing example for 0.9.x releases
  3. ballerina/reflect of 0.x
  4. ballerina/reflect of 1.0.5
  5. Ballerina release notes

2 个答案:

答案 0 :(得分:3)

注释处理可以在编译时或运行时进行。目前(使用Ballerina 1.0.5和更早版本),编译时注释处理只能通过“扩展芭蕾舞女演员”文档中所述的编译器扩展来完成,而运行时注释访问可以使用annotation access expression来完成或通过ballerina/reflect模块(目前ballerina/reflect模块中仅提供了通过注释访问表达式无法实现的功能-而在发行说明中提到了此附加功能“二进制运算符。@已被删除。引入了在运行时访问批注值的功能。”,这似乎遗漏了ballerina/reflect模块中的某些功能。

https://github.com/ballerina-platform/ballerina-lang/issues/19325描述了拟议的Ballerina编译器插件体系结构,该体系结构允许使用Ballerina编写扩展。

在运行时:

  1. 要检索服务中定义的资源的名称-IINM,如果不编写外部方法(使用Java互操作),当前无法实现。在编译时是否不知道资源名称?您能否根据要求创建一个issue in the ballerina-lang repository

  2. 访问资源注释-可以使用reflect:getResourceAnnotations方法

import ballerina/http;
import ballerina/io;
import ballerina/reflect;

type AnnotRecord record {| 
    string value; 
|};

annotation AnnotRecord my_annonatation on resource function;

string[] resourceNames = ["my_resource_1", "my_resource_2"];

service my_service on new http:Listener(8080) {
    @my_annonatation {
        value: "my-value-for-resource-1"
    }
    resource function my_resource_1(http:Caller caller, http:Request request) {}

    @my_annonatation {
        value: "my-value-for-resource-2"
    }
    resource function my_resource_2(http:Caller caller, http:Request request) {}
}

public function main() {
    foreach var resourceName in resourceNames {
        any annot = reflect:getResourceAnnotations(my_service, resourceName, "my_annonatation");
        if annot is AnnotRecord {
            io:println(annot.value);
        }
    }
}

答案 1 :(得分:0)

更新:

@MaryamZis的解决方案适用于单个芭蕾舞女演员文件,但不适用于芭蕾舞女演员项目。正如她建议的那样,我已将<org-name>/<module>:<version>传递到module函数的reflect:getResourceAnnotations参数中,以使其正常工作。

...
any annot = reflect:getResourceAnnotations(
    my_service, 
    resourceName, 
    "my_annonatation", 
    "my_org/my_module:0.1.0"
);
...

//NOTE: org-name and version are defined in Ballerina.toml of the project

但是,期望通过reflect函数检测当前项目的注释而无需指定模块。 issue由@MaryamZi记录在芭蕾舞女演员git存储库中。