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