如何使用xtext中的JvmModelInferrer使用声明变量的值生成代码?

时间:2012-09-10 16:38:20

标签: xtext

所以我有以下XText语法:

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;

我试过摆弄范围和推理者,但无济于事。我试图做的是什么?

1 个答案:

答案 0 :(得分:2)

基本上有两种选择:

  1. 您可以为模型中的每个constantDecl推断JvmType中的常量。
  2. 您必须自定义各种各样的内容,例如范围,代码生成和验证,以便将常量值内联到表达式中。
  3. 由于我发现(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
      ]
    ]