Scalaで書いたコードを逆コンパイルしてみる

はじめに

 逆コンパイラがあったら何でも逆コンパイルしてみたくなるものです。
 というわけで、Scalaで書いたコードを逆コンパイル

環境

コンパイルしてみたソース

 以下のようなソースをコンパイルしました。

  • classではなくオブジェクトである
  • 関数を引数にとるタイプの関数を使っている。
  • 省略記法を使っている。

 具体的には、プログラミングScala(初版第1刷)のP16〜P17のコードです。
 以下にコードを示します。

package IntoroducingScala

object Upper {
    def main(args: Array[String]) = {
        args.map(_.toUpperCase()).foreach(printf("%s",_))
        println("")
    }
}

コンパイル結果

コンパイルすると4つのファイルが得られますので、全て逆コンパイルしてみました。
コンパイルして得られたファイルは以下の4つです。

  • Upper.class
  • Upper$.class
  • Upper$$anonfun$main$1.class
  • Upper$$anonfun$main$2.class

 変換結果ですが、綺麗に逆コンパイルできないコードがあるようで、一部不思議なことになっています。
 Upper$.classのstatic初期化ブロックは結構不思議。

 そういった謎はありつつも、以下については「なるほどー」という感じ。

  • Javaとの互換性をもちつつ、objectで宣言したものはsingletonにする方法。
  • 関数を引数にとるタイプの関数の実装方法。

Upper.class

package IntoroducingScala;

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\0015:Q!\001\002\t\006\025\tQ!\0269qKJT\021aA\001\022\023:$xN]8ek\016LgnZ*dC2\f7\001\001\t\003\r\035i\021A\001\004\t\021\t!\t\021!E\003\023\t)Q\013\0359feN\031qA\003\n\021\005-\001R\"\001\007\013\0055q\021\001\0027b]\036T\021aD\001\005U\0064\030-\003\002\022\031\t1qJ\0316fGR\004\"a\005\f\016\003QQ\021!F\001\006g\016\fG.Y\005\003/Q\0211bU2bY\006|%M[3di\")\021d\002C\0015\0051A(\0338jiz\"\022!\002\005\0069\035!\t!H\001\005[\006Lg\016\006\002\037CA\0211cH\005\003AQ\021A!\0268ji\")!e\007a\001G\005!\021M]4t!\r\031BEJ\005\003KQ\021Q!\021:sCf\004\"a\n\026\017\005MA\023BA\025\025\003\031\001&/\0323fM&\0211\006\f\002\007'R\024\030N\\4\013\005%\"\002")
public final class Upper
{
  public static final void main(String[] paramArrayOfString)
  {
    Upper..MODULE$.main(paramArrayOfString);
  }
}

Upper$.class(出力結果について一部改行位置を変更しています)

package IntoroducingScala;

import java.io.Serializable;
import scala.Array.;
import scala.Predef.;
import scala.ScalaObject;
import scala.collection.IndexedSeqOptimized;
import scala.collection.TraversableLike;
import scala.reflect.ClassManifest.;
import scala.runtime.AbstractFunction1;

public final class Upper$
  implements ScalaObject
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void main(String[] args)
  {
    Predef..MODULE$.refArrayOps((Object[])Predef..MODULE$.refArrayOps((Object[])args).map(
            new AbstractFunction1() {
                public static final long serialVersionUID = 0L;

                public final String apply(String paramString) {
                    return paramString.toUpperCase();
                }
    }
    , Array..MODULE$.canBuildFrom(ClassManifest..MODULE$.classType(String.class)))).foreach(
            new AbstractFunction1() {
                public static final long serialVersionUID = 0L;

                public final void apply(String paramString) {
                    Predef..MODULE$.printf("%s", Predef..MODULE$.genericWrapArray(new Object[] { paramString }));
                }
    });
  }

  private Upper$()
  {
    MODULE$ = this;
  }
}

Upper$$anonfun$main$1.class

package IntoroducingScala;

import java.io.Serializable;
import scala.runtime.AbstractFunction1;

public final class Upper$$anonfun$main$1 extends AbstractFunction1
  implements Serializable
{
  public static final long serialVersionUID;

  public final String apply(String)
  {
  }
}

Upper$$anonfun$main$2.class

package IntoroducingScala;

import java.io.Serializable;
import scala.runtime.AbstractFunction1;

public final class Upper$$anonfun$main$2 extends AbstractFunction1
  implements Serializable
{
  public static final long serialVersionUID;

  public final void apply(String)
  {
  }
}

さいごに

 Eclipse使いにとってScala IDEはそれなりに便利ですが、常用している環境とは別の環境に入れた方がいいかもしれません。
 なぜか「Eclipseについて」のウインドウが表示されなくなってしまいました。
 なにかのプラグインとの相性問題だとは思うのですが、謎です。