Skip to content

Commit

Permalink
Analyze jdk classes through reflection instead of asm
Browse files Browse the repository at this point in the history
  • Loading branch information
sfPlayer1 committed Sep 20, 2024
1 parent c067634 commit b789f39
Showing 1 changed file with 62 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
package org.spongepowered.asm.mixin.transformer;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -907,6 +909,59 @@ private ClassInfo(ClassNode classNode) {
}
}

private ClassInfo(Class<?> cls) {
this.name = getName(cls);
this.superName = cls.getSuperclass() != null ? getName(cls.getSuperclass()) : ClassInfo.JAVA_LANG_OBJECT;
this.initialisers = new HashSet<Method>();
this.methods = new HashSet<Method>();
this.fields = new HashSet<Field>();
this.isInterface = cls.isInterface();
Class<?>[] interfaces = cls.getInterfaces();
this.interfaces = new HashSet<String>(interfaces.length);
this.isMixin = false;
this.mixin = null;
this.mixins = Collections.emptySet();

for (Class<?> iface : interfaces) {
this.interfaces.add(getName(iface));
}

for (Constructor<?> ctor : cls.getDeclaredConstructors()) {
if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
continue;
}

this.initialisers.add(new Method(ctor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(ctor), ctor.getModifiers()));
}

for (java.lang.reflect.Method method : cls.getDeclaredMethods()) {
if ((method.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
continue;
}

this.methods.add(new Method(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method), method.getModifiers()));
}

for (java.lang.reflect.Field field : cls.getDeclaredFields()) {
if ((field.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
continue;
}

this.fields.add(new Field(field.getName(), org.objectweb.asm.Type.getDescriptor(field.getType()), field.getModifiers()));
}

this.isProbablyStatic = true;
this.methodMapper = new MethodMapper(MixinEnvironment.getCurrentEnvironment(), this);

this.access = cls.getModifiers();
this.isInner = false;
this.outerName = null;
}

private static String getName(Class<?> cls) {
return cls.getName().replace('.', '/');
}

void addInterface(String iface) {
this.interfaces.add(iface);
this.getSignature().addInterface(iface);
Expand Down Expand Up @@ -2025,9 +2080,13 @@ public static ClassInfo forName(String className) {
ClassInfo info = ClassInfo.cache.get(className);
if (info == null) {
try {
int flags = MixinEnvironment.getCurrentEnvironment().getOption(Option.CLASSREADER_EXPAND_FRAMES) ? ClassReader.EXPAND_FRAMES : 0;
ClassNode classNode = MixinService.getService().getBytecodeProvider().getClassNode(className, true, flags);
info = new ClassInfo(classNode);
if (className.startsWith("java/")) { // this would ideally check the platform class loader for other jdk classes, but needs extra api to do so
info = new ClassInfo(Class.forName(className.replace('/', '.'), false, ClassInfo.class.getClassLoader()));
} else {
int flags = MixinEnvironment.getCurrentEnvironment().getOption(Option.CLASSREADER_EXPAND_FRAMES) ? ClassReader.EXPAND_FRAMES : 0;
ClassNode classNode = MixinService.getService().getBytecodeProvider().getClassNode(className, true, flags);
info = new ClassInfo(classNode);
}
} catch (Exception ex) {
ClassInfo.logger.catching(Level.TRACE, ex);
ClassInfo.logger.warn("Error loading class: {} ({}: {})", className, ex.getClass().getName(), ex.getMessage());
Expand Down

0 comments on commit b789f39

Please sign in to comment.