2012-10-31 51 views
0

我正在處理xtext項目,並且我通過.xtext文件生成對象。 我想將新的屬性添加到其中一個生成的對象。 我看到http://christiandietrich.wordpress.com/2011/07/22/customizing-xtext-metamodel-inference-using-xtend2/ 下面的代碼是在ObjectValue 中生成一個臨時變量,但我希望臨時是類型MyObject。在xtext項目中使用xtend生成代碼

如何做?我在哪裏可以讀到它?

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

第一:MyObject必須由EClassEDataType來描述任一。一個普通的Java對象不會這樣做。

如果MyObject是一個EDataType則必須在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並把它掛到模型下面的代碼片段應該工作:

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

太棒了!謝謝!我如何創建我的對象作爲EDataType? –

+0

@DanaKlein:嗯。定義一個'EDataType'有幾種方法。另一個問題是,「EDataType」是否真的是正確的。爲了簡單易行,您可以使用'EcorePackage'中的預定義內容 - 每個getXyz'方法返回'EDataType'。如果你真的想定義你自己的EDataType,那麼你應該先諮詢一本關於EMF的書。 –

+0

謝謝! 是否有可能返回一個Iterator對象? s.t.生成的代碼如下所示: public Iterator getIterator(){} –

相關問題