Wednesday, October 24, 2007

Beyond simple refactorings and IDE portability of projects

I recently did a short presentation at work on some of the java pattern based search and replace features that can be found in IntelliJ (SSR) and Netbeans (jackpot). The nice thing about these two features is that they let you specify a custom refactoring without worrying about whitespace or lines and you can match against more than just the raw text (i.e. - match 'where the base class is xxxx' or 'where the expression evaluates to type String' or even where this statement was preceeded by a statement that created a variable.......etc..').

In relatively short order, I was able to whip up some expressions to do custom refactorings across an entire codebase. Here are some examples:
  • Replace two line declare and return pattern with one-line return
    • Netbeans jackpot: { $stmts$; $type $value = $expr; return $value; } => { $stmts$; return $expr; }
  • Move common trailing statements in if/else blocks outside the if
    • Intellij SSR:
      • Search pattern:
        if($boolean_expression$) {
        $trueStatements$;
        $commonstmts$;
        }
        else {
        $falseStatements$;
        $commonstmts$;
        }
      • Replace pattern:
        if($boolean_expression$) {
        $trueStatements$;
        }
        else {
        $falseStatements$
        }
        $commonstmts$;

  • Improve the expressiveness of code by quickly introducing helper's for certain patterns
    • Netbeans jackpot: {$type $var = $expr; $var.add($valueExpr); $remainingStmts$;} => {$type $var = Arrays.asList($valueExpr); $remainingStmts$;};

The possibilities of what you can search and replace with these pattern/ast based features is really impressive. As I showed some examples, my colleagues were continuously coming up with additional ideas for things we could do with this.

The Intellij SSR is a bit more polished but the jackpot rules language seems like a more flexible idea. Jackpot also lets you access a Java API to do transformations on code, though I think I hold off on learning that until I need to do a refactoring against a code base large enough to justify that time investment.

Intellij and Netbeans are using their AST (Abstract Syntax Tree) to provide this useful
functionality. I can only hope that Eclipse will catch up soon. In the meantime, one of the side-effects of the exercise was that it forced me to exercise some of the new maven integration capabilities of the latest IDE's. I've now got a fairly solid way to open a project in any of the 3 major IDE's (Eclipse, Netbeans, Intellij) without doing any special configuration. Here is the basic idea:
  1. Use a maven pom.xml to define project dependencies.
  2. To Use Eclipse: use the mvn eclipse:eclipse plugin to generate the eclipse project files.
  3. To Use Netbeans: Point Netbeans at the maven pom.
  4. To Use Intellij: Point Intellij at the maven pom.
It's nice to finally have a simple way to open any project in any of the leading IDE's without any manual configuration.

Tuesday, October 02, 2007

links: presentation style

http://www.presentationzen.com/presentationzen/