Xtext 2.8+ 格式化程序,格式化简单规则

Xtext 2.8+ formatter, formatting simple rule

我是Xtend/Xtext新手。目前我正在使用新的格式化程序 API,我正在尝试格式化规则,如下所示:

Expression:
    Error|Warning|Enum|Text
;

使用这样的 xtend 调度方法

def dispatch void format(Expression e){
        if (e instanceof ErrorImpl)
            ((ErrorImpl)e).format
}

问题是,表达式 e 的类型是不可发现的,我收到这个错误

Type mismatch: cannot convert from Class<ErrorImpl> to Expression

为什么我不能进行这种转换(我当然怀疑 xTend 语义)(甚至 Eclipse 告诉我 Expression 只是创建子项的接口。 ) 以及如何为该规则的每个子项调用 format 方法?谢谢

Xtend 的类型转换语法不同:您写 e as ErrorImpl 而不是 (ErrorImpl) e。在这种情况下,甚至不需要类型大小写:由于前面的 instanceof 检查,变量 e 被隐式转换为 ErrorImpl,因此您可以编写与 [=20] 相同的代码=]

def dispatch void format(Expression e) {
    if (e instanceof ErrorImpl)
        e.format
}

但是,此代码会导致堆栈溢出,因为使用相同的输入递归调用 format(EObject) 方法。为了正确地利用分派方法的力量,你应该这样写你的代码:

def dispatch void format(Error error) {
    // Code for handling Errors
}
def dispatch void format(Warning warning) {
    // Code for handling Warnings
}
def dispatch void format(Enum enum) {
    // Code for handling Enums
}
def dispatch void format(Text text) {
    // Code for handling Texts
}

这会生成一个方法 format(Expression),它会根据参数类型自动分派到更具体的方法。

请注意,格式化程序调度方法还需要 IFormattableDocument 类型的第二个参数,因此它们应该类似于

def dispatch void format(Error error, extension IFormattableDocument document) {
    // Code for handling Errors
}
...