if (!toProxy.isDefaultInstantiable()) {
throw new UnproxyableClassException(toProxy.getFullyQualifiedName() + " must have a default no-arg constructor");
}
ClassStructureBuilder builder = ClassBuilder.define(proxyClassName, toProxy).publicScope()
// .implementsInterface(parameterizedAs(Proxy.class, typeParametersOf(toProxy)))
.body();
String proxyVar = "_proxy";
builder.privateField(proxyVar, toProxy).finish();
for (MetaMethod method : toProxy.getMethods()) {
if (method.getDeclaringClass().getFullyQualifiedName().equals("java.lang.Object")) continue;
DefParameters defParameters = DefParameters.from(method);
BlockBuilder methBody = builder.publicMethod(method.getReturnType(), method.getName()).parameters(defParameters)
.body();
List<Parameter> parms = defParameters.getParameters();
Statement[] statementVars = new Statement[parms.size()];
for (int i = 0; i < parms.size(); i++) {
statementVars[i] = Stmt.loadVariable(parms.get(i).getName());
}
if (method.getReturnType().isVoid()) {
methBody.append(Stmt.loadVariable(proxyVar).invoke(method, statementVars));
}
else {
methBody.append(Stmt.loadVariable(proxyVar).invoke(method, statementVars).returnValue());
}
methBody.finish();
}
builder.publicMethod(void.class, PROXY_BIND_METHOD).parameters(DefParameters.of(Parameter.of(toProxy, "proxy")))
.append(Stmt.loadVariable(proxyVar).assignValue(Stmt.loadVariable("proxy"))).finish();
return builder.getClassDefinition();
}