writeGeneratedBuilder static method

void writeGeneratedBuilder(
  1. ClassElement element,
  2. StructurizeResult structurized,
  3. String constructorName,
  4. SubjectCodeContext codeContext,
)

Implementation

static void writeGeneratedBuilder(
    ClassElement element,
    StructurizeResult structurized,
    String constructorName,
    SubjectCodeContext codeContext) {
  var emitter = DartEmitter();
  var builderName = "${element.name}Builder";
  var clazz = Class((builder) {
    builder.name = builderName;

    builder.fields.add(Field((builder) => builder
      ..name = "\$values"
      ..type = Reference("late List<dynamic>")));

    builder.fields.add(Field((builder) => builder
      ..name = "\$src"
      ..type = Reference("${codeContext.className(element)}?")));

    builder.constructors.add(Constructor((builder) => builder
      ..optionalParameters.add(Parameter((builder) => builder
        ..type = Reference("${codeContext.className(element)}?")
        ..name = "\$src"))
      ..body = Code(
          "if (\$src == null) {\$values = List.filled(${structurized.fieldNames.length},null);} else {\$values = ${element.name}Converter._values(\$src);this.\$src=\$src;}")));

    for (var element in structurized.structure.fields) {
      var index = structurized.structure.fields.indexOf(element);
      builder.methods.add(Method((builder) => builder
        ..name = element.accessor
        ..type = MethodType.setter
        ..requiredParameters.add(Parameter((builder) => builder
          ..name = "value"
          ..type = Reference(element.type + (element.optional ? "?" : ""))))
        ..body = Code("\$values[$index] = value;")));

      builder.methods.add(Method((builder) => builder
        ..name = element.accessor
        ..type = MethodType.getter
        ..returns = Reference(element.type + (element.optional ? "?" : ""))
        ..lambda = true
        ..body = Code("\$values[$index]")));
    }

    var hasRebuildHook = TypeChecker.fromRuntime(PostRebuildHook).isAssignableFromType(element.thisType);

    builder.methods.add(Method((builder) => builder
      ..name = "build"
      ..returns = Reference(codeContext.className(element))
      ..body = Code("""
var instance = ${element.name}Converter._activator(\$values);
${!hasRebuildHook ? "" : """if (\$src != null) {
instance.postRebuild(\$src!, instance);
}"""}
return instance;""")));
  });
  codeContext.codeBuffer.writeln(clazz.accept(emitter));
}