uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

AST変換の途中結果をGroovyソースに戻してみよう(ファイルで)

Groovy AST Browser Improved!の記事に書いたように、Groovy 1.8のGroovy ConsoleはAST変換の過程を見ることができるのです。

では、ファイルでスクリプトのコードが(Groovy Consoleからコピペせずに)欲しいときはどうすれば良いかというと、以下のようにします。

groovy -e 'println(new groovy.inspect.swingui.AstNodeToScriptAdapter().compileToScript("1+1", 9))'

すると以下が標準出力に表示されます。

return 1 + 1
public class script1309421611172 extends groovy.lang.Script { 

    private static org.codehaus.groovy.reflection.ClassInfo $staticClassInfo 
    public static transient boolean __$stMC 
    public static long __timeStamp 
    public static long __timeStamp__239_neverHappen1309421611217 

    public script1309421611172() {
    }
    public script1309421611172(groovy.lang.Binding context) {
        super.setBinding(context)
    }

    public static void main(java.lang.String[] args) {
        org.codehaus.groovy.runtime.InvokerHelper.runScript(script1309421611172, args)
    }

    public java.lang.Object run() {
        return 1 + 1
    }

 :
 以下略

# 1行目についてるreturn 1+1はコンパイル元ソースらしいが、何でなんだぜ?
compileToScript()の第一引数はスクリプト文字列で、

groovy -e 'println(new groovy.inspect.swingui.AstNodeToScriptAdapter().compileToScript(new File(args[0]).text, 9))' ~/a.groovy 

とかすればスクリプトをファイルからも読み込めます。第二引数はコンパイルのフェイズをあらわす整数値で、Groovy Consoleでも指定するものですが、整数値で指定する必要があって、その値は、Phases.javaによると

    public static final int INITIALIZATION        = 1;   // Opening of files and such
    public static final int PARSING               = 2;   // Lexing, parsing, and AST building
    public static final int CONVERSION            = 3;   // CST to AST conversion
    public static final int SEMANTIC_ANALYSIS     = 4;   // AST semantic analysis and elucidation
    public static final int CANONICALIZATION      = 5;   // AST completion
    public static final int INSTRUCTION_SELECTION = 6;   // Class generation, phase 1
    public static final int CLASS_GENERATION      = 7;   // Class generation, phase 2
    public static final int OUTPUT                = 8;   // Output of class to disk
    public static final int FINALIZATION          = 9;   // Cleanup
    public static final int ALL                   = 9;   // Synonym for full compilation

こういう対応があります。詳しくはまた別途。

ちなみにですが、ほんとは、AstNodeToScriptAdapterには立派なmainがあるのですが、ちょっとしたバグがあったので呼びだせませんでした。報告しておいたので、もし対応されれば、将来的には、

java -cp /tool/groovy-1.8.0/target/install/embeddable/groovy-all-1.8.0.jar groovy.inspect.swingui.AstNodeToScriptAdapter a.groovy 7

とか

groovy -e 'groovy.inspect.swingui.AstNodeToScriptAdapter.main(args)' ~/a.groovy   3

のように呼び出せるようになるのではないかと思います。

追伸、Amazonの「プログラミングGroovy」は書影が入りました。

プログラミングGROOVY
プログラミングGROOVY
posted with amazlet at 11.06.30
関谷 和愛 上原 潤二 須江 信洋 中野 靖治
技術評論社
売り上げランキング: 80691


発売先行販売のイベントもあるようですね〜。