简体   繁体   中英

XText - get content (compiled value) of XExpression

I have a certain part of my XText grammer that defines a block for classes that shall print all its expressions. The XText grammar part for this looks as follows:

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

Now I use the following inferrer code to create a print() method:

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

Ok, I go ahead and test it with the following code in a class:

print {
    "hallo"
    4
    6 + 7
}

And the result is the following:

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>]);}

Of course, I was hoping for:

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

I understand that I might have to call the compiler somehow in the inferrer for «printline.obj» , but I am really not sure how.

i think you are doing this on a wrong basis. this sounds to me like an extension of xbase, not only a simple use.

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

;

Type Computer

class MyDslTypeComputer extends XbaseTypeComputer {

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

}

Compiler

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
            ]
        ]

    )
}

Bindings

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM