先顺带简要谈谈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
(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,看注释算了:
*
* <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。
// 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中的一段注释:
* 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。