別のコードジェネレーターの上にコードジェネレーターを実行する方法?


14

使用source_genのコードジェネレータを作るためにスタックを、どのように私は別の発電機(より具体的にの入力になりますコードを生成発電機を作ることができますかjson_serializable)?

たとえば、次のことを考慮してください。

class Example extends Generator {
  @override
  String generate(LibraryReader library, BuildStep buildStep) {
    return '''
@JsonSerializable(nullable: false)
class Person {
  final String firstName;
  final String lastName;
  final DateTime dateOfBirth;
  Person({this.firstName, this.lastName, this.dateOfBirth});
  factory Person.fromJson(Map<String, dynamic> json) => _PersonFromJson(json);
  Map<String, dynamic> toJson() => _PersonToJson(this);
}
''';
  }
}

これは、次に送信する必要があるコードを出力するコードジェネレーターの例です。 json_serializable

json_serializableここで正しく生成されるようにするにはどうすればよいですか?


答えはありませんが、このリンクはあなたを良い方向に導くかもしれませんか?私も興味があります。さらなる研究を行うためにそのリンクをブックマークしました
Frank Treacy

私はあなたの質問のケースを理解する途中です。もっと詳しく教えてもらえますか?これを解決するには、JSONのパーツファイルを出力する実際のメソッドを呼び出す方法と、手動でステップビルダーを構成して自分自身を呼び出す方法の2つがあります。dartを使用してコマンドを実行する3番目の方法がありますが、これはawait Process.start('bash',arguments,runInShell: true);プレイする最後の手段のようなものです。実際、私はこのリポジトリリンクで 1日前にすべてのコード生成ロジックを試したところなので、参考になります。
Parth Dave

コードジェネレーターを作成して、別のコードジェネレーターに依存するコードジェネレーターを作成できるようにします。このようにして、保守性の目的でソースをフォークする必要がなくなります。
レミRousselet

生成ステップは単一のflutter generate/ で機能する必要がありpub run build_runner buildます。それ以外の場合は、使用することは非常に珍しいでしょう。
レミRousselet

回答:


3

詳細については、build.yaml構成ファイルのドキュメントを確認してください。ただし、定義したビルドの後に別のビルドを実行できるようにするapplies_buildersparamを使用する必要があると思います。

この例は、.tar.gzファイルを生成し、.tar.gzファイルを入力として使用する別のビルドを実行するビルダーを示しています

builders:
  # The regular builder config, creates .tar.gz files.
  regular_builder:
    import: "package:my_package/builder.dart"
    builder_factories: ["myBuilder"]
    build_extensions: {".dart": [".tar.gz"]}
    auto_apply: dependents
    apply_builders: [":archive_extract_builder"]
post_process_builders:
  # The post process builder config, extracts .tar.gz files.
  extract_archive_builder:
    import: "package:my_package/extract_archive_builder.dart"
    builder_factory: "myExtractArchiveBuilder"
    input_extensions: [".tar.gz"]

だからsource_genあなたはあなたのビルドのために実装する必要があります

applies_builders: ["source_gen|combining_builder", "json_serializable"]

他のビルダーを設定します

json_serializable:
    import: "package:json_serializable/builder.dart"
    builder_factories: ["jsonSerializable"]
    build_extensions: {".dart": ["json_serializable.g.part"]}
    auto_apply: dependents
    build_to: cache
    applies_builders: ["source_gen|combining_builder"]

[apply_builders]プロパティで何を渡すべきですか?
ペドロマサンゴ

2

両方に@JsonSerializable注釈が付いている2つのパッケージが存在する可能性があるため、注釈だけでは不可能です。

2つの状況があります。

  • あなたはあなたのジェネレータの後に他のジェネレータが何を実行すべきか知っています。

    • https://stackoverflow.com/a/59605830/6877472はソリューションの1つです
    • 自分のジェネレータで他のジェネレータのコードを使用して、それらのジェネレータの.generate関数を呼び出すことができます。コード例:

class Example extends Generator {
    @override
    String generate(LibraryReader library, BuildStep buildStep) {
      return JsonSerializable().generate('''
          @JsonSerializable(nullable: false)
          class Person {
            final String firstName;
            final String lastName;
            final DateTime dateOfBirth;
            Person({this.firstName, this.lastName, this.dateOfBirth});
            factory Person.fromJson(Map<String, dynamic> json) => _PersonFromJson(json);
            Map<String, dynamic> toJson() => _PersonToJson(this);
          }
        ''');
     }

}
  • ジェネレーターの後に他のジェネレーターを実行する必要があるかどうかはわかりません。

残念ながら、現時点では、ジェネレーターがコード生成を必要とするコードを生成する可能性があることをsource_genに通知する方法はありません。

購読したい場合は、https://github.com/dart-lang/source_gen/issues/442でここに問題を作成しました


-2

jsonDecode()メソッドの引数としてJSON文字列を使用して関数を呼び出すことにより、JSONをデコードできます。

Map<String, dynamic> user = jsonDecode(jsonString);

print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');

次に、User.fromJson()コンストラクターを使用して、マップ構造とtoJson()ユーザーインスタンスをマップに変換するメソッドから新しいUserインスタンスを作成します。

employee.dart

class Employee {
  final String name;
  final String id;

  Employee(this.name, this.id);

  Employee.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        id = json['id'];

  Map<String, dynamic> toJson() =>
    {
      'name': name,
      'id': id,
    };
}

json_serializable JSONシリアル化ボイラープレートを生成する自動ソースコードジェネレーターです。

json_serializableプロジェクトに含めるには、1つの通常の依存関係と2つのdev依存関係が必要です。

dependencies:
  json_annotation: ^0.2.3

dev_dependencies:
  build_runner: ^0.8.0
  json_serializable: ^0.5.0

JSONシリアル化の詳細については、こちらを参照してください

Smokeライブラリを使用することもできます。

これはミラー機能のサブセットですが、ミラーベースとCodegenベースの両方の実装があります。それはPolymerDartチームによって書かれているので、これからやってくる「公式」に近いものです。

開発中は、ミラーベースのエンコード/デコードを使用します。ただし、パブリッシングの場合は、コードを生成する小さなトランスフォーマーを作成できます。

Seth Laddがここコードサンプルを作成しまし。これは、子オブジェクトをサポートするために少し拡張しました


実際、彼は自分のbuild_runnerプラグインを作成しており、そこからビルドランナーのスタッキングのような別のランナーを実行する必要があります。
パースデイブ

これはトピック外です。json_serializable単なる一例であり、何でもかまいません
レミRousselet

スモークライブラリの使用方法の例を示しただけです
Sreeram Nair
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.