proxy method

String proxy(
  1. Snippet snippet,
  2. String kn,
  3. String dn,
  4. ClassElement k,
  5. List<MethodElement> ms,
)

Implementation

String proxy(Snippet snippet, String kn, String dn, ClassElement k,
    List<MethodElement> ms) {
  return '''
class MPI$kn implements $kn, Injectable, Introspectable {
final InvocationHandler _h;
late final Map<String, Method> _methods;

MPI$kn(this._h) {
  _methods = {
  ${ms.map((m) {
    final pms = m.formalParameters.where((x) {
      return x.name != 'ctx';
    }).toList();
    final mmm = mpi(ConstantReader(macro.firstAnnotationOf(m)));
    final methodName = m.displayName;
    final method = methodName.length < 2
        ? methodName
        : '${methodName[0].toUpperCase()}${methodName.substring(1)}';
    final pname = '_Mesh$dn${method}Parameters';
    final rname = '_Mesh$dn${method}Returns';
    snippet.init('ark.constructor<$pname>(() => $pname());');
    snippet.init('ark.constructor<$rname>(() => $rname());');
    final List<Pair<String, String>> rs = [
      const Pair('code', 'String'),
      const Pair('message', 'String'),
      const Pair('cause', 'Cause'),
      Pair('content', types(m.returnType)),
    ];
    for (var idx = 0; idx < rs.length; idx++) {
      final p = rs[idx];
      final i = index(idx, p.a, m.returnType, annotation(Index), kn: p.b);
      final a = accessor(rname, i, p.a);
      snippet.init('''ark.declare<$rname>('${p.a}', $a);''');
    }
    for (var idx = 0; idx < pms.length; idx++) {
      final p = pms[idx];
      final name = p.displayName;
      final i = index(idx, name, p.type, annotation(Index, e: p));
      final a = accessor(pname, i, name);
      snippet.init('ark.declare<$pname>(\'$name\', $a);');
    }
    final i = index(-1, 'attachments', m.type, annotation(Index),
        kn: 'Types(Map,[String, String],()=><String,String>{})');
    final a = accessor(pname, i, 'attachments');
    snippet.init('ark.declare<$pname>(\'attachments\', $a);');
    snippet.define(parameters(pname, pms));
    snippet.define(returns(rname, m.returnType));
    return ''''${m.displayName}': Method({$mmm}, ${k.name}, $pname, $rname),''';
  }).join('\n')}
  };
}

@override
void ioc() {
  _h.ioc();
}

@override
Map<String, Introspector> methods() {
  return _methods;
}

${ms.map((m) {
    final rt = m.returnType.getDisplayString();
    final pt = m.formalParameters.map((p) => p.displayString()).join(', ');
    final pn = m.formalParameters
        .where((x) {
          return x.name != 'ctx';
        })
        .map((p) => p.name)
        .join(', ');
    final isStream = m.returnType.isDartAsyncStream;
    final body = isStream
        ? "await for (final v in await _h.invoke(this, _methods['${m.displayName}']!, [$pn], ctx)) { yield v; }"
        : "return await _h.invoke(this, _methods['${m.displayName}']!, [$pn], ctx);";
    return '''
    @override
    $rt ${m.displayName}($pt) async${isStream ? '*' : ''} {
      $body
    }
    ''';
  }).join('\n')}
}
''';
}