|
|
@@ -1,12 +1,9 @@
|
|
|
-package net.ranides.assira.reflection.asm.cg;
|
|
|
+package net.ranides.assira.reflection.asm.impl;
|
|
|
|
|
|
import lombok.Data;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import net.ranides.assira.reflection.*;
|
|
|
-import net.ranides.assira.reflection.IClassLoader;
|
|
|
-import net.ranides.assira.reflection.asm.AsmClassBuilder;
|
|
|
-import net.ranides.assira.reflection.asm.AsmMethodBuilder;
|
|
|
-import net.ranides.assira.reflection.asm.AsmSupport;
|
|
|
+import net.ranides.assira.reflection.asm.*;
|
|
|
|
|
|
import java.util.*;
|
|
|
import java.util.function.Function;
|
|
|
@@ -28,6 +25,8 @@ public class CGAdapter {
|
|
|
|
|
|
private static final IMethod M_THAT = IClass.typeinfo(CGAdapterWrapper.class).method("net_ranides_assira_cg_that").get();
|
|
|
|
|
|
+ private final AdapterFactory factory;
|
|
|
+
|
|
|
private final IClass<?> adapter;
|
|
|
|
|
|
private final IClass<?> that;
|
|
|
@@ -38,13 +37,18 @@ public class CGAdapter {
|
|
|
|
|
|
private final AsmClassBuilder writer;
|
|
|
|
|
|
- private final byte[] bytecode;
|
|
|
-
|
|
|
private final List<IMethod> reflective;
|
|
|
|
|
|
private final List<AdapterMeta> adapters;
|
|
|
|
|
|
- public CGAdapter(IClass<?> adapter, IClass<?> that) {
|
|
|
+ private final IClass<?> generated;
|
|
|
+
|
|
|
+ public static IClass<?> load(AdapterFactory factory, IClass<?> adapter, IClass<?> that) {
|
|
|
+ return new CGAdapter(factory, adapter, that).generated;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CGAdapter(AdapterFactory factory, IClass<?> adapter, IClass<?> that) {
|
|
|
+ this.factory = factory;
|
|
|
this.adapter = adapter;
|
|
|
this.that = that;
|
|
|
this.name = that.name() + "$asm:" + AsmSupport.escape(adapter.name());
|
|
|
@@ -60,42 +64,44 @@ public class CGAdapter {
|
|
|
|
|
|
writer.field(IAttributes.of(IAttribute.PRIVATE), that, F_THAT);
|
|
|
|
|
|
- putConstructor();
|
|
|
+ implementConstructor();
|
|
|
|
|
|
- putToString();
|
|
|
+ implementInterface();
|
|
|
|
|
|
- putWrapperThat();
|
|
|
+ implementToString();
|
|
|
|
|
|
for(IMethod m : adapter.methods()) {
|
|
|
new MethodLink(m).link();
|
|
|
}
|
|
|
|
|
|
+ declareStatic();
|
|
|
+
|
|
|
+ this.generated = factory.loader().defineClass(name, writer.bytecode());
|
|
|
+
|
|
|
+ initStatic();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void declareStatic() {
|
|
|
for(int i=0, n=reflective.size(); i<n; i++) {
|
|
|
writer.field(A_METHODS, IClass.typeinfo(IMethod.class), F_METHODS+i);
|
|
|
}
|
|
|
for(int i=0, n=adapters.size(); i<n; i++) {
|
|
|
writer.field(A_ADAPTERS, IClass.typeinfo(Function.class), F_ADAPTERS + i);
|
|
|
}
|
|
|
- this.bytecode = writer.bytecode();
|
|
|
}
|
|
|
|
|
|
- private void init(IClass<?> ic) {
|
|
|
+ private void initStatic() {
|
|
|
for(int i=0, n=reflective.size(); i<n; i++) {
|
|
|
- ic.field(F_METHODS+i).get().set(null, reflective.get(i));
|
|
|
+ generated.field(F_METHODS+i).get().set(null, reflective.get(i));
|
|
|
}
|
|
|
+
|
|
|
for(int i=0, n=adapters.size(); i<n; i++) {
|
|
|
AdapterMeta meta = adapters.get(i);
|
|
|
- ic.field(F_ADAPTERS+i).get().set(null, Adapter.adapter(meta.target, meta.source));
|
|
|
+ generated.field(F_ADAPTERS+i).get().set(null, this.factory.adapter(meta.target, meta.source));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public IClass<?> load(IClassLoader loader) {
|
|
|
- IClass<?> ic = loader.defineClass(name, bytecode);
|
|
|
- init(ic);
|
|
|
- return ic;
|
|
|
- }
|
|
|
-
|
|
|
- private void putConstructor() {
|
|
|
+ private void implementConstructor() {
|
|
|
/// Adapter(That that) {
|
|
|
/// super();
|
|
|
/// this.that = that;
|
|
|
@@ -115,7 +121,7 @@ public class CGAdapter {
|
|
|
m.end();
|
|
|
}
|
|
|
|
|
|
- private void putToString() {
|
|
|
+ private void implementToString() {
|
|
|
/// String toString() {
|
|
|
/// String v = that.toString();
|
|
|
/// return new StringBuilder(24 + v.length()).append("Adapter{").append(that).append("=> some type}").toString()
|
|
|
@@ -153,7 +159,7 @@ public class CGAdapter {
|
|
|
m.end();
|
|
|
}
|
|
|
|
|
|
- private void putWrapperThat() {
|
|
|
+ private void implementInterface() {
|
|
|
/// public Object net_ranides_assira_cg_that() {
|
|
|
/// return this.that;
|
|
|
/// }
|
|
|
@@ -194,7 +200,7 @@ public class CGAdapter {
|
|
|
}
|
|
|
|
|
|
private int initResultAdapter() {
|
|
|
- if(!method.returns().annotation(Adapt.class).isPresent()) {
|
|
|
+ if(!method.returns().annotation(AdapterWrapper.class).isPresent()) {
|
|
|
return -1;
|
|
|
}
|
|
|
AdapterMeta meta = new AdapterMeta(target.returns(), method.returns());
|
|
|
@@ -253,7 +259,7 @@ public class CGAdapter {
|
|
|
m.dup();
|
|
|
m.push(i);
|
|
|
m.load(iargs.get(i), i + 1);
|
|
|
- if(iargs.get(i).annotation(Adapt.class).isPresent()) {
|
|
|
+ if(iargs.get(i).annotation(AdapterWrapper.class).isPresent()) {
|
|
|
m.invokeVirtual(M_THAT);
|
|
|
}
|
|
|
if (iargs.get(i).attribute(IAttribute.PRIMITIVE)) {
|
|
|
@@ -267,7 +273,7 @@ public class CGAdapter {
|
|
|
private void invokeDirect() {
|
|
|
for(int i=0, n=iargs.size(); i<n; i++) {
|
|
|
m.load(iargs.get(i), i+1);
|
|
|
- if(iargs.get(i).annotation(Adapt.class).isPresent()) {
|
|
|
+ if(iargs.get(i).annotation(AdapterWrapper.class).isPresent()) {
|
|
|
m.invokeVirtual(M_THAT);
|
|
|
}
|
|
|
if(!iargs.get(i).isSubclass(oargs.get(i))) {
|