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


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零件文件的实际方法,或者使用手动步骤配置和调用我们自己的零件生成器。还有第三种方法可以使用dart运行命令,await Process.start('bash',arguments,runInShell: true);但这是最后一种方法。实际上,我一天前刚刚在此repo 链接上尝试了所有代码生成逻辑,所以..我认为我可以提供帮助。
Parth Dave

这是关于编写代码生成器的,这样我就可以编写一个依赖于另一个代码生成器的代码生成器。这样,我就不必为了可维护性而分叉其资源。
雷米Rousselet

生成步骤必须以flutter generate/开头pub run build_runner build。否则使用将非常不寻常。
雷米Rousselet

Answers:


3

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

所以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注释的软件包

有两种情况:

  • 您知道在生成器之后还应该运行其他哪些生成器。


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实例,该实例将User实例转换为地图。

员工镖

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序列化样板。

您需要一个常规依赖项,并需要两个dev依赖项才能包含json_serializable在您的项目中。

dependencies:
  json_annotation: ^0.2.3

dev_dependencies:
  build_runner: ^0.8.0
  json_serializable: ^0.5.0

有关JSON序列化的更多详细信息,请参见此处

您还可以使用Smoke库。

它是Mirrors功能的子集,但同时具有基于Mirrors和基于Codegen的实现。它是由PolymerDart团队编写的,因此与我们即将获得的“正式版”非常接近。

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

塞思·拉德(Seth Ladd)在这里创建了一个代码示例,我对其进行了扩展以支持子对象:


实际上,他实际上并没有在创建自己的build_runner插件,而需要从该插件运行另一种运行器,例如堆叠构建运行器。
Parth Dave

这是题外话。json_serializable仅仅是一个例子,可以是任何东西
雷米Rousselet

我只是在举例说明如何使用烟雾库
Sreeram Nair
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.