我正在使用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?其余的,我也许可以做到...
与another StackOverflow entry相关,我想到了在推断器中将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声明从静态修改为抽象(错误)
答案 0 :(得分:0)
我认为您无法使用jvm模型推断器生成所需的内容。
您应该提供自己的XbaseCompiler子类(或JBaseCompiler,如果有的话……,并且不要忘记在运行时模块中向guice注册),并重写doInternalToJavaStatement(XExpression expr,ITreeAppendable it,boolean isReferenced)以管理应如何生成FunctionDeclaration。