XText - 获取 XExpression 的内容(编译值)

XText - get content (compiled value) of XExpression

我的 XText 语法的某个部分为 classes 定义了一个块,该块将打印其所有表达式。 XText 语法部分如下所示:

Print: 
    {Print}
    'print' '{' 
        print += PrintLine* 
    '}';
PrintLine:
    obj += XExpression;

现在我使用以下推断代码创建一个 print() 方法:

Print: {
    members += feature.toMethod('print', typeRef(void)) [
    body = '''
        «FOR printline : feature.print»
            System.out.println(«printline.obj»);
        «ENDFOR»
        '''
    ]
}

好的,我继续在 class:

中使用以下代码对其进行测试
print {
    "hallo"
    4
    6 + 7
}

结果如下:

public void print() {
   System.out.println([org.eclipse.xtext.xbase.impl.XStringLiteralImpl@20196ba8 (value: hallo)]);
   System.out.println([org.eclipse.xtext.xbase.impl.XNumberLiteralImpl@7d0b0f7d (value: 4)]);
   System.out.println([<XNumberLiteralImpl> + <XNumberLiteralImpl>]);}

当然,我希望:

public void print() {
   System.out.println("hallo");
   System.out.println(4);
   System.out.println(6+7);
}

我知道我可能必须在 «printline.obj» 的推断器中以某种方式调用编译器,但我真的不确定如何调用。

我认为你这样做是错误的。这听起来像是 xbase 的扩展,而不仅仅是简单的使用。

import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase

Print: 
    {Print}
    'print' 
        print=XPrintBlock
    ;

XPrintBlock returns xbase::XBlockExpression:
    {xbase::XBlockExpression}'{'
        expressions+=XPrintLine*
    '}'
;

XPrintLine returns xbase::XExpression:
    {PrintLine} obj=XExpression

;

计算机类型

class MyDslTypeComputer extends XbaseTypeComputer {

     def dispatch computeTypes(XPrintLine literal, ITypeComputationState state) {
        state.withNonVoidExpectation.computeTypes(literal.obj)
        state.acceptActualType(getPrimitiveVoid(state))
    }

}

编译器

class MyDslXbaseCompiler extends XbaseCompiler {

    override protected doInternalToJavaStatement(XExpression obj, ITreeAppendable appendable, boolean isReferenced) {
        if (obj instanceof XPrintLine) {
            appendable.trace(obj)
            appendable.append("System.out.println(")
            internalToJavaExpression(obj.obj,appendable);
            appendable.append(");")
            appendable.newLine
            return
        }

        super.doInternalToJavaStatement(obj, appendable, isReferenced)
    }

}

XExpressionHelper

class MyDslXExpressionHelper extends XExpressionHelper {

    override hasSideEffects(XExpression expr) {
        if (expr instanceof XPrintLine || expr.eContainer instanceof XPrintLine) {
            return true
        }
        super.hasSideEffects(expr)
    }

}

JvmModelInferrer

def dispatch void infer(Print print, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
    acceptor.accept(
        print.toClass("a.b.C") [
            members+=print.toMethod("demo", Void.TYPE.typeRef) [
                body = print.print
            ]
        ]

    )
}

绑定

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {

    def Class<? extends ITypeComputer> bindITypeComputer() {
        MyDslTypeComputer
    }

    def Class<? extends XbaseCompiler> bindXbaseCompiler() {
        MyDslXbaseCompiler
    }

    def Class<? extends XExpressionHelper> bindXExpressionHelper() {
        MyDslXExpressionHelper
    }
}