【问题标题】:How to JvmModelInferrer method body from XExpression and append boilerplate code如何从 XExpression 获取 JvmModelInferrer 方法体并附加样板代码
【发布时间】:2018-10-10 08:23:56
【问题描述】:

在JvmModelInferrer中,在构造方法或构造函数的主体时,如何从语法中插入both一个XExpression

body = op.body

和额外的“样板”代码,例如

body = [
    append(
    '''
        System.out.println("BOILERPLATE");
    '''
    )
]

我可以做到,但不能同时做到。

对于一个最小的工作示例,请考虑以下规范的 Xbase 语法,

grammar org.example.xbase.entities.Entities with org.eclipse.xtext.xbase.Xbase

generate entities "http://www.example.org/xbase/entities/Entities"

Model:
    importSection=XImportSection?
    entities+=Entity*;

Entity:
    'entity' name=ID ('extends' superType=JvmParameterizedTypeReference)? '{'
        attributes += Attribute*
        operations += Operation*
    '}';

Attribute:
    'attr' (type=JvmTypeReference)? name=ID ('=' initexpression=XExpression)? ';';

Operation:
    'op' (type=JvmTypeReference)? name=ID 
    '(' (params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' 
        body=XBlockExpression;

和 JvmModelInferrer,

package org.example.xbase.entities.jvmmodel

import com.google.inject.Inject
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.example.xbase.entities.entities.Entity

class EntitiesJvmModelInferrer extends AbstractModelInferrer {

    @Inject extension JvmTypesBuilder

    def dispatch void infer(Entity entity, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
        acceptor.accept(entity.toClass("entities."+entity.name)) [
            documentation = entity.documentation
            if (entity.superType != null)
                superTypes += entity.superType.cloneWithProxies
            entity.attributes.forEach[
                a | 
                val type = a.type ?: a.initexpression?.inferredType
                members += a.toField(a.name, type) [
                    documentation = a.documentation
                    if (a.initexpression != null)
                        initializer = a.initexpression
                ]
                members += a.toGetter(a.name, type)
                members += a.toSetter(a.name, type)
            ]
            entity.operations.forEach[
                op |
                members += op.toMethod(op.name, op.type ?: inferredType) [
                    documentation = op.documentation
                    for (p : op.params) {
                        parameters += p.toParameter(p.name, p.parameterType)
                    }
//              body = [
//                  append(
//                  '''
//                      System.out.println("BOILERPLATE");
//                  '''
//                  )
//              ]
                body = op.body
                ]
            ]
        ]
    }
}

正如 cmets 所建议的,我想在 XExpression 本身之前将“样板”代码插入到方法的主体中。虽然我可以插入样板或表达式,但我不知道如何同时执行这两种操作。

【问题讨论】:

    标签: xtext xbase


    【解决方案1】:

    这不起作用。你唯一能做的就是推断出两种方法

    methodWithBoilerplate() {
        //pre
        methodwithoutboilerplate
        //post
    }
    methodwithoutboilerplate() {
        usercode goes here
    }
    
    • 首次使用body = '''code here'''
    • 第二次使用body = exp.body

    【讨论】:

    • 感谢您的回答。这种方法是我的“解决方法”,但我想看看是否有更纯粹的解决方案。没有通过 XExpression API 的自然方式吗?组合表达式然后设置正文? (我当然看过。)
    • 正如我所说:不,没有好办法以编程方式完成
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 2018-05-20
    • 2011-09-26
    • 2013-11-02
    • 2011-10-05
    • 2012-05-29
    相关资源
    最近更新 更多