Open3
【Dart】コードジェネレーションの作法
参考資料
作成ステップ
- 3つのディレクトリを作成
- annotations (package)
- example (project)
- generators (package)
- annotationsディレクトリにannotation定義のファイルを作成する
- packageのエントリーポイントとなるファイルに定義したannotationクラスをexportする
- generatorsディレクトリに
build.yaml
を追加 -
generators/pubspec.yaml
のdependencies
にbuild
、source_gen
パッケージをimport - 自作の
annotations
パッケージもpath指定して作成 -
pubspec.yaml
にpublish_to: none
を記述 -
generators/pubspec.yaml
のdev_dependencies
にbuild_runner
パッケージをimport -
build.yaml
に設定を記述する -
generators/lib/src
にmodel_visitor.dart
を作成 - その中に
SimpleElementVisitor
を継承したModelVisitor
クラスを作成。source_gen
が依存するanalyzer
パッケージ内に存在している。 -
visitConstructorElement
、visitFieldElement
メソッドをoverride
する。 - 同ディレクトリに
json_generator.dart
を作成 - その中に
GeneratorForAnnotation
クラスを継承したJsonGenerator
クラスを定義。(GeneratorForAnnotation
はsource_gen
に定義されたクラス) -
JsonGenerator
クラスのgenerateForAnnotatedElement
メソッドをoverrideする。 -
JsonGenerator
クラスの中で生成する文字列を記載する -
generators/lib/generators.dart
にSharedPartBuilder
クラスを返すメソッドを記述する
主要な登場人物
- Builder
- Annotation
- Generator
- Visitor
自動生成の流れ
- build_runnerによってBuilderが実行される
- アノテーションがついているElementを探索する
- 対象Elementに対してGeneratorクラスのGenerateForAnnotatedElementが実行される
- element.visitChildrenを実行して、Element内の値を格納するVisitorクラスに値を格納する
言い換えると、
Builder:生成対象物の探索者
Annotation: 生成対象物を特定する目印
Generator: 生成処理プログラム
Visitor: Elementを格納する箱
BuilderがAnnotationが付いた生成対象を探して、Generatorを実行し、GeneratorはVisitorを使ってElementを取り扱いしやすいデータに加工して、コード生成に使う。
あくまでも主役は Builder
とGenerator
。