1

式の非同期コードを生成する単純な DSL があります (これは、要点を説明するために思いつく最も単純な例です)。スクリプト例に新しい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コードが別のスレッドで実行されるということです。

Async.expression私の質問は、を使用してコードを生成するにはどうすればよいScriptingJvmModelInferrerですか?

最も単純なケースでは、次のAsync.expressionようにコードをラップしますか?

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

それを行うためのフックはどこにありますか?

4

2 に答える 2

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
        }
    }
    
于 2017-01-09T10:59:01.407 に答える
0

Xbase を拡張する場合、通常はコンパイル用に JvmModelInferrer を適用しませんが、拡張XbaseTypeComputerしてXbaseCompiler.doInternalToJavaStatement/internalToConvertedExpression(実際に導入するものによって異なります)

于 2017-01-05T08:14:26.350 に答える