2025/04/27 17:42 Macros in the Dart Programming Language

ロボ子、Dartにマクロが導入されるって話、知ってるかのじゃ?コンパイル時にプログラムを修正するコードのことじゃ。

マクロですか、博士。それはすごいですね!具体的にはどのようなことができるようになるのでしょう?

マクロは、適用された宣言を調査して、コードを生成したり修正したりできるのじゃ。既存のコード生成ツールみたいなものだと思えば良いぞ。

なるほど。マクロはどのように定義されるのですか?

ユーザー定義のDartクラスとして実装されて、組み込みマクロインターフェースを実装するのじゃ。個別の「マクロ言語」ではなく、普通のDartコードで書けるのがミソじゃな。

通常のDartコードで書けるのは便利ですね。マクロはプログラムの構造をどのように調査するのですか?

イントロスペクションという機能を使うのじゃ。マクロは、クラスの名前やスーパークラス、メンバーなどを調査できるぞ。

イントロスペクションですか。型が省略されている場合はどうなるのでしょう?

`OmittedTypeAnnotation`が使われるのじゃ。これは、型推論が必要な場合に、後続のフェーズで型を推論するために使われるぞ。

なるほど。マクロの適用順序はどのように決まるのですか?

基本的にはユーザーが制御できる場合とそうでない場合があるのじゃ。順序が重要な場合は、ユーザーが制御できるぞ。メンバーに適用されたマクロは、周囲の型に対するマクロよりも前に適用されるのじゃ。

マクロはフェーズで実行されるとのことですが、フェーズとは具体的に何をするものなのでしょう?

フェーズは3つあるのじゃ。型、宣言、定義のフェーズじゃ。早いフェーズは新しい型と宣言を追加して、遅いフェーズはそれらを埋めるのじゃ。

各フェーズでマクロがアクセスできるのは、すでに完了しているプログラムの部分だけなのですね。

その通りじゃ。マクロは、`macro`キーワードで始まる特殊な型のクラスとして宣言されるぞ。すべてのマクロコンストラクタはconstとしてマークする必要があるのじゃ。

マクロは、メタデータアノテーションを読み取る必要があるとのことですが、どのように行うのですか?

アノテーション可能なすべての宣言には、`Iterable<MetadataAnnotation> get metadata`ゲッターがあるのじゃ。そして、すべての`MetadataAnnotation`オブジェクトには、アノテーションを`Code`オブジェクトとして提供する`Code get code`ゲッターがあるぞ。

マクロは、新しいコードを宣言にアタッチすることでコードを生成するのですね。

そうじゃ。マクロに与えられたビルダーオブジェクトのメソッドを呼び出すのじゃ。コード自体は、特殊な`Code`クラス(またはそのサブクラスの1つ)のインスタンスじゃ。

マクロは、別のマクロのコードをインスタンス化して直接実行することもできるのですね。

その通りじゃ。マクロは、マクロアプリケーションを含むコードを生成できるぞ。ただし、マクロが定義されているライブラリから、マクロが使用されているライブラリへのインポートパスがあってはならないのじゃ。

マクロは、コンパイラ内でコンパイル時に直接実行されるのですね。セキュリティ面は大丈夫なのでしょうか?

心配ないぞ。マクロは、不適切に(または悪意を持って)記述されたマクロが引き起こす可能性のある問題を最小限に抑えるサンドボックスで実行されるのじゃ。コアライブラリへのアクセスも制限されるぞ。

なるほど。マクロはリソース(ファイルなど)をロードすることもできるのですね。

そうじゃ。リソースは、`Resource`を介して読み取られるぞ。読み取られたリソースは、プログラムへのソース入力として扱われるのじゃ。

Dartのマクロ、奥が深いですね!

じゃろ?Dartにマクロが導入されたら、メタプログラミングが捗ること間違いなしじゃ!

私も早くマクロを使いこなせるようになりたいです!

そうじゃな。ところでロボ子、マクロって、コンパイラにとってはまるで化粧みたいなものじゃな。ちょっと盛るだけで、あら不思議、別の顔になるんじゃから!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。