build method
Generates the outputs for a given BuildStep.
Implementation
@override
Future<void> build(BuildStep buildStep) async {
final libraryElement = await buildStep.inputLibrary;
final library = LibraryReader(libraryElement);
try {
final spec = SpecExtractor.extract(library);
// ── Validate before generating ─────────────────────────────────────
final issues = SpecValidator.validate(spec);
for (final issue in issues) {
if (issue.isError) {
log.severe('nitrogen: ${buildStep.inputId.path}\n $issue');
} else {
log.warning('nitrogen: ${buildStep.inputId.path}\n $issue');
}
}
if (issues.any((i) => i.isError)) {
log.severe(
'nitrogen: Aborting generation for ${buildStep.inputId.path} due to validation errors above.',
);
return;
}
// We can use buildStep.allowedOutputs to find the EXACT output paths
// generated by build_runner based on our map.
final outputs = buildStep.allowedOutputs;
for (final outId in outputs) {
if (outId.path.endsWith('.g.dart')) {
final rawCode = DartFfiGenerator.generate(spec);
String formattedCode;
try {
formattedCode = DartFormatter().format(rawCode);
} catch (e) {
log.warning('nitrogen: Could not format ${outId.path}:\n$e');
formattedCode = rawCode;
}
await buildStep.writeAsString(outId, formattedCode);
} else if (outId.path.endsWith('.bridge.g.kt')) {
await buildStep.writeAsString(outId, KotlinGenerator.generate(spec));
} else if (outId.path.endsWith('.bridge.g.swift')) {
await buildStep.writeAsString(outId, SwiftGenerator.generate(spec));
} else if (outId.path.endsWith('.bridge.g.h')) {
await buildStep.writeAsString(outId, CppHeaderGenerator.generate(spec));
} else if (outId.path.endsWith('.bridge.g.cpp')) {
await buildStep.writeAsString(outId, CppBridgeGenerator.generate(spec));
} else if (outId.path.endsWith('.CMakeLists.g.txt')) {
await buildStep.writeAsString(outId, CMakeGenerator.generate(spec));
// ── NativeImpl.cpp outputs ─────────────────────────────────────
} else if (outId.path.endsWith('.native.g.h')) {
await buildStep.writeAsString(outId, CppInterfaceGenerator.generate(spec));
} else if (outId.path.endsWith('.mock.g.h')) {
await buildStep.writeAsString(outId, CppMockGenerator.generateMockHeader(spec));
} else if (outId.path.endsWith('.test.g.cpp')) {
await buildStep.writeAsString(outId, CppMockGenerator.generateTestStarter(spec));
}
}
} catch (e, st) {
log.warning('nitrogen: Could not process ${buildStep.inputId}:\n$e\n$st');
}
}