20 January 2011

Tags: asm ast groovy intellij java transform

I’m releasing a new version of my ASM plugin for IntelliJ IDEA tonight, as well as a new version of the Groovy @Bytecode AST Transformation. Both are worth an upgrade as they greatly improve your experience :

ASM plugin for IntelliJ IDEA

The new version of the plugin provides several improvements :

  • Ability to show the differences between two versions of the bytecode

  • Configuration of output verbosity : skip frames, skip code, skip debug and expand frames

  • Support for showing bytecode of test classes

  • A new Groovy tab which displays Groovified code for the @Bytecode AST Transformation

  • Support for two types of Groovy code : legacy and Groovified

The last two items are directly related to the upgrade of the Groovy AST bytecode transformation, and will make integration of ASM bytecode into Groovy even easier !

Improved syntax for the @Bytecode AST Transformation

The new release of the transformation adds support for a Groovier syntax, mostly contributed by Guillaume Laforge. Basically, the AST Transformation now supports different syntaxes that you can mix :

  • a legacy syntax which is as close as possible of the output of tools like javap or the ASM plugin for Eclipse/IntelliJ

  • a Groovified syntax which makes it really easy to embed bytecode into Groovy : just copy and paste !

if you use the IntelliJ IDEA ASM plugin, you wont need to modify the generated bytecode to make it work with the @Bytecode transformation :

First, on the class you want to show the bytecode for, right click on the editor and choose ``Show bytecode outline'' : image

The new plugin includes a third tab which shows generated Groovy code. Select the 3rd tab :

You’ll notice that the syntax here is the legacy syntax, as close as possible to the javap output. Now, click on the settings tab and choose Groovified code style :
image  image

Right click on the editor to show bytecode again. The Groovified tab will now use the brand new syntax. You can click on the ``Show differences'' button to highlight the differences :

I definitely wanted to keep the two syntaxes as both have great interest. Here are the differences :

  • Labels

    • Legacy syntax : l0

    • Groovified syntax : anyLabel:

    • The Groovified syntax uses regular Groovy labels, allowing you to use any label, not only the l[0-9]+ syntax

  • Goto jumps

    • Legacy syntax : _goto l15

    • Groovified syntax : go to: myLabel

    • The underscore is replaced with a Groovier go to: syntax

  • instanceof checks

    • Legacy syntax : _instanceof 'java/lang/String'

    • Groovified syntax : instance of: String

    • Just like the goto variation, but allows class literals to be specified directly, not only string literals

  • Fields access

    • Legacy syntax : putfield 'com/lingway/test/MaClasse.valeur','I'

    • Groovified syntax : putfield MaClasse.valeur >> int

    • get/put (static) field instructions support direct class literals. Field type is specified by the right hand side of the expression, after the right shift operator

  • Methods

    • Legacy syntax : invokevirtual 'java/lang/StringBuilder.append','(Ljava/lang/String;)Ljava/lang/StringBuilder;'

    • Groovified syntax : invokevirtual StringBuilder.append(String) >> StringBuilder

    • method instructions support direct class literals. Field type is specified by the right hand side of the expression, after the right shift operator

  • `New' operator

    • Legacy syntax : _new 'java/lang/String'

    • Groovified syntax : newobject String

    • A newobject keyword, supporting the class directly, not as a string literal

  • Arrays

    • Legacy syntax : newarray T_INT

    • Groovified syntax : newarray int

    • Supports class literals as well as primitive types

  • Multidimensional arrays

    • Legacy syntax : multianewarray '[[Ljava/lang/Object;',2

    • Groovified syntax : multianewarray Object[][],2

    • Supports classes directly, as well as primitive types

  • Type casting

    • Legacy syntax : checkcast 'java/lang/String'

    • Groovified syntax : checkcast String

    • Supports class literals

  • Exceptions

    • Legacy syntax : trycatchblock l0,l1,l2,'java/lang/Throwable'

    • Groovified syntax : trycatchblock l0,l1,l2,Throwable

    • Supports class literals


Plugin for IDEA

The plugin for IntelliJ IDEA can be downloaded directly from the plugin manager or from this link.

Groovy @Bytecode AST Transformation