原文:
公開: 2018年10月31日 - 7 分 読む
」では、コード生成の背景にある動機とは何かを紹介し、コンピュータが大変な作業を行うためのDartにおける最も重要なツールを列挙しました。この記事では、Dartアノテーションの作成方法と使用方法、そして使用して作業を開始する方法について説明します。
Dartのアノテーション
アノテーションは、Dart コードに追加できる構文メタデータの一形態です。言い換えれば、コードの任意のコンポーネントに追加情報を追加する方法です。アノテーションは、Dartのコードのいたるところで見かけることができます。@requiredを使用して、名前付きパラメータがオプションではないことを指定し、アノテーションされたフィールドが存在しない場合はコードがコンパイルされないようにしたり、@overrideを使用して、親クラスで指定されたAPIが子クラスで実装されていることを特定したりします。なぜアノテーションだとわかるのでしょうか?アノテーションを見つけるのは簡単です。
しかし、注釈はどのように作成されるのでしょうか?
クラス内に「メタデータ」を持つというアイデアは、非常にエキゾチックで複雑に聞こえますが、アノテーションは実際にはDartで最も単純なものの1つです。上の段落で、アノテーションは単に余分な情報を運ぶものだと述べました。データクラスのようなものです。定数コンストラクタさえあれば、どんなクラスでもアノテーションに変換できます。
class Todo {
final String name; final String todoUrl; final
final String todoUrl.Const Todo(this.name, {this.todoUrl} : assert(name !
const Todo(this.name, {this.todoUrl}) : assert(name != null);
}
@Todo('hello first annotation', todoUrl: 'https://..om')
class HelloAnnotations {}
ご覧のように、注釈はとてもシンプルです。重要なのは、アノテーションをどのように使うかです。アノテーションに含まれる情報と、その情報をどのように使うかが、アノテーションを特別なものにするのです。そこで、source_genとbuild_runnerが役に立ちます。
ビルドの使い方_runner
build_runnerは、Dart コードを使用してファイルを生成するのに役立つ Dart パッケージです。Builderファイルはbuild.yamlを介して設定されます。一度設定されると、ビルドがトリガーされるか、ファイルが変更されると、更新が受信され、変更されたコードや特定の標準に準拠したコードを解析できるようになります。
Dartのコードを理解するためのsource_gen
ある意味で、build_runner は、いつコードを生成する必要があるかという質問に答えるメカニズムであり、source_gen は、どのようなコードを生成する必要があるかという質問に対する答えであると考えることができます。source_gen は、build_runner が期待するものを構築するためのフレームワークを提供すると同時に、コードを解析して生成するためのユーザーフレンドリーな API を公開します。
すべてのピースをまとめる:TODOレポーター。
この記事の続きでは、このbuild_runnerあるtodo_reporter.dartというペット・プロジェクトで動作します。
これは、コード生成を使用するすべてのプロジェクトで見られる不文律です。アノテーション用のパッケージとジェネレータ用の別のパッケージを作成し、それらに値を追加します。Dart/Flutterでライブラリパッケージを作成するために必要な情報は、このリンクあります。
ルートフォルダの接尾辞を.dartにしているのは、わかりやすくするためです。これは必須ではありませんが、このパッケージがどのDartプロジェクトでも使えることを明確にするためです。逆に、ozzie.flutterようにFlutter専用のパッケージにしたい場合は、別のサフィックスを使います。これは強制ではなく、私が好きな命名規則です。
todo_reporterを作成する注釈付きパッケージは、最も単純なものでもあります。
name: todo_reporter
description: Keep track of all your TODOs.
version: 1.0.0
author: Jorge Coca <jcocaramos@gmail.com>
homepage: https://.//_.rt
environment:
sdk: ">=2.0.0 <3.0.0"
dependencies:
dev_dependencies:
test: 1.3.4
開発目的にのみ使用されるテストパッケージ以外には、実際の依存関係はありません。
libフォルダーでは、次のようにします。
import "package:todo_reporter/todo_reporter.dart"
todo_reporter.dartが作成され、パッケージのパブリックAPIを公開するためにexportを使用するすべてのクラスがそこに登録されます。 これは、パッケージ内の任意のパブリッククラスが.NET経由でインポートできるので、良いプラクティスです。このクラスがどのようなものか、ここで見ることができます:github.com/t....libフォルダの中にsrcフォルダを作成し、公開・非公開を問わずすべてのコードを格納します。
サンプルに含める必要があるのはコメントだけです。これらを入れたtodo.dartファイルを作りましょう。
class Todo {
final String name; final String todoUrl; final
final String todoUrl.Const Todo(this.name, {this.todoUrl} : assert(name !
const Todo(this.name, {this.todoUrl}) : assert(name != null);
}
さて、必要なメモは以上です。簡単だって言ったでしょ?さて、まだ終わりではありません。テストパッケージにユニットテストを追加しましょう。
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://.om';
final todo = Todo('name', todoUrl: givenUrl);
expect(todo.todoUrl, givenUrl);
});
});
}
これだけでアノテーションを作成することができます。コードはこのリンクあります。
それではコード生成に取り掛かりましょう。
Todo_reporter_generator。
todo_reporter_generator
パッケージの作成方法がわかったところで、.NET というパッケージを作成してみましょう。todo_reporter_generator.dart
その中に pubspec.yaml、build.yaml ファイル、lib フォルダがあり、lib フォルダの中に src フォルダと export ステートメントを含むファイルがあります。これは、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://.//_.rt
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を完成させましょう。このファイルにはBuildersに必要な設定が含まれています。詳細はこちらを参照してください:github.com/b...
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_factories エントリはコードをビルドするメソッドを指します。todo_reporter_generator.dart
libにbuilder.dartファイルを作成し、srcに以下の内容のファイルを追加します。
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');
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!";
}
}
todo_reporter_generator.dart
TodoReporterGenerator
ご覧のように、builder.dart には、Builder を作成する todoReporter メソッドがあります。この Builder は、.NET ファイルを受け取る SharedPartBuilder を使用して提供されます。このように、build_runner と source_gen は連携して動作します。
TodoReporterGenerator
GeneratorForAnnotation
generateForAnnotatedElement
つまり、Todoの場合、与えられたコメントでコメントされたコード片を見つけたときのみ実行されます。
generateForAnnotatedElement
生成されたコードがコンパイルされない場合、ビルドフェーズは失敗します。
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/
これらのファイルをプロジェクトで使用すると、コードを自動生成しようとするたびに、. コメントの扱い方については、次の投稿で説明します。
すべてのピースをまとめる:使用中のtodo_reporter
todo_repoter.dartを使い始めるための最後のピースは、プロジェクト上でその機能を実証することです。他の開発者が実際のプロジェクトでAPIがどのように使われているかを見ることができます。
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/
さて、パッケージを取得した後、使用されるアノテーション。
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のコードに含まれるすべてのTodoコメントに対して、有効なDartファイルを生成できるようになりました。コードに含まれるすべての Todo コメントに対して有効な Dart ファイルを生成できるようになりました。お好きなだけコメントを作成してください。
次の記事では...
ファイルを生成するための正しいセットアップができたので、次の記事では、生成されたコードが実際に何かクールなことをできるようにするコメントを利用する方法を学びます。
www.DeepL.com/Translator翻译 経由