writeBuiltInteropConverter function

Future<void> writeBuiltInteropConverter(
  1. ClassElement element,
  2. SubjectCodeContext codeContext,
  3. SubjectGenContext<Element> context
)

Implementation

Future<void> writeBuiltInteropConverter(ClassElement element, SubjectCodeContext codeContext, SubjectGenContext context) async {
  codeContext.additionalImports.add(AliasImport.gen("package:dogs_core/dogs_core.dart"));
  codeContext.additionalImports.add(AliasImport.gen("package:dogs_built/dogs_built.dart"));
  codeContext.additionalImports.add(AliasImport.gen("package:built_collection/built_collection.dart"));

  var builtInterfaceImpl = element.thisType.asInstanceOf(builtInterface)!;
  var builderElement = builtInterfaceImpl.typeArguments[1].element! as ClassElement;

  var structure = await structurizeBuilt(codeContext, context, element);
  var builderName = builderElement.name;
  var typeRef = codeContext.typeName(element.thisType);
  var emitter = DartEmitter();
  var clazz = Class((builder) {
    builder.name = "${element.name}Converter";
    builder.extend = Reference(
        "$genAlias.GeneratedBuiltInteropConverter<$typeRef>");

    builder.constructors.add(Constructor((constr) => constr
      ..initializers.add(Code("super(struct: const ${structure.code(structure.fields.map((e) => "_\$${e.accessor}").toList())})"))
    ));

    builder.methods.add(Method((builder) => builder
      ..name = "_values"
      ..returns = Reference("List<dynamic>")
      ..requiredParameters.add(Parameter((builder) => builder
        ..type = Reference(codeContext.className(element))
        ..name = "obj"))
      ..static = true
      ..lambda = true
      ..body =
      Code("[${structure.fields.map((e) => "obj.${e.accessor}").join(",")}]")));

    for (var value in structure.fields.map((e) => e.accessor)) {
      builder.methods.add(Method((builder) => builder
        ..name = "_\$$value"
        ..returns = Reference("dynamic")
        ..requiredParameters.add(Parameter((builder) => builder
          ..type = Reference(codeContext.className(element))
          ..name = "obj"))
        ..static = true
        ..lambda = true
        ..body = Code("obj.$value")));
    }

    builder.methods.add(Method((builder) => builder
      ..name = "_activator"
      ..returns = Reference(codeContext.className(element))
      ..requiredParameters.add(Parameter((builder) => builder
        ..type = Reference("List")
        ..name = "list"))
      ..static = true
      ..lambda = false
      ..body = Code("return (${typeRef}Builder()\n${
           builderElement.accessors.where((element) => element.isGetter && element.isPublic && !element.isStatic)
              .mapIndexed((i,e) {
                if (listBuilderChecker.isAssignableFromType(e.returnType)) {
                  var innerType = e.returnType.asInstanceOf(listBuilderInterface)!.typeArguments[0];
                  return "..${e.name} = list[$i] == null ? null : gen.ListBuilder<${codeContext.typeName(innerType)}>(list[$i])";
                } else if (setBuilderChecker.isAssignableFromType(e.returnType)) {
                  var innerType = e.returnType.asInstanceOf(setBuilderInterface)!.typeArguments[0];
                  return "..${e.name} = list[$i] == null ? null : gen.SetBuilder<${codeContext.typeName(innerType)}>(list[$i])";
                } else if (mapBuilderChecker.isAssignableFromType(e.returnType)) {
                  var typeArguments = e.returnType.asInstanceOf(mapBuilderInterface)!.typeArguments;
                  return "..${e.name} = list[$i] == null ? null : gen.MapBuilder<${codeContext.typeName(typeArguments[0])}, ${codeContext.typeName(typeArguments[1])}>(list[$i])";
                }
                return "..${e.name} = list[$i]";
              })
              .join("\n")
      }).build();")));
  });
  codeContext.codeBuffer.writeln(clazz.accept(emitter));
}