如何在另一个代码生成器的顶部运行代码生成器?

Rém*_*let 16 dart flutter

使用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);
}
''';
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个代码生成器的例子,它输出代码然后需要发送到 json_serializable

我该怎么做才能json_serializable在此处正确生成?

jam*_*sco 6

检查 build.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"]
Run Code Online (Sandbox Code Playgroud)

所以source_gen你应该为你的构建实现

applies_builders: ["source_gen|combining_builder", "json_serializable"]
Run Code Online (Sandbox Code Playgroud)

并配置另一个构建器

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"]
Run Code Online (Sandbox Code Playgroud)


Sre*_*air -3

您可以通过调用该函数来解码 JSON jsonDecode(),并将 JSON 字符串作为方法参数。

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

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

现在,使用User.fromJson()构造函数从映射结构和toJson()方法构造新的 User 实例,该方法将 User 实例转换为映射。

雇员.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,
    };
}
Run Code Online (Sandbox Code Playgroud)

json_serializable是一个自动源代码生成器,可以为您生成 JSON 序列化样板。

您需要将一个常规依赖项和两个开发依赖项包含json_serializable在您的项目中。

dependencies:
  json_annotation: ^0.2.3

dev_dependencies:
  build_runner: ^0.8.0
  json_serializable: ^0.5.0
Run Code Online (Sandbox Code Playgroud)

有关 JSON 序列化的更多详细信息,您可以参考此处

您还可以使用Smoke库。

它是 Mirrors 功能的子集,但同时具有基于 Mirrors 和基于 Codegen 的实现。它是由 PolymerDart 团队编写的,因此它与我们所得到的最接近“官方”。

在开发过程中,它将使用基于Mirrors的编码/解码;但为了发布,您可以创建一个小型转换器来生成代码。

Seth Ladd在这里创建了一个代码示例,我对其进行了稍微扩展以支持子对象: