Wiki

Clone wiki

jackpot30 / RulesLanguageAdditionalDocs

Rules Language Additional Docs

This is contributed documentation that may be moved to the main doc pages.

See the jackpot30 source for more examples.

Conditions

instanceof

   $1.isDirectory() :: $1 instanceof java.io.File
=> !$1.isFile()
;;

'negative instance of':
   $1+$2 :: !$1 instanceof int && !$2 instanceof int
=> $2+$1
;;

otherwise

   assert $cond;
=> assert $left != $right; :: matchesWithBind($cond, "$left == $right")
=> assert $left == $right; :: matchesWithBind($cond, "$left != $right")
=> assert !$cond           :: otherwise
;;

inClass(String... className)

Tests whether the current occurrences is enclosed (directly or indirectly) by any of the specified classes.

NEEDS EXAMPLE

inPackage(String... packageName)

Tests whether the current occurrences is in any of the given packages.

NEEDS EXAMPLE

sourceVersionGE(SourceVersion source)

   'Convert to Enhanced For':
   for(int $i = 0; $i < $array.length; $i++) {
       $T $var = ($T) $array[$i];
       $stmts$;
   } ::    !referencedIn($i, $stmts$)
        && sourceVersionGE(SourceVersion.RELEASE_5)
=> for($T $var : $array) {
       $stmts$;
   }
;;

hasModifier(Variable variable, Modifier modifier)

   'Double checked locking':
   if ($var == null) {
      synchronized ($lock) {
          if ($var == null) {
              $s2$;
          }
      }
   } :: !hasModifier($var, Modifier.VOLATILE)
=> synchronized ($lock) {
      if ($var == null) {
          $s2$;
      }
   }
;;

elementKindMatches(Variable variable, ElementKind... kind)

'Synchronizing on non-final field':
synchronized($var) {
    $stmts$;
} ::    !hasModifier($var, Modifier.FINAL)
     && elementKindMatches($var, ElementKind.FIELD)
;;

isNullLiteral(Variable var)

   'Wrong string comparison':
   $left == $right ::    $left instanceof java.lang.String
                      && $right instanceof java.lang.String
                      && !isNullLiteral($left)
                      && !isNullLiteral($right)
=> $left == null ? $right == null : $left.equals($right)
=> $left.equals($right)
;;

parentMatches(String pattern)

   $1 = new $2() :: !parentMatches("$_;")
=> $1 = $2.create()
;;

matchesAny(Variable var, String... patterns)

   new String($orig) ::    $orig instanceof String
                        && !matchesAny($orig,
                                       "$o.substring($s)",
                                       "$o.substring($s, $e)")
=> $orig
;;

matches(String pattern) deprecated

matches(pattern) is equivelent to matchesAny($_, pattern).

matchesWithBind(Variable var, String pattern)

   return $expr;
=> return $o != $t; :: matchesWithBind($expr, "$o == $t")
=> return $t == $o; :: matchesWithBind($expr, "$t != $o")
;;

containsAny(Variable var, String... patterns)

NEEDS EXAMPLE

referencedIn(Variable variable, Variable in)

   for(int $i = 0; $i < $array.length; $i++) {
       $T $var = $array[$i];
       $stmts$;
   } :: !referencedIn($i, $stmts$)
=> for($T $var : $array) {
       $stmts$;
   }
;;

Custom Import

<?
    import java.util.LinkedList;
    import java.util.ArrayList;
?>

   new LinkedList()
=> new ArrayList()
;;

   LinkedList $0;
=> ArrayList $0;
;;

Custom Conditions

<?
    import java.util.HashSet;
?>

   $opt ::    $opt instanceof com.whatever.Option
           && matchName($opt)
=>
   $optNew :: changeVariableName($opt, $optNew)
;;

<?
    public boolean matchName(Variable v) {
        return names.contains(context.name(v));
    }

    public boolean changeVariableName(Variable v, Variable target) {
        String name = context.name(v);
        context.createRenamed(v, target, name + "Renamed");
        return true;
    }

    final static HashSet<String> names = new HashSet<String>();
    static {
        names.add("p_bs");
        names.add("p_cb");
    }
?>

Options

Options modify or augment the behavior. The error/warning options allow to specify errors/warnings that are shown in the refactoring UI as appropriate. suppress-warnings allows to add @SuppressWarnings keys.

Empty "fix" normally means "remove $_ from its parent tree", but this is suppressed when an error/warning is present (because the hint may just want to show a warning to the user, not necessarily change the code). "remove-from-parent" forces the "remote $_ from its parent" even if errors/warnings are present. The intent here is to default to the more common cases, but allow to overrule the default.

There is also an option that requests that the dependencies of the current "module" are updated ("ensure-dependency") - typically that a new dependency is added. In many cases, the dependencies are updated automatically. This works reasonably for NetBeans module projects only.

Generally, the options are meant to be used by the script writer, but (I hope) are mostly useful for fine-tuning the behavior.

<!error="message">
remove-from-parent

   int i
=> /*remove-from-parent*/
;;
   float f
=> <!error="err">
;;
   double d
=> <!error="err",remove-from-parent=true>
;;

<!suppress-warnings=xxx>"

   $1.isDirectory <!suppress-warnings=isDirectory>
        :: $1 instanceof java.io.File
;; 

Other Examples

   $modifiers$ java.lang.String $name = $initializer;
=> $modifiers$ java.lang.CharSequence $name = $initializer;
;;

Updated