【问题标题】:code generate with xtend in xtext project在 xtext 项目中使用 xtend 生成代码
【发布时间】:2012-11-01 21:50:25
【问题描述】:

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

【问题讨论】:

    标签: code-generation xtext generated-code xtend


    【解决方案1】:

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

    如果MyObjectEDataType,那么您必须在handle 方法中添加EAttribute。您的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 并将其连接到模型中,以下 sn-p 应该可以工作:

    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
            ]
        ]
    }
    

    【讨论】:

    • @DanaKlein:嗯。有几种方法可以定义EDataTypeEDataType 是否真的是正确的事情是另一个问题。对于简单的事情,您可以使用来自EcorePackage 的预定义内容 - 每个getXyz 方法都返回EDataType。如果你真的想定义自己的 EDataType,那么你应该先查阅一本关于 EMF 的书。
    • 谢谢!是否可以返回 Iterator 对象?英石。生成的代码如下所示: public Iterator getIterator(){}
    • 技术上:我很确定,但我不能随便告诉你。但是“迭代器”听起来像是您正在尝试计算某些东西。那么无论是属性还是引用都不适合放入模型中。在这种情况下,操作听起来更合适。
    • 我正在尝试迭代对象元素。所以为此我想生成一个带有签名的方法: public Iterator getIterator(){...}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2018-11-15
    • 1970-01-01
    相关资源
    最近更新 更多