generateTo static method

Future<void> generateTo(
  1. SubjectGenContext<Element> genContext,
  2. SubjectCodeContext codeContext
)

Implementation

static Future<void> generateTo(
    SubjectGenContext genContext, SubjectCodeContext codeContext) async {
  var emitter = DartEmitter();
  AliasCounter aliasCounter = AliasCounter();
  CachedAliasCounter counter = CachedAliasCounter(aliasCounter);
  LibraryElement httpLibraryElement = await genContext.step.resolver
      .libraryFor(
          AssetId.resolve(Uri.parse("package:darwin_http/darwin_http.dart")));
  LibraryReader httpLibrary = LibraryReader(httpLibraryElement);
  DartType httpServer = httpLibrary.findType("DarwinHttpServer")!.thisType;

  var serviceClass = genContext.matches.first as ClassElement;
  var descriptorName = "${serviceClass.name}Descriptor";
  var srcDependencies =
      getDependencies(serviceClass.unnamedConstructor?.parameters, counter);
  var dependencies = srcDependencies.toList()
    ..add(CompiledInjectorKey(httpServer, null));
  var controllerMethods = serviceClass.methods;
  var builder = ClassBuilder();
  //region Generate Service Implementation
  ServiceGen.implementConstructor(builder, descriptorName);
  ServiceGen.implementDependencies(builder, dependencies, counter);
  ServiceGen.implementPublications(builder, [CompiledInjectorKey(serviceClass.thisType, null)], counter);
  ServiceGen.implementConditions(builder, serviceClass, counter);
  ServiceGen.implementBindings(builder, serviceClass, serviceClass.thisType, counter);
  ServiceGen.implementInstantiate(builder, serviceClass, srcDependencies, counter);
  //endregion
  //region Link Start Methods
  var startMethodCodeBuilder = StringBuffer();
  startMethodCodeBuilder.writeln(Handlers.enclosingClassVarDef(serviceClass, counter));
  startMethodCodeBuilder.writeln(
      "${counter.get(httpServer)} httpServer = await system.injector.get(${counter.get(httpServer)});");
  var pathSpecifierChecker = TypeChecker.fromRuntime(dh.RequestPathSpecifier);
  var requestRegistrations = (await Future.wait(controllerMethods
          .where((element) => pathSpecifierChecker.hasAnnotationOf(element))
          .map((e) => createHttpRegistration(
              genContext, codeContext, builder, serviceClass, e, counter))))
      .toList();
  for (var registration in requestRegistrations) {
    startMethodCodeBuilder.writeln(registration);
  }

  builder.methods.add(Method((builder) => builder
    ..returns = Reference("Future<void>")
    ..modifier = MethodModifier.async
    ..name = "start"
    ..requiredParameters.add(Parameter((builder) => builder
      ..name = "system"
      ..type = ServiceGen.darwinSystemRef))
    ..requiredParameters.add(Parameter((builder) => builder
      ..name = "obj"
      ..type = Reference("dynamic")))
    ..annotations.add(CodeExpression(Code("override")))
    ..body = Code(startMethodCodeBuilder.toString())));
  //endregion
  //region Link Stop Methods
  var stopMethodCodeBuilder = StringBuffer();
  builder.methods.add(Method((builder) => builder
    ..returns = Reference("Future<void>")
    ..modifier = MethodModifier.async
    ..name = "stop"
    ..requiredParameters.add(Parameter((builder) => builder
      ..name = "system"
      ..type = ServiceGen.darwinSystemRef))
    ..requiredParameters.add(Parameter((builder) => builder
      ..name = "obj"
      ..type = Reference("dynamic")))
    ..annotations.add(CodeExpression(Code("override")))
    ..body = Code(stopMethodCodeBuilder.toString())));
  //endregion
  var descriptorClass = builder.build();
  codeContext.additionalImports.addAll(counter.imports);
  codeContext.additionalImports.addAll([
    AliasImport.gen("package:darwin_sdk/darwin_sdk.dart"),
    AliasImport.gen("package:darwin_http/darwin_http.dart"),
    AliasImport.gen("package:darwin_injector/darwin_injector.dart"),
    AliasImport.gen("package:lyell/lyell.dart"),
    AliasImport.root("dart:async"),
    AliasImport.root("dart:core")
  ]);
  codeContext.additionalImports.where((element) => element.import.startsWith("dart:_http")).toList().forEach((element) {
    codeContext.additionalImports.remove(element);
    codeContext.additionalImports.add(AliasImport("dart:io", element.alias));
  });
  codeContext.codeBuffer.writeln(descriptorClass.accept(emitter));
}