use of org.fakereplace.data.ClassData in project fakereplace by fakereplace.
the class MethodReflection method getMethod.
public static Method getMethod(Class<?> clazz, String name, Class<?>... parameters) throws NoSuchMethodException {
ClassData cd = ClassDataStore.instance().getModifiedClassData(clazz.getClassLoader(), Descriptor.toJvmName(clazz.getName()));
if (cd == null) {
return clazz.getMethod(name, parameters);
}
String args = '(' + DescriptorUtils.classArrayToDescriptorString(parameters) + ')';
MethodData md = cd.getMethodData(name, args);
Class<?> superClass = clazz;
while (superClass.getSuperclass() != null && md == null && superClass != Object.class) {
superClass = superClass.getSuperclass();
cd = ClassDataStore.instance().getModifiedClassData(superClass.getClassLoader(), Descriptor.toJvmName(superClass.getName()));
if (cd != null) {
md = cd.getMethodData(name, args);
}
}
if (md == null) {
return clazz.getMethod(name, parameters);
}
switch(md.getType()) {
case NORMAL:
return superClass.getMethod(name, parameters);
case FAKE:
try {
if (!AccessFlag.isPublic(md.getAccessFlags())) {
throw new NoSuchMethodException(clazz.getName() + "." + name);
}
Class<?> c = superClass.getClassLoader().loadClass(md.getClassName());
return c.getMethod(name, parameters);
} catch (NoSuchMethodException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
throw new NoSuchMethodException();
}
use of org.fakereplace.data.ClassData in project fakereplace by fakereplace.
the class MethodReflection method getDeclaredMethods.
public static Method[] getDeclaredMethods(Class<?> clazz) {
try {
ClassData cd = ClassDataStore.instance().getModifiedClassData(clazz.getClassLoader(), Descriptor.toJvmName(clazz.getName()));
if (cd == null || !cd.isReplaceable()) {
return clazz.getDeclaredMethods();
}
Method[] meth = clazz.getDeclaredMethods();
List<Method> visible = new ArrayList<>(meth.length);
for (int i = 0; i < meth.length; ++i) {
MethodData mData = cd.getData(meth[i]);
if (mData == null || mData.getType() == MemberType.NORMAL) {
visible.add(meth[i]);
}
}
for (MethodData i : cd.getMethods()) {
if (i.getType() == MemberType.FAKE) {
Class<?> c = clazz.getClassLoader().loadClass(i.getClassName());
visible.add(i.getMethod(c));
}
}
Method[] ret = new Method[visible.size()];
for (int i = 0; i < visible.size(); ++i) {
ret[i] = visible.get(i);
}
return ret;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.fakereplace.data.ClassData in project fakereplace by fakereplace.
the class ConstructorReflection method getConstructor.
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameters) throws NoSuchMethodException {
ClassData cd = ClassDataStore.instance().getModifiedClassData(clazz.getClassLoader(), Descriptor.toJvmName(clazz.getName()));
if (cd == null || !cd.isReplaceable()) {
return clazz.getConstructor(parameters);
}
String args = '(' + DescriptorUtils.classArrayToDescriptorString(parameters) + ')';
MethodData md = cd.getMethodData("<init>", args);
if (md == null) {
return clazz.getConstructor(parameters);
}
switch(md.getType()) {
case NORMAL:
return clazz.getConstructor(parameters);
case FAKE_CONSTRUCTOR:
try {
Class<?> c = clazz.getClassLoader().loadClass(md.getClassName());
return c.getConstructor(parameters);
} catch (NoSuchMethodException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
throw new NoSuchMethodException();
}
use of org.fakereplace.data.ClassData in project fakereplace by fakereplace.
the class ConstructorReflection method getConstructors.
public static Constructor<?>[] getConstructors(Class<?> clazz) {
try {
ClassData cd = ClassDataStore.instance().getModifiedClassData(clazz.getClassLoader(), Descriptor.toJvmName(clazz.getName()));
if (cd == null || !cd.isReplaceable()) {
return clazz.getConstructors();
}
Constructor<?>[] meth = clazz.getConstructors();
List<Constructor<?>> visible = new ArrayList<>(meth.length);
for (int i = 0; i < meth.length; ++i) {
if (meth[i].getParameterTypes().length != 3 || !meth[i].getParameterTypes()[2].equals(ConstructorArgument.class)) {
visible.add(meth[i]);
}
}
ClassData cta = cd;
while (cta != null) {
for (MethodData i : cta.getMethods()) {
if (i.isConstructor()) {
if (i.getType() == MemberType.FAKE_CONSTRUCTOR && AccessFlag.isPublic(i.getAccessFlags())) {
Class<?> c = clazz.getClassLoader().loadClass(i.getClassName());
visible.add(i.getConstructor(c));
} else if (i.getType() == MemberType.REMOVED && i.getMethodName().equals("<init>")) {
Class<?> c = clazz.getClassLoader().loadClass(i.getClassName());
visible.remove(i.getConstructor(c));
}
}
}
cta = cta.getSuperClassInformation();
}
Constructor<?>[] ret = new Constructor[visible.size()];
for (int i = 0; i < visible.size(); ++i) {
ret[i] = visible.get(i);
}
return ret;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.fakereplace.data.ClassData in project fakereplace by fakereplace.
the class ConstructorReflection method getDeclaredConstructor.
public static Constructor<?> getDeclaredConstructor(Class<?> clazz, Class<?>... parameters) throws NoSuchMethodException {
ClassData cd = ClassDataStore.instance().getModifiedClassData(clazz.getClassLoader(), Descriptor.toJvmName(clazz.getName()));
if (cd == null || !cd.isReplaceable()) {
return clazz.getDeclaredConstructor(parameters);
}
String args = '(' + DescriptorUtils.classArrayToDescriptorString(parameters) + ')';
MethodData md = cd.getMethodData("<init>", args);
if (md == null) {
return clazz.getDeclaredConstructor(parameters);
}
switch(md.getType()) {
case NORMAL:
return clazz.getDeclaredConstructor(parameters);
case FAKE_CONSTRUCTOR:
try {
Class<?> c = clazz.getClassLoader().loadClass(md.getClassName());
return c.getDeclaredConstructor(parameters);
} catch (NoSuchMethodException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
throw new NoSuchMethodException();
}
Aggregations