Clone wiki

jackpot30 / RulesLanguage

Rules Language

Basic Structure

The rules file consists of any number of transformation rules. The rule is defined as follows:

=> <fix-pattern>
=> <fix-pattern>

Each occurrence of <pattern> in the source code can be rewritten to one of the <fix-pattern>s. For example, the following transformation rule:

   $1 == null                                                                 
=> null == $1                                                                 

will rewrite the following code:

if (a == null) {
   System.err.println("a is null");


if (null == a) {
    System.err.println("a is null");

Note: $1$ is a variable, explained below.

Note: batch refactoring will typically use only the first applicable fix patterns of each applicable rule.


The pattern is a Java expression, statement or several statements. All references to classes in the pattern need to be resolvable, i.e. either fully qualified names need to be used, or the custom import section must be used (see Custom Imports).

TODO: equivalence - static elements are checked only against themselves, blocks with one statement considered equivalent to single statement.

Note: variable declaration is a Java statement.


Variables start with the dollar sign ($). In the pattern, first occurrences of a variable is bound to the actual sub-tree that appears in the code. Second and following occurrences of the variable the actual sub-tree is verified against the subtree bound to the variable. The pattern occurs in the text only if the actual sub-tree matches the sub-tree bound to the variable. In the fix pattern, all occurrences of the variables are replaced with the tree(s) bound to the respective variables.

The forms of the variables are:

any expression
any statement
any number of sub-trees (except statements - see next definition)
any number of statements
for patterns undefined, for fixes and conditions automatically bound to the current matched region
reserved -- do not use


Both the search and fix patterns may specify additional conditions. These conditions are specified after ::. Currently, the conditions have the following limitations:

   $1.isDirectory() :: $1 instanceof
=> !$1.isFile()

will rewrite the following code: testFile = new"/tmp");
if (testFile.isDirectory()) {
    System.err.println("/tmp is a directory");

to: testFile = new"/tmp");
if (!testFile.isFile()) {
    System.err.println("/tmp is a directory");

Display Names and Localization

Custom Conditions

Custom Import