onGenerate method

  1. @override
Future<$BuildOutput> onGenerate(
  1. ArtifactBuilder builder,
  2. ClassElement clazz,
  3. ConstructorElement ctor,
  4. List<FormalParameterElement> params,
  5. BuildStep step,
  6. List<String>? eFields,
)
override

Implementation

@override
Future<$BuildOutput> onGenerate(
  ArtifactBuilder builder,
  ClassElement clazz,
  ConstructorElement ctor,
  List<FormalParameterElement> params,
  BuildStep step,
  List<String>? eFields,
) async {
  StringBuffer buf = StringBuffer();
  List<Uri> importUris = <Uri>[];
  LibraryElement targetLib = clazz.library;

  buf.writeln(
    '  ${builder.applyDefsF("ArtifactMirror")} get \$mirror{_;return ${builder.applyDefsF("ArtifactReflection")}.instanceOf(_H)!;}',
  );
  builder.registerDef("List<Object>");
  buf.write(
    "  static ${builder.applyDefsF("List<Object>")} get \$annotations {_;return[",
  );
  for (ElementAnnotation a in clazz.metadata.annotations) {
    String? src = _annotationCode(a, builder, importUris);
    if (src != null) {
      buf.write("$src,");
    }
  }
  buf.writeln("];}");

  builder.registerDef("List<\$AFld>");
  buf.write(
    '  static ${builder.applyDefsF("List<\$AFld>")} get \$fields{_;return[',
  );

  for (FormalParameterElement param in params) {
    String name = param.name ?? "";
    String fullType = getTypeName(param.type);
    _addTypeImports(param.type, targetLib, builder, importUris);
    String descriptor = typeDescriptorCode(param.type, builder);
    builder.registerDef(fullType);
    buf.write("\$AFld<${builder.applyDefsF(clazz.name ?? "")}, $fullType>(");
    buf.write("${builder.stringD(name)},");
    buf.write("(i)=>i.$name,");
    buf.write("(i,v)=>i.copyWith($name:v),");

    buf.write("[");
    FieldElement? field = clazz.getField(name);
    if (field != null) {
      for (ElementAnnotation a in field.metadata.annotations) {
        String? src = _annotationCode(a, builder, importUris);
        if (src != null) {
          buf.write("$src,");
        }
      }
    }
    buf.write("],");
    buf.write("$descriptor,");
    buf.write("),");
  }
  buf.writeln("];}");

  builder.registerDef("List<\$AMth>");
  builder.registerDef("MethodParameters");
  buf.write(
    '  static ${builder.applyDefsF("List<\$AMth>")} get \$methods {_;return[',
  );
  a:
  for (MethodElement method in clazz.methods) {
    if (method.isOperator ||
        method.isStatic ||
        method.isAbstract ||
        method.isExternal ||
        method.isPrivate ||
        method.isSynthetic) {
      continue;
    }

    for (FormalParameterElement i in method.formalParameters) {
      if (getTypeName(i.type) == "InvalidType") {
        warn(
          "Unable to reflect on method ${clazz.name}.${method.name} because param ${i.name}'s type is unreadable.",
        );
        continue a;
      }
    }

    String name = method.name ?? "";
    String fullType = getTypeName(method.returnType);
    _addTypeImports(method.returnType, targetLib, builder, importUris);
    String returnTypeDescriptor = typeDescriptorCode(
      method.returnType,
      builder,
    );
    builder.registerDef(fullType);
    buf.write("\$AMth<${builder.applyDefsF(clazz.name ?? "")}, $fullType>(");
    buf.write("${builder.stringD(name)},");
    buf.write("(i, p)=>i.$name(");
    int g = 0;
    for (FormalParameterElement i in method.formalParameters.where(
      (i) => !i.isNamed,
    )) {
      String paramType = getTypeName(i.type);
      _addTypeImports(i.type, targetLib, builder, importUris);
      builder.registerDef(paramType);
      buf.write("p.o<${builder.applyDefsF(paramType)}>(${g++}),");
    }

    for (FormalParameterElement i in method.formalParameters.where(
      (i) => i.isNamed,
    )) {
      String paramType = getTypeName(i.type);
      _addTypeImports(i.type, targetLib, builder, importUris);
      builder.registerDef(paramType);
      buf.write(
        "${i.name}: p.n<${builder.applyDefsF(paramType)}>(${builder.stringD(i.name ?? "")}),",
      );
    }
    buf.write("),");

    buf.write("[");
    for (FormalParameterElement i in method.formalParameters.where(
      (i) => !i.isNamed,
    )) {
      String paramType = getTypeName(i.type);
      _addTypeImports(i.type, targetLib, builder, importUris);
      builder.registerDef(paramType);
      buf.write("${builder.applyDefsF(paramType)},");
    }
    buf.write("],");
    buf.write("{");
    for (FormalParameterElement i in method.formalParameters.where(
      (i) => i.isNamed,
    )) {
      String paramType = getTypeName(i.type);
      _addTypeImports(i.type, targetLib, builder, importUris);
      builder.registerDef(paramType);
      buf.write(
        "${builder.stringD(i.name ?? "")}: ${builder.applyDefsF(paramType)},",
      );
    }
    buf.write("},");
    buf.write("[");
    for (ElementAnnotation a in method.metadata.annotations) {
      String? src = _annotationCode(a, builder, importUris);
      if (src != null) {
        buf.write("$src,");
      }
    }
    buf.write("],");
    buf.write("$returnTypeDescriptor,");
    buf.write("[");
    for (FormalParameterElement i in method.formalParameters.where(
      (i) => !i.isNamed,
    )) {
      buf.write("${typeDescriptorCode(i.type, builder)},");
    }
    buf.write("],");
    buf.write("{");
    for (FormalParameterElement i in method.formalParameters.where(
      (i) => i.isNamed,
    )) {
      buf.write(
        "${builder.stringD(i.name ?? "")}: ${typeDescriptorCode(i.type, builder)},",
      );
    }
    buf.write("},");
    buf.write("),");
  }
  buf.writeln("];}");

  return (importUris, buf);
}