在 Xtext 中,如何调整某些函数调用 [英] In Xtext, how to tweak certain function calls

查看:17
本文介绍了在 Xtext 中,如何调整某些函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Xtext 2.15 生成一种语言,除其他外,该语言以看起来同步的方式处理异步调用.

I am using Xtext 2.15 to generate a language that, among other things, processes asynchronous calls in a way they look synchronous.

例如,以我的语言编写的以下代码:

For instance, the following code in my language:

int a = 1;
int b = 2;
boolean sleepSuccess = doSleep(2000); // sleep two seconds
int c = 3;
int d = 4;

将生成以下 Java 代码:

would generate the following Java code:

int a = 1;
int b = 2;
doSleep(2000, new DoSleepCallback() {
  public void onTrigger(boolean rc) {
    boolean sleepSuccess = rc;
    int c = 3;
    int d = 4;
  }
});

为了实现它,我是这样定义语法的:

To achieve it, I defined the grammar this way:

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 规则用于定义异步调用.在我的语言库中,我会有系统调用:

The FunctionDeclaration rule is used to define asynchronous calls. In my language library, I would have as system call:

boolean doSleep(int millis) {} // async FunctionDeclaration element stub

底层 Java 实现将是:

The underlying Java implementation would be:

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 元素的调用、添加回调参数并在内部类中处理主体的其余部分?

So, using the inferrer, type computer and compiler, how to identify calls to FunctionDeclaration elements, add a callback parameter and process the rest of the body in an inner class?

例如,我可以在语言编译器中覆盖 appendFeatureCall,它会起作用吗?还有一部分不知道怎么做...

I could, for instance, override appendFeatureCall in the language compiler, would it work? There is still a part I don't know how to do...

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?剩下的,我也许可以做到……

So basically, how to tell if "feature" points to FunctionDeclaration? The rest, I may be able to do it...

另一个StackOverflow条目相关,我有将FunctionDeclaration作为类在inferrer中实现的想法而不是作为一种方法:

Related to another StackOverflow entry, I had the idea of implementing FunctionDeclaration in the inferrer as a class instead of as a method:

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 默认范围以包含类以使其工作......

The generated class would extend FunctionDeclarationObject, so I thought there was a way to identify FunctionDeclaration as FunctionDeclarationObject subclasses. But then, I would need to extend the XFeatureCall default scoping to include classes in order to making it work...

我完全意识到问题不明显,对不起...

I fully realize the question is not obvious, sorry...

谢谢,

马丁

将 DoSleepCallback 声明从静态修改为抽象(错误)

modified DoSleepCallback declaration from static to abstract (was erroneous)

推荐答案

我认为您无法使用 jvm 模型推断器生成所需的内容.

I don't think you can generate what you need using the jvm model inferrer.

您应该提供您自己的 XbaseCompiler 子类(或 JBaseCompiler,如果有的话...并且不要忘记在您的运行时模块中注册 guice),并将 doInternalToJavaStatement(XExpression expr, ITreeAppendable it, boolean isReferenced) 覆盖为管理您的 FunctionDeclaration 的生成方式.

You should provide your own subclass of the XbaseCompiler (or JBaseCompiler, if any... and don't forget to register with guice in your runtime module), and override doInternalToJavaStatement(XExpression expr, ITreeAppendable it, boolean isReferenced) to manage how your FunctionDeclaration should be generated.

这篇关于在 Xtext 中,如何调整某些函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆