org.sfm.reflect.asm.ConstructorDefinition Maven / Gradle / Ivy
package org.sfm.reflect.asm;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.sfm.reflect.TypeHelper;
public final class ConstructorDefinition {
private final Constructor constructor;
private final ConstructorParameter[] parameters;
public ConstructorDefinition(Constructor constructor,
ConstructorParameter[] parameters) {
super();
this.constructor = constructor;
this.parameters = parameters;
}
public Constructor getConstructor() {
return constructor;
}
public ConstructorParameter[] getParameters() {
return parameters;
}
public static List> extractConstructors(final Class target) throws IOException {
final List> constructors = new ArrayList<>();
ClassLoader cl = target.getClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
final InputStream is = cl.getResourceAsStream(target.getName().replace('.', '/') + ".class");
try {
ClassReader classReader = new ClassReader(is);
classReader.accept(new ClassVisitor(Opcodes.ASM5) {
@Override
public MethodVisitor visitMethod(int access,
String name,
String desc,
String signature,
String[] exceptions) {
if ("".equals(name)) {
return new MethodVisitor(Opcodes.ASM5) {
final List parameters = new ArrayList<>();
Label firstLabel;
Label lastLabel;
@Override
public void visitLabel(Label label) {
if (firstLabel == null) {
firstLabel = label;
}
lastLabel = label;
}
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
if (start.equals(firstLabel) && end.equals(lastLabel) && ! "this".equals(name)) {
parameters.add(createParameter(name, signature == null ? desc : signature));
}
}
private ConstructorParameter createParameter(String name,
String desc) {
try {
return new ConstructorParameter(name, AsmUtils.toGenericType(desc));
} catch (ClassNotFoundException e) {
throw new Error("Unexpected error " + e, e);
}
}
@Override
public void visitEnd() {
try {
constructors.add(new ConstructorDefinition<>(target.getDeclaredConstructor(toTypeArray(parameters)), parameters.toArray(new ConstructorParameter[parameters.size()])));
} catch(Exception e) {
throw new Error("Unexpected error " + e, e);
}
}
private Class>[] toTypeArray(List parameters) {
Class>[] types = new Class>[parameters.size()];
for(int i = 0; i < types.length; i++) {
types[i] = TypeHelper.toClass(parameters.get(i).getType());
}
return types;
}
};
} else {
return null;
}
}
}, 0);
} finally {
try { is.close(); } catch(Exception e) {};
}
return constructors;
}
public boolean hasParam(ConstructorParameter param) {
for (ConstructorParameter p : parameters) {
if (p.equals(param)) {
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy