Skip to content

コンパイラ(onionc)

onionc コマンドは、OnionのソースファイルをJVMの .class ファイルにコンパイルします。

使い方

onionc [オプション] ソースファイル...

オプション

-classpath <classpath>

コンパイル時のクラスパスを設定します。外部のJavaライブラリや、他のコンパイル済みOnionクラスを参照する場合に使います。

onionc -classpath lib/mylib.jar:lib/other.jar MyProgram.on

-encoding <encoding>

ソースファイルの文字エンコーディングを指定します。未指定時はプラットフォーム依存のデフォルトが使われます。

onionc -encoding UTF-8 MyProgram.on

-d <出力ディレクトリ>

生成されたクラスファイルの出力先を設定します。未指定時はカレントディレクトリに出力されます。

onionc -d build/classes MyProgram.on

クラスファイルはモジュール名に応じて整理されます。 - Unix系: org/onion_lang/MyClass.class - Windows: org\onion_lang\MyClass.class

-maxErrorReports <count>

報告するコンパイルエラーの最大数を制限します。大量のエラーがある大規模プロジェクトで便利です。

onionc -maxErrorReports 10 MyProgram.on

--dump-ast

構文解析後のASTを標準エラー出力に出力します。構文やパースのデバッグに便利です。

onionc --dump-ast MyProgram.on

--dump-typed-ast

型付きASTの概要(クラス、フィールド、メソッド)を標準エラー出力に出力します。

onionc --dump-typed-ast MyProgram.on

--profile-compile

各フェーズの所要時間、ソース数、クラスパスサイズ、生成クラス数を含むコンパイルプロファイルを出力します。

onionc --profile-compile MyProgram.on

--profile-format <text|json>

コンパイルプロファイルの出力形式を選択します。

onionc --profile-compile --profile-format json MyProgram.on

--profile-output <target>

コンパイルプロファイルを stderrstdout、またはファイルパスに出力します。

onionc --profile-compile --profile-format json \
       --profile-output target/profile.json \
       MyProgram.on

--warn <off|on|error>

警告の扱いを制御します。error を指定すると警告をコンパイルエラーとして扱います。

onionc --warn error MyProgram.on

--Wno <codes>

特定の警告カテゴリをコードまたは名前で抑制します。

onionc --Wno W0001,unused-parameter MyProgram.on

基本的なコンパイル

1つのファイルをコンパイルします。

onionc Hello.on

これにより、カレントディレクトリに Hello.class が作成されます。

複数ファイルのコンパイル

複数のソースファイルを同時にコンパイルします。

onionc Person.on Employee.on Manager.on

出力ディレクトリの指定

出力を整理します。

onionc -d out/classes src/Main.on src/Utils.on

クラスファイルは out/classes/ に出力されます。

クラスパス付きのコンパイル

外部ライブラリを参照します。

onionc -classpath lib/gson-2.8.jar:lib/commons-lang.jar \
       src/JsonParser.on

完全な例

onionc \
  -d build/classes \
  -classpath lib/external.jar \
  -encoding UTF-8 \
  -maxErrorReports 20 \
  src/*.on

コンパイル後の実行

コンパイル後は、Javaで実行します。

# コンパイル
onionc -d build Main.on

# Javaで実行
java -cp build Main

またはJARで実行します。

# コンパイル
onionc -d build Main.on Helper.on

# JARの作成
jar cvfe program.jar Main -C build .

# JARの実行
java -jar program.jar

モジュール構成

OnionはJavaと同様のモジュール名(パッケージ)を使用します。

MyClass.on:

module com.example.myapp

class MyClass {
  public:
    static def main(args :String[]): void {
      println("Hello")
    }
}

コンパイル:

onionc -d build MyClass.on

出力:

build/com/example/myapp/MyClass.class

実行:

java -cp build com.example.myapp.MyClass

コンパイルエラー

よくあるエラー

型の不一致:

Error: Type mismatch
  Expected: Int
  Found: String
  at MyProgram.on:10

未定義の変数:

Error: Undefined variable 'count'
  at MyProgram.on:15

メソッドが見つからない:

Error: Method 'getValue()' not found in class Person
  at MyProgram.on:23

インクリメンタルコンパイル

onionc は指定したファイルを毎回すべてコンパイルします。大規模プロジェクトでは以下を検討してください。

  1. 変更されたファイルのみをコンパイルする
  2. ビルドツールを使う(Make、SBT、Gradleなど)
  3. コードをモジュールに分割する

ビルドツールとの統合

Makefileの例

SRC_DIR = src
OUT_DIR = build/classes
SOURCES = $(wildcard $(SRC_DIR)/*.on)

all: compile

compile:
    mkdir -p $(OUT_DIR)
    onionc -d $(OUT_DIR) $(SOURCES)

clean:
    rm -rf $(OUT_DIR)

run: compile
    java -cp $(OUT_DIR) Main

シェルスクリプトの例

#!/bin/bash

SRC_DIR="src"
OUT_DIR="build/classes"
CLASSPATH="lib/*"

mkdir -p "$OUT_DIR"

echo "Compiling Onion sources..."
onionc -d "$OUT_DIR" -classpath "$CLASSPATH" "$SRC_DIR"/*.on

if [ $? -eq 0 ]; then
    echo "Compilation successful"
    echo "Running program..."
    java -cp "$OUT_DIR:$CLASSPATH" Main
else
    echo "Compilation failed"
    exit 1
fi

コンパイラ出力

成功時のコンパイル

通常、成功時は何も出力されません。

$ onionc Hello.on
$ ls
Hello.class  Hello.on

コンパイルエラー

エラーは標準エラー出力に書き出されます。

$ onionc BadProgram.on
Error: Type mismatch at BadProgram.on:5
Error: Undefined variable at BadProgram.on:10
Compilation failed with 2 errors

分割コンパイルとリンク

Onion のユニットは独立してコンパイルでき、クラスパスを介してロード時にリンクされます ——すべてのソースを 1 回の onionc 呼び出しに含める必要はありません。ライブラリを先に コンパイルし、生成された .class に対してクライアントをコンパイルします。

# ライブラリを先にコンパイル
onionc -d out/lib greeter/Greeter.on

# ライブラリ出力をクラスパスに置いてクライアントをコンパイル
onionc -d out/app -classpath out/lib app/Main.on

# リンクは JVM の仕事——全出力ディレクトリ(と onion.jar)をクラスパスに
java -cp onion.jar:out/lib:out/app Main   # => Hello, Onion

クラス・インターフェース・レコード・enum・継承・静的メンバ、そしてジェネリック型が ユニット境界を越えられます。onionc.class に JVM ジェネリックシグネチャを書き込むため、 ジェネリック型は型パラメータを保持します(別ユニットの new Container[String](x) が解決)。

ユニットは依存順にコンパイルします(参照先を先にコンパイル)。インクリメンタルビルドの キャッシュは無いため、ユニットの公開 API が変わったら依存側を再コンパイルしてください。

次のステップ