วิธีการเรียกใช้ตัวสร้างรหัสที่ด้านบนของตัวสร้างรหัสอื่นได้อย่างไร


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 นั้นหรือโดยใช้ขั้นตอนแบบแมนนวลเพื่อกำหนดค่าและเรียกใช้ตัวสร้างส่วนของเราเอง มีวิธีที่สามในการรันคำสั่งโดยใช้โผawait Process.start('bash',arguments,runInShell: true);แต่มันเป็นวิธีสุดท้ายในการเล่น จริงๆแล้วฉันเพิ่งลองใช้การสร้างรหัสทั้งหมดเมื่อวันที่แล้วที่ลิงค์ repo นี้ดังนั้นฉันคิดว่าฉันจะมีประโยชน์
Parth Dave

มันเกี่ยวกับการเขียนโปรแกรมสร้างโค้ดซึ่งฉันสามารถเขียนได้ขึ้นอยู่กับอีกเครื่องหนึ่ง วิธีนี้ฉันจะไม่ต้องแยกแหล่งที่มาเพื่อการบำรุงรักษา
Rémi Rousselet

ขั้นตอนการสร้างจะต้องทำงานในครั้งเดียว/flutter generate pub run build_runner buildไม่อย่างนั้นมันก็ผิดปกติมาก ๆ
Rémi Rousselet

คำตอบ:


3

ตรวจสอบเอกสารประกอบของไฟล์ config.yaml สำหรับข้อมูลเพิ่มเติม แต่ฉันคิดว่าคุณควรใช้applies_buildersพารามิเตอร์ที่อนุญาตให้เรียกใช้งานบิลด์อื่นหลังจากที่กำหนดไว้

ตัวอย่างแสดงตัวสร้างที่สร้างไฟล์. 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]
Pedro Massango

2

มันเป็นไปไม่ได้เพียงแค่มีคำอธิบายประกอบเพราะอาจจะมีสองแพคเกจที่ทั้งสองมี@JsonSerializableคำอธิบายประกอบ

มีสอง situtations:

  • คุณรู้ว่าเครื่องกำเนิดไฟฟ้าอื่นควรทำงานอะไรหลังจากเครื่องกำเนิดไฟฟ้าของคุณ

    • https://stackoverflow.com/a/59605830/6877472เป็นหนึ่งในโซลูชั่น
    • คุณสามารถใช้รหัสของเครื่องกำเนิดอื่นในเครื่องกำเนิดของคุณเองและเรียกใช้ฟังก์ชันการทำงานของเครื่องกำเนิดของพวกเขา รหัสตัวอย่าง:

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

คุณสามารถถอดรหัส JSON ได้โดยการเรียกใช้jsonDecode()ฟังก์ชันโดยใช้สตริง JSON เป็นอาร์กิวเมนต์เมธอด

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

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

ตอนนี้ใช้User.fromJson()Constructor สำหรับการสร้างอินสแตนซ์ผู้ใช้ใหม่จากโครงสร้างแผนที่และtoJson()วิธีการซึ่งจะแปลงอินสแตนซ์ผู้ใช้เป็นแผนที่

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ไว้ในโครงการของคุณ

dependencies:
  json_annotation: ^0.2.3

dev_dependencies:
  build_runner: ^0.8.0
  json_serializable: ^0.5.0

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการทำให้เป็นอันดับ JSON คุณสามารถดูได้ที่นี่

คุณสามารถใช้ห้องสมุดควัน

มันเป็นส่วนหนึ่งของฟังก์ชั่น Mirrors แต่มีทั้งการใช้แบบ Mirrors และแบบเบส Codegen มันเขียนโดยทีม PolymerDart ดังนั้นมันจึงใกล้เคียงกับ "Official" อย่างที่เราจะได้รับ

ในขณะที่กำลังพัฒนามันจะใช้การเข้ารหัส / ถอดรหัสแบบใช้กระจกเงา แต่สำหรับการเผยแพร่คุณสามารถสร้างหม้อแปลงขนาดเล็กที่จะสร้างรหัส

Seth Ladd สร้างตัวอย่างโค้ดที่นี่ซึ่งฉันขยายเล็กน้อยเพื่อรองรับวัตถุย่อย:


ไม่จริงเขากำลังสร้างปลั๊กอิน build_runner ของเขาเองและจากที่เขาต้องการเรียกใช้นักวิ่งคนอื่นเช่นการซ้อนของนักวิ่งสร้าง
เดฟ

นี่คือนอกหัวข้อ json_serializableเป็นเพียงตัวอย่างและสามารถเป็นอะไรก็ได้
Rémi Rousselet

ฉันแค่ยกตัวอย่างวิธีการใช้ห้องสมุดควัน
Sreeram Nair
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.