使用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
在此处正确生成?
答案 0 :(得分:3)
请查看build.yaml配置文件文档以获取更多信息,但是我认为您应该使用applies_builders
param,它允许在定义的构建之后执行另一构建。
该示例显示了一个生成器,该生成器生成.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"]
答案 1 :(得分: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 :(得分:-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实例转换为地图。
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序列化的更多详细信息,您可以参考here
您还可以使用Smoke库。
它是Mirrors功能的子集,但同时具有基于Mirrors和基于Codegen的实现。它是由PolymerDart团队撰写的,因此与我们即将获得的“官方”产品非常接近。
在开发过程中,它将使用基于镜像的编码/解码;但是对于发布,您可以创建一个小型的转换器来生成代码。
Seth Ladd创建了a code sample here,我extended slightly支持子对象: