我正在处理一个包含200多个模型的dart程序包,此刻,我必须为每个模型手动编写一行“导出”,以使使用该程序包的每个人都可以使用这些模型。
我希望构建运行器生成一个包含每个导出定义的dart文件。
因此,我将创建一个注释“ ExportModel”。构建器应搜索每个带有此注释的类。
我尝试创建一些生成器,但是它们将为每个带注释的类生成一个* .g.dart文件。我只想要一个文件。
在哪里可以创建仅运行一次并在最后创建文件的构建器?
答案 0 :(得分:0)
关于您的构建器仅运行一次并在包中创建一个文件的问题的简短答案是使用r'$lib$'
作为输入扩展名。长答案是要找到被注释的类,您可能需要中间输出来跟踪它们。
我要用2个构建器编写该文件,一个用于搜索ExportModel
批注,另一个用于编写导出文件。这是一个粗略的草图,其中省略了细节-我在这里没有测试任何代码,但是它应该可以帮助您开始正确的道路。
@ExportModel()
注释的类。可以使用package:source_gen
中的某些实用程序进行编写,但是不能使用LibraryBuilder
,因为它不会输出Dart代码...
目标是在每个.exports
文件旁边写入一个.dart
文件,作为所有用@ExportModel()
注释的类的名称。
class ExportLocatingBuilder implements Builder {
@override
final buildExtensions = const {
'.dart': ['.exports']
};
@override
Future<void> build(BuildStep buildStep) async {
final resolver = buildStep.resolver;
if (!await resolver.isLibrary(buildStep.inputId)) return;
final lib = LibraryReader(await buildStep.inputLibrary);
final exportAnnotation = TypeChecker.fromRuntime(ExportModel);
final annotated = [
for (var member in lib.annotatedWith(exportAnnotation)) element.name,
];
if (annotated.isNotEmpty) {
buildStep.writeAsString(
buildStep.inputId.changeExtension('.exports'), annotated.join(','));
}
}
}
此构建器应为build_to: cache
,并且您可能希望拥有一个PostProcessBuilder
来清理其产生的所有输出,这些输出将用applies_builder
指定。您可以使用FileDeletingBuilder
廉价地执行清理。有关临时输出,请参见the FAQ,例如,请参见angular cleanup。
.exports
文件并生成Dart文件使用findAssets
来跟踪所有这些.exports
文件,并为每个文件编写一个export
语句。在文件内容中使用show
,其中应包含被注释成员的名称。
class ExportsBuilder implements Builder {
@override
final buildExtensions = const {
r'$lib$': ['exports.dart']
};
@override
Future<void> build(BuildStep buildStep) async {
final exports = buildStep.findAssets(Glob('**/*.exports'));
final content = [
await for (var exportLibrary in exports)
'export \'${exportLibrary.changeExtension('.dart').uri}\' '
'show ${await buildStep.readAsString(exportLibrary)};',
];
if (content.isNotEmpty) {
buildStep.writeAsString(
AssetId(buildStep.inputId.package, 'lib/exports.dart'),
content.join('\n'));
}
}
}
如果您想将此文件发布在pub上,则此构建器可能应该为build_to: source
。它应该有一个required_inputs: [".exports"]
以确保它在先前的构建器之后运行。
您可以将其实现为使用findAssets
查找所有Dart文件的单个生成器。缺点是:
analyzer
不起作用,您需要使用Resolver
API直接解析此代码-解析器仅在主要输入是Dart库时才起作用,然后仅对Dart库起作用。从该库中导入的代码。.exports
并根据更改进行重建,然后只有导出更改时exports.dart
文件才会失效。 / li>