EMF中的code generation(二)

先顺带简要谈谈jmerge,它主要用来合并代码。在source和target中用annotation来标记,在jmerge配置文件中使用<merge:dictionaryPattern>元素来指定要匹配的pattern。

在目标代码中删除或修改@generated标记,就没有与dictionary中匹配,那么代码就不会merge。

在source代码中,标记了@unmodified,不管目标代码匹配不匹配@generated都会合并。

 好像新的EMF中已经没有用merge rule xml文件了。还在看是从哪定制rules。

 【GenModelActionBarContributor】pop-up menu 的generate All

 protected IAction generateAllAction = new  GenerateAction
  (
new
 ProjectType[]
   
{
     
new ProjectType(GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, CodeGenEcorePlugin.INSTANCE.getString("_UI_ModelProject_name"
)),
     
new ProjectType(GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE, CodeGenEcorePlugin.INSTANCE.getString("_UI_EditProject_name"
)),
     
new ProjectType(GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE, CodeGenEcorePlugin.INSTANCE.getString("_UI_EditorProject_name"
)),
     
new ProjectType(GenBaseGeneratorAdapter.TESTS_PROJECT_TYPE, CodeGenEcorePlugin.INSTANCE.getString("_UI_TestsProject_name"
))
   }
,
   GenModelEditPlugin.INSTANCE.getString(
"_UI_GenerateAll_menu_item"
));

GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE在GenBaseGeneratorAdapter.canGenerate()判定,如果可以generate,那么有了object和generate type,看注释算了:

    /* <p>Code generation is performed as follows:
   * 
   * <ol>
   * <li>The ...{@link GeneratorAdapter adapters} for the object are obtained.
   * <li>A complete collection of objects to be considered is formed by iteratively invoking the
   *     ...{@link GeneratorAdapter#getGenerateParent(Object, Object) getGenerateParent(Object, Object)} and
   *     ...{@link GeneratorAdapter#getGenerateChildren(Object, Object) getGenerateChildren(Object, Object)} methods on the
   *     adapters for the object, the adapters for the object's parent and children, and so on【在getGeneratorData()中调用】. It is the adapters'
   *     responsibility to determine the relevant objects through their implementations of these methods.
   * <li>If this is the first invocation of ...{@link #generate(Object, Object, String, Monitor)} or initialization has
   *     been ...{@link #requestInitialize() requested}, ...{@link GeneratorAdapterFactory#initialize(Object) initialize(Object)}
   *     is invoked on each adapter factory for the ...{@link #getInput() input} object.
   * <li>The ...{@link GeneratorAdapter#preGenerate(Object, Object) preGenerate(Object, Object)} method is invoked on all
   *     the adapters for every object in the set formed in step 2, giving the adapters a chance to perform setup
   *     before any code is generated.
   * <li>The ...{@link GeneratorAdapter#generate(Object, Object, Monitor) generate(Object, Object, Monitor)} method is
   *     invoked on all the adapters for every object in the set formed in step 2. This is where code generation
   *     actually occurs.
   * <li>The ...{@link GeneratorAdapter#postGenerate(Object, Object) postGenerate(Object, Object)} method is invoked on all
   *     the adapters for every object in the set formed in step 2, giving adapters a chance to clean up from code
   *     generation.
   * </ol>
   * 
   * <p>The operation may be cancelled during step 4 or 5, either based on the <code>Monitor</code> or the
   * <code>Diagnostic</code> returned by any generator adapter invocation. By default, only a <code>CANCEL</code>
   * ...{@link org.eclipse.emf.common.util.Diagnostic#getSeverity severity} will cause code generation to stop; however,
   * this can be customized by overriding ...{@link #canContinue(Diagnostic) canContinue(Diagnostic)}. Even if code
   * generation is cancelled, ...{@link GeneratorAdapter#postGenerate(Object, Object) postGenerate(Object, Object)} will
   * still be called on all the adapters on which ...{@link GeneratorAdapter#preGenerate(Object, Object) preGenerate(Object, Object)}
   * has been called.
*/

 

使用generator的最简单的例子,以下生成一个standard GenModel-decorated Ecore model。

// Globally register the default generator adapter factory for GenModel
// elements (only needed in standalone).
// 
 GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.addDescriptor (GenModelPackage.eNS_URI, GenModelGeneratorAdapterFactory.DESCRIPTOR);
// Create the generator and set the model-level input object.

// 
 Generator generator = new  Generator();
 
 generator.setInput(genModel);

 
// Generator model code.
   //
 generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE,new BasicMonitor.Printing(System.out));

还有所有的代码都集中在Generator中完成,如GenModel中的generator()都已经报废。各种generator通过Adapter组合成新的应用,如AbstractGeneratorAdapter中的generateJava,generateText等是最基本的generator方法,子类GenBaseGeneratorAdapter继承,再组合其他的类,达成成新的应用(典型的adapter)。source code中的一段注释:

* <p><code>GeneratorAdapter</code> implementation performs code generation for a single type of model object. It is
 
* created by a {@link GeneratorAdapterFactory} and used by its containing {@link Generator} . Several different 
 
* generator adapters can be associated with a single object
, with each one contributing functionality to the code
 
* generation for that object. A singleton pattern is usually used for generator adapters, where
 a single instance of an
 
* adapter type is shared by all instances of the same object
 type. 
 
*
 
 
* <p>A generator adapter is primarily responsible for
 two aspects of two tasks. The tasks are:
 
* <ul>

 
* <li>Determining whether code generation is possible for an object .
 
* <li>Generating code for an object
.
 
* </ul>

 
*  
 
* <p>
The two aspects of these tasks are:
 
* <ul>

 
* <li>Assembling the tree of relevant objects for  the task.
 
* <li>Performing the task for each object
.
 
* </ul>

 
* 

此外,默认的merge rules:emf-merge.xml。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值