build method
Generates the outputs for a given BuildStep
.
Implementation
@override
Future build(BuildStep buildStep) async {
var contexts = <BuildContext?>[];
LibraryReader lib;
try {
lib = LibraryReader(await buildStep.inputLibrary);
} catch (_) {
return;
}
var elements = <AnnotatedElement>[];
try {
elements = lib
.annotatedWith(const TypeChecker.fromRuntime(Serializable))
.toList();
} catch (_) {
// Ignore error in source_gen/build_runner that has no explanation
}
for (var element in elements) {
if (element.element.kind != ElementKind.CLASS) {
throw 'Only classes can be annotated with a @Serializable() annotation.';
}
var annotation = element.annotation;
var serializers = annotation.peek('serializers')?.listValue ?? [];
if (serializers.isEmpty) continue;
// Check if TypeScript serializer is supported
if (!serializers.any((s) => s.toIntValue() == Serializers.typescript)) {
continue;
}
contexts.add(await buildContext(
element.element as ClassElement,
element.annotation,
buildStep,
buildStep.resolver,
autoSnakeCaseNames != false));
}
if (contexts.isEmpty) return;
var refs = <String>[];
var buf = CodeBuffer(
trailingNewline: true,
sourceUrl: buildStep.inputId.uri,
);
buf.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND');
// declare module `foo` {
buf
..writeln("declare module '${buildStep.inputId.package}' {")
..indent();
for (var ctx in contexts) {
// interface Bar { ... }
buf
..writeln('interface ${ctx!.modelClassNameRecase.pascalCase} {')
..indent();
var ext = <CodeBuffer>[];
for (var field in ctx.fields) {
// Skip excluded fields
if (ctx.excluded[field.name]?.canSerialize == false) continue;
var alias = ctx.resolveFieldName(field.name);
var typeScriptType = await compileToTypeScriptType(ctx, field.name,
ctx.resolveSerializedFieldType(field.name), refs, ext, buildStep);
// foo: string;
if (!ctx.requiredFields.containsKey(field.name)) {
if (alias != null) {
alias += '?';
}
}
buf.writeln('$alias: $typeScriptType;');
}
buf
..outdent()
..writeln('}');
for (var b in ext) {
b.copyInto(buf);
}
}
buf
..outdent()
..writeln('}');
var finalBuf = CodeBuffer();
refs.forEach(finalBuf.writeln);
buf.copyInto(finalBuf);
await buildStep.writeAsString(
buildStep.inputId.changeExtension('.d.ts'),
finalBuf.toString(),
);
}