最初の部分では、コード生成が必要な理由を見つけ、Dartでコード生成に必要なツールをリストしました。 第2部では、Dartで注釈を作成および使用する方法、およびsource_genとbuild_runnerを使用してコード生成を開始する方法を学習します。

Dartアノテーション
注釈は、コードに追加できる構文メタデータです。 言い換えると、コードのコンポーネント(クラスやメソッドなど)に追加情報を追加する機会です。 注釈はDartコードで広く使用されています。 @required
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用して名前付きパラメーターが必要であることを示し、注釈付きパラメーターが指定されていない場合、コードはコンパイルされません。 また、 @override
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用して、親クラスで定義されたAPI @override
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    クラスで実装されていることを示します。 注釈は常に@
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    記号で始まります。 
独自の注釈を作成する方法は?
 コードにメタデータを追加するという考えは少しエキゾチックで複雑に聞こえますが、アノテーションはDart言語で最も単純なものの1つです。 以前に注釈が単に追加情報を運ぶと言われました。 これらはPODO (Plain Old Dart Objects)に似ています。 また、 const
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    コンストラクターが定義されている場合、どのクラスも注釈として機能します 。 
 class { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); } @Todo('hello first annotation', todoUrl: 'https://www.google.com') class HelloAnnotations {}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       ご覧のとおり、注釈は非常に簡単です。 そして主なことは、これらの注釈を使用して何をするかです。 これはsource_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    とbuild_runner
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ます。 
build_runnerの使用方法は?
  build_runner
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は、Dartコードを使用してファイルを生成するのに役立つDartパッケージです。  build.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用してBuilder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルを構成します。 設定されると、 Builder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    はすべてのbuild
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    コマンドで、またはファイルが変更されたときに呼び出されます。 また、変更されたコードや特定の条件を満たすコードを解析する機会もあります。 
Dartコードを理解するためのsource_gen
 ある意味では、 build_runner
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は「 いつコードを生成する必要があるのか」という質問に答えるメカニズムです。 同時に、 source_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は「 どのコードを生成する必要がありますか?」という質問に答えます。  source_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は、 source_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    機能するBuilderを作成するためのフレームワークを提供します。 また、 source_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は、コードを解析および生成するための便利なAPIを提供します。 
すべてをまとめる:TODOレポート
この記事の残りの部分では、 todo_reporter.dartプロジェクトを逆アセンブルします 。これは、 こちらにあります 。
コード生成を使用するすべてのプロジェクトが従う未記述のルールがあります。 アノテーションを含む パッケージと、これらのアノテーションを使用するジェネレーター用の個別のパッケージを作成する必要があります。 Dart / Flutterでパッケージライブラリを作成する方法については、 こちらをご覧ください 。
 まず、 todo_reporter.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリを作成する必要があります。 このディレクトリ内に、注釈を含むtodo_reporter_generator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリ、注釈を処理するtodo_reporter_generator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリ、および作成されるライブラリの機能のデモを含むexample
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリを作成する必要があります。 
 明確にするために、サフィックス.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ルートディレクトリ名に追加され.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    います。 もちろん、これは必須ではありませんが、このルールに従って、このパッケージがどのDartプロジェクトでも使用できるという事実を正確に示したいと思います。 それどころか、このパッケージがFlutter( ozzie.flutterなど )専用であることを示したい場合は、別のサフィックスを使用します。 これは必ずしも必要ではありません。単なる命名規則であり、私はそれを順守しようとしています。 
シンプルなアノテーションパッケージtodo_reporterの作成
  todo_reporter
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    内にtodo_reporter.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を作成します。 これを行うには、 pubspec.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルとlib
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリを作成します。 
  pubspec.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    非常に簡単です。 
name: todo_reporter description: Keep track of all your TODOs. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: dev_dependencies: test: 1.3.4
 開発プロセスで使用されるtest
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    パッケージを除き、依存関係はありません。 
  lib
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリで、次を実行する必要があります。 
-   
todo_reporter.dart
ファイルを作成する必要があります。todo_reporter.dart
ファイルでは、export
を使用して、パブリックAPIを持つすべてのクラスが指定されます。 パッケージ内のクラスはimport 'package:todo_reporter/todo_reporter.dart';
を使用してimport 'package:todo_reporter/todo_reporter.dart';
できるため、これは良い習慣import 'package:todo_reporter/todo_reporter.dart';
。 ここでこのクラスを見ることができます 。 -   
lib
ディレクトリ内に、すべてのコード(パブリックおよび非パブリック)を含むsrc
ディレクトリを作成します。 
 この場合、追加する必要があるのは注釈だけです。 注釈付きのtodo.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルを作成しましょう。 
 class Todo { final String name; final String todoUrl; const Todo(this.name, {this.todoUrl}) : assert(name != null); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       注釈を付けるのに必要なことはそれだけです。 簡単だと言った。 しかし、それだけではありません。  test
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリに単体テストを追加しましょう。 
 import 'package:test/test.dart'; import 'package:todo_reporter/todo_reporter.dart'; void main() { group('Todo annotation', () { test('must have a non-null name', () { expect(() => Todo(null), throwsA(TypeMatcher<AssertionError>())); }); test('does not need to have a todoUrl', () { final todo = Todo('name'); expect(todo.todoUrl, null); }); test('if it is a given a todoUrl, it will be part of the model', () { final givenUrl = 'http://url.com'; final todo = Todo('name', todoUrl: givenUrl); expect(todo.todoUrl, givenUrl); }); }); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      これで注釈を作成することができます。 ここでコードを見つけることができます。 これでジェネレーターに行くことができます。
クールな仕事をする:todo_reporter_generator
 パッケージの作成方法がわかったので、 todo_reporter_generator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    パッケージを作成しましょう。 このパッケージ内には、 pubspec.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    およびbuild.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    とlib
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリが必要です。  lib
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリには、 src
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリとbuilder.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルがbuilder.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    です。  todo_reporter_generator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は、 dev_dependency
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    として他のプロジェクトに追加される個別のパッケージと見なされます。 これは、コード生成が開発段階でのみ必要であり、完成したアプリケーションに追加する必要がないためです。 
  pubspec.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    次のとおりです。 
name: todo_reporter_generator description: An annotation processor for @Todo annotations. version: 1.0.0 author: Jorge Coca <jcocaramos@gmail.com> homepage: https://github.com/jorgecoca/todo_reporter.dart environment: sdk: ">=2.0.0 <3.0.0" dependencies: build: '>=0.12.0 <2.0.0' source_gen: ^0.9.0 todo_reporter: path: ../todo_reporter/ dev_dependencies: build_test: ^0.10.0 build_runner: '>=0.9.0 <0.11.0' test: ^1.0.0
 ここでbuild.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    作成しましょう。 このファイルには、 Builderに必要な構成が含まれています。 詳細はこちらをご覧ください 。  build.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    次のとおりです。 
targets: $default: builders: todo_reporter_generator|todo_reporter: enabled: true builders: todo_reporter: target: ":todo_reporter_generator" import: "package:todo_reporter_generator/builder.dart" builder_factories: ["todoReporter"] build_extensions: {".dart": [".todo_reporter.g.part"]} auto_apply: dependents build_to: cache applies_builders: ["source_gen|combining_builder"]
  import
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    プロパティは、 Builder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を含むファイルを指し、 builder_factories
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    プロパティは、コードを生成するメソッドを指します。 
 これで、 lib
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリにbuilder.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルを作成できます。 
 import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter_generator/src/todo_reporter_generator.dart'; Builder todoReporter(BuilderOptions options) => SharedPartBuilder([TodoReporterGenerator()], 'todo_reporter');
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
        src
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリーのtodo_reporter_generator.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイル: 
 import 'dart:async'; import 'package:analyzer/dart/element/element.dart'; import 'package:build/src/builder/build_step.dart'; import 'package:source_gen/source_gen.dart'; import 'package:todo_reporter/todo_reporter.dart'; class TodoReporterGenerator extends GeneratorForAnnotation<Todo> { @override FutureOr<String> generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) { return "// Hey! Annotation found!"; } }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       ご覧のとおり、 builder.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルで、 Builder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    が作成するtodoReporter
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    メソッドを定義しています。  Builder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    は、 SharedPartBuilder
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用するTodoReporterGenerator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を使用して作成されます。 したがって、 build_runner
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    とsource_gen
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    一緒に機能します。 
  TodoReporterGenerator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    はGeneratorForAnnotation
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    サブクラスGeneratorForAnnotation
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     。そのため、 generateForAnnotatedElement
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    メソッドは、この注釈(この場合は@Todo
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     )がコードで見つかった場合にのみ実行されます。 
  generateForAnnotatedElement
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    メソッドは、生成されたコードを含む文字列を返します。  生成されたコードがコンパイルされない場合、ビルドフェーズ全体が失敗します。 これは、将来の間違いを避けるのに役立つため、非常に便利です。 
 したがって、各コード生成で、 todo_repoter_generator
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    はコメント付きのpart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ファイルを作成します// Hey! Annotation found!
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     // Hey! Annotation found!
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     次の記事では、注釈を処理する方法を学びます。 
すべてをまとめる:todo_reporterを使用する
 これで、 todo_reporter.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    を実演できます。 パッケージを使用する場合は、 example
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    プロジェクトを追加することをお勧めします。 そのため、他の開発者は、実際のプロジェクトでAPIを使用する方法を確認できます。 
 プロジェクトを作成し、必要な依存関係をpubspec.yaml
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    追加しましょう。 この例では、 example
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    ディレクトリ内にFlutterプロジェクトを作成し、依存関係を追加します。 
dependencies: flutter: sdk: flutter todo_reporter: path: ../todo_reporter/ dev_dependencies: build_runner: 1.0.0 flutter_test: sdk: flutter todo_reporter_generator: path: ../todo_reporter_generator/
 パッケージを受け取った後( flutter packages get
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     )アノテーションを使用できます: 
 import 'package:todo_reporter/todo_reporter.dart'; @Todo('Complete implementation of TestClass') class TestClass {}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      すべてが整ったので、ジェネレーターを実行します:
$ flutter packages pub run build_runner build
 コマンドが完了すると、プロジェクトに新しいファイルtodo.g.dart
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    表示されます。 次のものが含まれます。 
 // GENERATED CODE - DO NOT MODIFY BY HAND part of 'todo.dart'; // ***************************************************************** // TodoReporterGenerator // ******************************************************************** // Hey! Annotation found!
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       私たちは望んでいたものを達成しました! これで、コード内の各@Todo
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
    アノテーションに対して正しいDartファイルを生成できます。 必要な数だけ試して作成してください。 
次の記事で
これで、ファイルを生成するための正しい設定ができました。 次の記事では、生成されたコードが本当にクールなことを行えるように、注釈の使用方法を学習します。 実際、現在生成されているコードはあまり意味がありません。