JET FAQ How does JMerge work?
How does JMerge work?
JMerge is reconciles an existing Java file (the Existing Code) with the Java code produced by the code generator (the Emitted Code). There result of JMerge is the Merged Code. JMerge is driven by a JMerge rules file, and is a multi-step process.
Step 1 - loading
JMerge loads JMerge rules file (an XML document), and both the Existing Code and the Emitted Code into an in memory model. The in memory model is, by default, an Abstract Syntax Tree (AST) created by the Jave Development Tools (JDT).
Step 2 - markup
- The JMerge rules must contain one or more 'markup' elements which specify regular expressions that will be executed against elements in the ASTs for the Existing and Emitted Code. For example, the EMF provided rules specifies a rule that looks for @generated in the javadoc of all AST fields, methods, classes, .... Markup regular expressions must include a 'capture', which is a subexpression enclosed in parentheses. For example, the regular expression for EMF @generated markup is
- When a markup rule matches a Java element, JMerge records the 'capture' of the rule and the corresponding Java element. In the case of the EMF @generated markup rule, JMerge would record the string 'gen' against any Java element with an @generated tag.
Step 3 - pull
- JMerge traverses 'pull' elements from the JMerge rules file. Each JMerge pull element specifies the type of AST object it operates on, and the markup that must exist on the object in order for the rule to operate. Finally, each pull rule specifies an AST object attribute to be copied from the Existing Code into the Emitted Code. For example, EMF has a pull rule on methods that copies the method body when the source and target methods both have the 'gen' markup.
- JMerge executes a pull rule by finding an AST element in the Existing Code with the specified target markup, and then finding the corresponding element in the Emitted Code AST. (Element matching is by name, or in the case of methods, by name and argument types.) If a corresponding element is found, and it has the specified 'source' markup, then the AST attribute is copied from Emitted to Existing.
Step 4 - push
- JMerges traverses the Emitted Code AST, looking for elements that are not in the Existing Code AST. (Again, matching is code by name, or method name plus method argument type). When an element is found in the Emitted Code but not the Existing Code, it is copied to the Existing Code.
- Note that no 'markup' is required for the Push phase. Also, there is no ability to specify 'push' rules to control the Push phase.
Step 5 - sweep
- JMerge traverse 'sweep' rules specified in the JMerge rules file. Each Sweep rule specified an AST Object type and a markup. For example, EMF has a JMerge sweep rule that matches class members with a 'gen' markup.
- For each sweep rule, JMerge seaches the Existing Code AST for Java elements that match the rule, and that do not have a corresponding element in the Emitted Code AST. If this case, the Java element is removed from the Existing Code AST.
Step 6 - write
Once JMerge is finished, the updated Existing Code AST is written to back to Java class file.
Some interesting consequences of JMerge
- A change in name of a method or field is equivalent to a delete of the old element, and an add of a new name.
- JET FAQ What is JMerge?
- JET FAQ How do I use JMerge to manage user specific code?
- JET FAQ How do I write custom JMerge rules?
Back to the M2T-JET-FAQ