build method
Generates the outputs for a given BuildStep.
Implementation
@override
Future<void> build(BuildStep buildStep) async {
final AssetId inputId = buildStep.inputId;
final AssetId outputId = AssetId(
inputId.package,
inputId.path.replaceAll('.dart', '.g.dart'),
);
final LibraryElement library = await buildStep.resolver.libraryFor(inputId);
final StringBuffer generatedCode = StringBuffer();
// Check if this file has any dependency injection annotations
final bool hasDependencyInjectionAnnotations =
library.children.any((Element element) {
if (element.metadata.annotations.isEmpty) {
return false;
}
for (final ElementAnnotation metadata in element.metadata.annotations) {
final Element? annotationElement = metadata.element;
if (annotationElement != null) {
final String? annotationType = annotationElement.library?.name;
final String annotationName = annotationElement.displayName;
if (_isDependencyInjectionAnnotation(
annotationName, annotationType)) {
return true;
}
}
}
return false;
});
if (!hasDependencyInjectionAnnotations) {
return;
}
generatedCode.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND');
generatedCode.writeln('// Generated by di_generator_build');
generatedCode.writeln(' ');
generatedCode.writeln("import 'package:get_it/get_it.dart';");
generatedCode
.writeln("import 'package:di_generator_build/get_it_extension.dart';");
generatedCode.writeln("import '${inputId.pathSegments.last}';");
// Note: Dependencies between generated files should be handled by the consuming project
// by importing the necessary .g.dart files in their main application code
generatedCode.writeln(' ');
final Set<String> processedElements = <String>{};
for (final Generator generator in _generators) {
if (generator is GeneratorForAnnotation) {
final List<Element> elements = library.children
.where((Element element) => element.metadata.annotations.isNotEmpty)
.toList();
for (final Element element in elements) {
for (final ElementAnnotation metadata
in element.metadata.annotations) {
final Element? annotation = metadata.element;
if (annotation != null) {
final String key = '${element.name}_${annotation.name}';
if (!processedElements.contains(key)) {
try {
final ConstantReader constantReader =
ConstantReader(metadata.computeConstantValue());
final String generated =
generator.generateForAnnotatedElement(
element,
constantReader,
buildStep,
);
if (generated.isNotEmpty) {
generatedCode.writeln(generated);
processedElements.add(key);
}
} on Exception {
// Skip if annotation doesn't match
}
}
}
}
}
}
}
if (generatedCode.isNotEmpty) {
// Write to build cache
await buildStep.writeAsString(outputId, generatedCode.toString());
// Try to write to source directory for better developer experience
try {
final String packageName = buildStep.inputId.package;
if (packageName != 'di_generator_build') {
final String sourcePath = inputId.path.replaceAll('.dart', '.g.dart');
final File sourceFile = File(sourcePath);
// Ensure the directory exists
final Directory dir = sourceFile.parent;
if (!dir.existsSync()) {
dir.createSync(recursive: true);
}
await sourceFile.writeAsString(generatedCode.toString());
}
} on Exception {
// If we can't write to source directory, that's okay
// The build cache version will still work
}
}
}