2017-01-04 7 views
0

J'ai un simple DSL qui devrait générer du code asynchrone pour les expressions (c'est l'exemple le plus simple que j'ai pu trouver pour illustrer mon propos). Je viens d'ajouter à la scripting example une nouvelle déclaration async:Comment générer du code pour un sous-type 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 
; 

L'idée serait que le code async est exécuté dans un autre thread.

Ma question est, comment puis-je générer du code pour le Async.expression en utilisant le ScriptingJvmModelInferrer?

Dans le cas le plus simple, je voudrais juste envelopper le code de la Async.expression comme ça?

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

Où est le crochet pour faire cela?

+0

Je crois avoir trouvé un exemple dans https : //eclipse.org/Xtext/documentation/207_template.html (Template Template) voir la section * Extension du compilateur * –

Répondre

0

Si vous étendez Xbase vous ne ususally pas apapt le JvmModelInferrer pour la compilation, mais vous étendez XbaseTypeComputer et XbaseCompiler.doInternalToJavaStatement/internalToConvertedExpression (selon ce que vous présentez en fait)

0

Vous devez faire 3 changements:

  1. Étendez le compilateur pour gérer votre langue. Le point clé consiste à gérer l'expression 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. Le type de l'expression doit être spécifiée

    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. Les deux extensions doivent être injectés:

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