0

我正在处理 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
}
}
4

1 回答 1

1

第一:MyObject必须用 anEClass或 an来描述EDataType。一个普通的 Java 对象不会这样做。

如果MyObject是一个,EDataType那么您必须EAttributehandle方法中添加一个。您的handle方法几乎是正确的,只有EType必须调整:

attr.EType = MyPackage::eINSTANCE.MyObject

否则:如果MyObject是 anEClass那么您必须添加 anEReference而不是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
        ]
    ]
}
于 2012-10-31T20:33:41.410 回答