Bagaimana menjalankan generator kode di atas pembuat kode lainnya?

14

Menggunakan tumpukan source_gen untuk membuat generator kode, bagaimana saya bisa membuat generator yang menghasilkan kode yang akan menjadi input generator lain (lebih khusus json_serializable)?

Sebagai contoh, pertimbangkan:

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);
}
''';
  }
}

Ini adalah contoh generator kode yang menghasilkan kode yang kemudian perlu dikirim json_serializable

Apa yang bisa saya lakukan sehingga json_serializablemenghasilkan dengan benar di sini?

Rémi Rousselet
sumber
Saya tidak punya jawaban tetapi tautan ini mungkin mengarahkan Anda ke arah yang baik? Saya juga tertarik. Saya telah menandai tautan itu untuk melakukan penelitian lebih lanjut
Frank Treacy
Saya setengah jalan untuk memahami kasus untuk pertanyaan Anda. dapatkah Anda menjelaskan lebih lanjut? ada dua cara untuk menyelesaikan ini baik dengan memanggil metode aktual yang menampilkan file bagian JSON itu atau dengan menggunakan langkah manual untuk mengkonfigurasi dan memanggil pembangun bagian diri kita. Ada cara ketiga untuk menjalankan perintah menggunakan panah, await Process.start('bash',arguments,runInShell: true);tetapi ini adalah cara terakhir untuk bermain. sebenarnya saya baru saja mencoba semua logika pembuatan kode satu hari yang lalu pada tautan repo ini jadi .. saya pikir saya bisa membantu.
Parth Dave
Ini tentang membuat generator kode, sehingga saya bisa menulis yang tergantung pada yang lain. Dengan cara ini saya tidak perlu mengambil sumbernya untuk tujuan pemeliharaan.
Rémi Rousselet
Langkah pembuatan harus bekerja dalam satu flutter generate/ pub run build_runner build. Kalau tidak, akan sangat tidak biasa untuk digunakan.
Rémi Rousselet

Jawaban:

3

Periksa dokumentasi file konfigurasi build.yaml untuk info lebih lanjut, tetapi saya pikir Anda harus menggunakan applies_buildersparam yang memungkinkan untuk mengeksekusi build lain setelah yang ditentukan.

Contoh ini memperlihatkan pembangun yang menghasilkan file .tar.gz dan kemudian menjalankan build lain yang menggunakan file .tar.gz sebagai input

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"]

jadi dengan source_genAnda harus menerapkan untuk membangun Anda

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

dan mengkonfigurasi pembangun lainnya

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"]
jamesblasco
sumber
Apa yang harus saya berikan di properti [apply_builders]?
Pedro Massango
2

Tidak mungkin hanya dengan anotasi karena mungkin ada dua paket yang keduanya memiliki @JsonSerializableanotasi

Ada dua situtations:

  • Anda tahu generator apa yang harus dijalankan setelah generator Anda.


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);
          }
        ''');
     }

}
  • Anda tidak tahu generator apa yang harus dijalankan setelah generator Anda.

Sayangnya saat ini tidak ada cara untuk memberi tahu source_gen bahwa generator Anda dapat menghasilkan kode yang membutuhkan pembuatan kode.

Saya membuat masalah di sini https://github.com/dart-lang/source_gen/issues/442 jika Anda ingin berlangganan

Sahandev
sumber
-2

Anda bisa mendekode JSON dengan memanggil jsonDecode()fungsi, dengan string JSON sebagai argumen metode.

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

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

Sekarang, Gunakan User.fromJson()konstruktor, untuk membuat instance Pengguna baru dari struktur peta dan toJson()metode, yang mengubah instance Pengguna menjadi peta.

pegawai.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 adalah generator kode sumber otomatis yang menghasilkan boilerplate serialisasi JSON untuk Anda.

Anda memerlukan satu dependensi reguler, dan dua dependensi dev untuk disertakan json_serializabledalam proyek Anda.

dependencies:
  json_annotation: ^0.2.3

dev_dependencies:
  build_runner: ^0.8.0
  json_serializable: ^0.5.0

Untuk detail lebih lanjut tentang serialisasi JSON Anda dapat merujuk di sini

Anda juga dapat menggunakan perpustakaan Asap .

Ini adalah bagian dari fungsi Mirrors tetapi memiliki implementasi berbasis Mirror dan juga Codegen. Ini ditulis oleh tim PolymerDart, jadi sedekat mungkin dengan "Resmi" yang akan kita dapatkan.

Saat mengembangkan, itu akan menggunakan encoding / decoding berbasis Mirrors; tetapi untuk penerbitan Anda dapat membuat transformator kecil yang akan menghasilkan kode.

Seth Ladd membuat contoh kode di sini , yang saya sedikit diperluas untuk mendukung objek anak:

Sreeram Nair
sumber
Tidak sebenarnya dia membuat plugin build_runner miliknya sendiri dan darinya dia perlu menjalankan jenis runner lain seperti susun build runner.
Parth Dave
Ini di luar topik. json_serializablehanyalah sebuah contoh dan bisa berupa apa saja
Rémi Rousselet
Saya baru saja memberi contoh tentang bagaimana perpustakaan asap dapat digunakan
Sreeram Nair