【问题标题】:How to generate code for a XExpression subtype?如何为 XExpression 子类型生成代码?
【发布时间】:2017-01-04 15:06:08
【问题描述】:

我有一个简单的 DSL,它应该为表达式生成异步代码(这是我能想出的最简单的例子来说明我的观点)。我刚刚在scripting example 中添加了一个新的async 声明:

grammar org.xtext.scripting.Scripting with org.eclipse.xtext.xbase.Xbase

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

Script returns xbase::XBlockExpression:
    {Script}
    (expressions+=XExpressionOrVarDeclaration ';'?)*;

XExpression returns xbase::XExpression:
    super | Async
;

Async:
    'async' expression=XExpression
;

这个想法是async 代码在另一个线程中执行。

我的问题是,如何使用ScriptingJvmModelInferrerAsync.expression 生成代码?

在最简单的情况下,我会像这样包装Async.expression 中的代码?

    AsyncRunner.exec(new Runnable() {
        @Override
        public void run() {
            // the Async.expression would end up here
        }
    })

这样做的钩子在哪里?

【问题讨论】:

标签: xtext xbase


【解决方案1】:

您必须进行 3 项更改:

  1. 扩展编译器以处理您的语言。关键是处理Async表达式。

    class ScriptingCompiler extends XbaseCompiler {
    
        override protected doInternalToJavaStatement(XExpression expr, ITreeAppendable it, boolean isReferenced) {
            switch expr {
                Async : {
                    newLine
                    append('''
                        AsyncRunner.exec(new Runnable() {
                          @Override
                          public void run() {''')
                    expr.expression.doInternalToJavaStatement(it, false)
                    newLine
                    append('}});')
    
                }
    
                default :
                    super.doInternalToJavaStatement(expr, it, isReferenced)
            }
        }
    
        override protected internalToConvertedExpression(XExpression obj, ITreeAppendable it) {
            if (hasName(obj))
                append(getName(obj))
            else 
                super.internalToConvertedExpression(obj, it) 
        }
    }
    
  2. 必须指定表达式的类型

    class ScriptingTypeComputer extends XbaseWithAnnotationsTypeComputer {
    
        override computeTypes(XExpression expression, ITypeComputationState state) {
            if(expression instanceof Async) {
                super.computeTypes(expression.expression, state);
            } else {
                super.computeTypes(expression, state)
            }
        }
    }
    
  3. 两个扩展都必须注入:

    class ScriptingRuntimeModule extends AbstractScriptingRuntimeModule {
        def Class<? extends XbaseCompiler> bindXbaseCompiler() {
            return ScriptingCompiler
        }
    
        def Class<? extends ITypeComputer> bindITypeComputer() {
            return ScriptingTypeComputer
        }
    }
    

【讨论】:

    【解决方案2】:

    如果您扩展 Xbase,您通常不会将 JvmModelInferrer 用于编译,而是扩展 XbaseTypeComputerXbaseCompiler.doInternalToJavaStatement/internalToConvertedExpression(取决于您实际引入的内容)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-23
      • 2018-07-03
      • 2022-10-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2020-11-07
      相关资源
      最近更新 更多