2012-09-10 27 views
0

所以我有以下XTEXT語法:如何使用xtext中的JvmModelInferrer使用聲明變量的值生成代碼?

grammar org.xtext.example.hyrule.HyRule with org.eclipse.xtext.xbase.Xbase 

generate hyRule "http://www.xtext.org/example/hyrule/HyRule" 


Start: 
    rules+=Rule+; 

Rule: 
    constantDecs+= XVariableDeclaration* 
    elementDecs+=elementDec+ 
    'PAYLOAD' payload=PAYLOAD 'CONSTRAINT' expression= XExpression 
; 

elementDec: 
    variable=FullJvmFormalParameter '=' xpath=XPATH 
; 




PAYLOAD: 
    "Stacons" | "any" | "sse"; 



//we override the definition in Xtype.xtext, so that we can have // in Xpaths 
terminal SL_COMMENT: 
    '#' !('\n' | '\r')* ('\r'? '\n')?; 

terminal XPATH: 
    (('//'|'/')('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'_'|':'|'0'..'9')*)+ 

    ; 

,我使用一個JvmModelInferrer推斷爲每個規則的方法。該推斷器的代碼的相關部分是:

def dispatch void infer(Start start, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { 

     for (rule: start.rules) { 
      acceptor.accept(rule.toClass("Rule" + counter)).initializeLater[ 
       ... 
       // method used to check the rule this class represents 
       members += rule.toMethod("checkRule",rule.newTypeRef('boolean'))[ 
        for (e : rule.elementDecs) { 
         parameters += e.variable.toParameter(e.variable.name, e.variable.parameterType) 
        } 
        setStatic(true) 
        body = expression 
       ] 

我想不出怎麼做的就是在可見的表達constantDecs變量decalarations的價值觀,更具體如何爲生成代碼包含這些值的表達式。目前變量聲明在生成代碼的範圍內,但是它們的值被聲明爲他們的名字。 例如輸入:

val j = Integer::parseInt('199') 
int x = //val/v 
PAYLOAD Stacons CONSTRAINT x>j 

導致生成的方法:

public static boolean checkRule(final int x) { 
    int _j = j; 
    boolean _greaterThan = (x > _j); 
    return _greaterThan; 
    } 

而我想它生成方法:

public static boolean checkRule(final int x) { 
     int _j = 199; 
     boolean _greaterThan = (x > _j); 
     return _greaterThan; 
     } 

我的範圍提供商看起來像這樣:

@Inject 
    IJvmModelAssociations associations; 

    @Override 
    protected IScope createLocalVarScopeForJvmOperation(JvmOperation context, IScope parentScope) { 
     parentScope = super.createLocalVarScopeForJvmOperation(context, parentScope); 

     // retrieve the AST element associated to the method 
     // created by our model inferrer 
     EObject sourceElement = associations.getPrimarySourceElement(context); 
     if (sourceElement instanceof Rule) { 
      Rule rule = (Rule) sourceElement; 
      return Scopes.scopeFor(rule.getConstantDecs(), parentScope); 
     } 

     return parentScope; 

我已經嘗試擺弄範圍和推理,但無濟於事。我正在嘗試做什麼?

回答

2

基本上有兩種選擇:

  1. 你可以推斷出在JvmType每個constantDecl常數模型。
  2. 你必須定製各種各樣的東西,如範圍界定,代碼生成和驗證,以便將常量值內聯到表達式中。

因爲我發現(2)方式太差,我建議去(1)。

acceptor.accept(rule.toClass("Rule" + counter)).initializeLater[ 
    .. 
    for(varDecl : constantDecs) { 
    switch(varDecl) { 
    XVariableDeclaration: members += varDecl.toField(varDecl.name, varDecl.type) [ 
     initializer = varDecl.right 
     setStatic(true) 
     setFinal(true) 
    ] 
    } 

    } 
    // method used to check the rule this class represents 
    members += rule.toMethod("checkRule",rule.newTypeRef('boolean'))[ 
    for (e : rule.elementDecs) { 
     parameters += e.variable.toParameter(e.variable.name, e.variable.parameterType) 
    } 
    setStatic(true) 
    body = expression 
    ] 
] 
+0

我已經試過了,問題是,varDecl是XExpression不是XVariableDeclaration(因爲這是什麼XVariableDeclaration規則回報)那裏似乎因此不是一個方式,它得到它的名字,或者它的類型。 –

+0

它很可能在運行時,因爲XVariableDeclaration的解析器規則總是返回一個XVariableDeclaration(如果不以其他方式重寫和更改它)。我更新了代碼片段。 –

+0

完美,謝謝:)。 –