2017-01-04 5 views
0

У меня есть простая DSL, которая должна генерировать асинхронный код для выражений (это самый простой пример, который я мог бы придумать для иллюстрации моей точки). Я просто добавил к scripting example в новое async заявление:Как сгенерировать код для подтипа XExpression?

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

Где этот крюк?

+0

Я думаю, что я нашел пример в HTTPS : //eclipse.org/Xtext/documentation/207_template.html (язык шаблонов) см. раздел * Расширение компилятора * –

ответ

0

Если продлить XBase вы Ususally не apapt в JvmModelInferrer для компиляции, но вы расширяете XbaseTypeComputer и XbaseCompiler.doInternalToJavaStatement/internalToConvertedExpression (в зависимости от того, что вы на самом деле ввести)

0

Вы должны сделать 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 
        } 
    }