xtext - 在 Xtext 中,如何调整某些函数调用
问题描述
我正在使用 Xtext 2.15 生成一种语言,除其他外,它以看起来同步的方式处理异步调用。
例如,我的语言中的以下代码:
int a = 1;
int b = 2;
boolean sleepSuccess = doSleep(2000); // sleep two seconds
int c = 3;
int d = 4;
将生成以下 Java 代码:
int a = 1;
int b = 2;
doSleep(2000, new DoSleepCallback() {
public void onTrigger(boolean rc) {
boolean sleepSuccess = rc;
int c = 3;
int d = 4;
}
});
为了实现它,我以这种方式定义了语法:
grammar org.qedlang.qed.QED with jbase.Jbase // Jbase inherits Xbase
...
FunctionDeclaration return XExpression:
=>({FunctionDeclaration} type=JvmTypeReference name=ValidID '(')
(params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)?
')' block=XBlockExpression
;
FunctionDeclaration 规则用于定义异步调用。在我的语言库中,我将作为系统调用:
boolean doSleep(int millis) {} // async FunctionDeclaration element stub
底层 Java 实现将是:
public abstract class DoSleepCallback {
public abstract void onTrigger(boolean rc);
}
public void doSleep(int millis, DoSleepCallback callback) {
<perform sleep and call callback.onTrigger(<success>)>
}
那么,使用推断器、类型计算机和编译器,如何识别对 FunctionDeclaration 元素的调用、添加回调参数并在内部类中处理主体的其余部分?
例如,我可以在语言编译器中覆盖 appendFeatureCall,它会工作吗?还有一部分不知道怎么办...
override appendFeatureCall(XAbstractFeatureCall call, ITreeAppendable b) {
...
val feature = call.feature
...
if (feature instanceof JvmExecutable) {
b.append('(')
val arguments = call.actualArguments
if (!arguments.isEmpty) {
...
arguments.appendArguments(b, shouldBreakFirstArgument)
// HERE IS THE PART I DON'T KNOW HOW TO DO
<IF feature IS A FunctionDeclaration>
<argument.appendArgument(NEW GENERATED CALLBACK PARAMETER)>
<INSERT REST OF XBlockExpression body INSIDE CALLBACK INSTANCE>
<ENDIF>
}
b.append(');')
}
}
所以基本上,如何判断“特征”是否指向 FunctionDeclaration?剩下的,我也许能做到……
与另一个 StackOverflow 条目相关,我有在推断器中将 FunctionDeclaration 实现为类而不是方法的想法:
def void inferExpressions(JvmDeclaredType it, FunctionDeclaration function) {
// now let's go over the features
for ( f : (function.block as XBlockExpression).expressions ) {
if (f instanceof FunctionDeclaration) {
members += f.toClass(f.fullyQualifiedName) [
inferVariables(f)
superTypes += typeRef(FunctionDeclarationObject)
// let's add a default constructor
members += f.toConstructor [
for (p : f.params)
parameters += p.toParameter(p.name, p.parameterType)
body = f.block
]
inferExpressions(f)
]
}
}
}
生成的类将扩展 FunctionDeclarationObject,所以我认为有一种方法可以将 FunctionDeclaration 标识为 FunctionDeclarationObject 子类。但是,我需要扩展 XFeatureCall 默认范围以包含类以使其工作......
我完全意识到这个问题并不明显,对不起......
谢谢,
马丁
编辑:将 DoSleepCallback 声明从静态修改为抽象(错误)
解决方案
我不认为你可以使用 jvm 模型推断器生成你需要的东西。
您应该提供您自己的 XbaseCompiler 子类(或 JBaseCompiler,如果有的话......并且不要忘记在运行时模块中注册 guice),并覆盖 doInternalToJavaStatement(XExpression expr, ITreeAppendable it, boolean isReferenced) 来管理您的应生成 FunctionDeclaration。
推荐阅读
- azure-ad-b2c - SM-Noop 和 nothing 之间的区别
- python - 如何用熊猫绘制具有不同值但比例相同的列?
- vuejs2 - vue2 composition api beforeRouteUpdate 路由变化后更新
- qt - 在 Visual Studio2019 中使用 Qt 6.1.3 的错误
- javascript - 代码在控制台中运行良好,但在添加到文件时无法正常工作 - 未捕获类型错误:无法读取 null 的属性(读取“样式”)
- python - Python Pandas QTableView如何删除选定的行并刷新qtableview
- linux - 无法在 debian 拉伸上构建 gobject--introspection-1.70.0
- woocommerce - 在检出页面上添加自定义字段
- go - 如何拆分传递给方法的接口
- clang - 为什么.eh_frame 和.eh_frame_hdr 在clang 32bit 中不存在所以呢?