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