build method

  1. @override
Future build(
  1. BuildStep buildStep
)

Generates the outputs for a given BuildStep.

Implementation

@override
Future build(BuildStep buildStep) async {
  // Set the out id.
  final fileName = buildStep.inputId.pathSegments.last;
  final id = _id(buildStep);

  // Prepare the library reader.
  final library = await buildStep.inputLibrary;
  final libraryReader = LibraryReader(library);

  // Initilize the buffers used for writing.
  final headersBuffer = StringBuffer();
  final importsBuffer = StringBuffer();
  final bodyBuffer = StringBuffer();
  final mainBuffer = StringBuffer();

  // Add the 'AUTO GENERATED' not on the header among other IDE stuff.
  headersBuffer.writeln("/// AUTO GENERATED - DO NOT EDIT!");
  headersBuffer
      .writeln("// ignore_for_file: unused_import, unnecessary_import");

  // Add all the imports as they are from the library we are reader from.
  for (final import in library.imports) {
    if (import.prefix == null) continue;
    importsBuffer.writeln('import "${import.uri}";');
  }
  // also don't forget to import itself ;)
  importsBuffer.writeln('import "$fileName";');

  // generate better base service class.
  for (final clazz in getServiceClasses(libraryReader)) {
    // Service name.
    final baseServiceName = clazz.name;
    final serviceName = getServiceName(clazz);
    final serviceClientName = "${serviceName}Client";

    final betterServiceBaseName = "Better${serviceName}ServiceBase";
    final betterServiceName = "Better${serviceName}Service";

    final betterClientBaseName = "Better${serviceName}ClientBase";
    final betterClientName = "Better${serviceName}Client";
    final betterOfflineClientName = "Better${serviceName}OfflineClient";

    // Generate the base class for the better `service`.
    bodyBuffer.writeln("abstract class $betterServiceBaseName {");
    bodyBuffer.write(methodsToAbstractImplementation(clazz.methods));
    bodyBuffer.writeln("}");

    // Implement the better service by binding methods from the base service that the
    // implementor provide.
    bodyBuffer.writeln("class $betterServiceName extends $baseServiceName {");
    bodyBuffer.writeln("  final $betterServiceBaseName _service;");
    bodyBuffer.writeln("  $betterServiceName(this._service);");
    bodyBuffer
        .write(bindMethods(clazz.methods, "_service", returnFutureOr: false));
    bodyBuffer.writeln("}");

    // Generate the base class for the better `client`.
    bodyBuffer.writeln("abstract class $betterClientBaseName {");
    bodyBuffer.write(methodsToAbstractImplementation(clazz.methods));
    bodyBuffer.writeln("}");

    // The online/default implementation for the better client.
    bodyBuffer
        .writeln("class $betterClientName extends $betterClientBaseName {");
    bodyBuffer.writeln("  final $serviceClientName _client;");
    bodyBuffer.writeln("  $betterClientName(this._client);");
    bodyBuffer.write(bindMethods(clazz.methods, "_client",
        excludeParameters: [ServiceCall]));
    bodyBuffer.writeln("}");

    // Offline implementation for the better client.
    bodyBuffer.writeln(
        "class $betterOfflineClientName extends $betterClientBaseName {");
    bodyBuffer.writeln("  final $betterServiceBaseName _service;");
    bodyBuffer.writeln("  $betterOfflineClientName(this._service);");
    bodyBuffer.write(bindMethods(clazz.methods, "_service",
        excludeParameters: [ServiceCall]));
    bodyBuffer.writeln("}");
  }

  // combine all buffers and write.
  mainBuffer
    ..write(headersBuffer)
    ..write(importsBuffer)
    ..write(bodyBuffer);
  await buildStep.writeAsString(id, mainBuffer.toString());
}