代码在xtext项目中使用xtend生成

时间:2012-10-31 11:47:00

标签: code-generation xtext generated-code xtend

我正在研究xtext项目,我正在通过.xtext文件生成对象。 我想为其中一个生成的对象添加新属性。 我在http://christiandietrich.wordpress.com/2011/07/22/customizing-xtext-metamodel-inference-using-xtend2/看到了 以下代码在ObjectValue中生成临时变量 但我希望temp属于MyObject类型。

怎么做?我在哪里可以阅读它?

import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage
import org.eclipse.emf.common.util.BasicEMap$Entry
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.EcoreFactory
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.xtext.GeneratedMetamodel
import org.eclipse.xtext.xtext.ecoreInference.IXtext2EcorePostProcessor

class CodeGeneratorClass implements IXtext2EcorePostProcessor {

    override process(GeneratedMetamodel metamodel) {
        metamodel.EPackage.process
    }

    def process(EPackage p) {
        for (c : p.EClassifiers.filter(typeof(EClass))) {
            if (c.name == "ObjectValue") {
                c.handle
            }
        }
    }

    def handle (EClass c) {
    val attr = EcoreFactory::eINSTANCE.createEAttribute
    attr.name = "temp"
    attr.EType = EcorePackage::eINSTANCE.EString
    c.EStructuralFeatures += attr
}
}

1 个答案:

答案 0 :(得分:1)

首先:MyObject必须由EClassEDataType来描述。普通的Java对象不会这样做。

如果MyObjectEDataType,那么您必须在EAttribute方法中添加handle。您的handle方法几乎正确,只需调整EType

attr.EType = MyPackage::eINSTANCE.MyObject

否则:如果MyObjectEClass,那么您必须添加EReference而不是EAttribute。此案例的handle方法如下所示:

def handleReference(EClass c){
    val ref = EcoreFactory::eINSTANCE.createEReference
    ref.name = "temp"
    ref.EType = MyPackage::eINSTANCE.MyObject
    c.EStructuralFeatures += ref
}

修改

为了定义一个新的最小EDataType并将其连接到模型中,以下代码片段应该可以工作:

def void process(GeneratedMetamodel it){
     // create new dynamic EDataType
     val dataType = EcoreFactory::eINSTANCE.createEDataType => [
        name = 'MyObject'
        instanceTypeName = 'java.package.with.MyObject' 
    ]

    // register new EDataType in own model package
    EPackage.EClassifiers += dataType

    // attach as EAttribute to appropriate EClasses
    EPackage.EClassifiers.filter(typeof(EClass)).filter[name == 'ObjectValue'].forEach[
        EStructuralFeatures += EcoreFactory::eINSTANCE.createEAttribute => [
            name = "temp"
            EType = dataType
        ]
    ]
}