+
+ public class ClassNameRecordingRemapper extends Remapper {
+
+ private final Set<? super String> classNames;
+
+ public ClassNameRecordingRemapper(Set<? super String> classNames) {
+ this.classNames = classNames;
+ }
+
+ @Override
+ public String map(String typeName) {
+ classNames.add(typeName);
+ return super.map(typeName);
+ }
+
+ @Override
+ public String mapDesc(String desc) {
+ //classNames.add(desc);
+ return super.mapDesc(desc);
+ }
+ @Override
+ public String mapFieldName(String owner, String name, String desc) {
+ return super.mapFieldName(owner, name, desc);
+ }
+ @Override
+ public String mapInvokeDynamicMethodName(String name, String desc) {
+ // TODO Auto-generated method stub
+ return super.mapInvokeDynamicMethodName(name, desc);
+ }
+ @Override
+ public String mapMethodDesc(String desc) {
+ //classNames.add(desc);
+ return super.mapMethodDesc(desc);
+ }
+ @Override
+ public String mapMethodName(String owner, String name, String desc) {
+ // TODO Auto-generated method stub
+ return super.mapMethodName(owner, name, desc);
+ }
+ @Override
+ public String mapSignature(String signature, boolean typeSignature) {
+ //classNames.add(signature);
+ return super.mapSignature(signature, typeSignature);
+ }
+ @Override
+ public String mapType(String type) {
+ classNames.add(type);
+ return super.mapType(type);
+ }
+ @Override
+ public String[] mapTypes(String[] types) {
+ for(String type : types)
+ classNames.add(type);
+ // TODO Auto-generated method stub
+ return super.mapTypes(types);
+ }
+ @Override
+ public Object mapValue(Object value) {
+ //classNames.add(value.toString());
+ // TODO Auto-generated method stub
+ return super.mapValue(value);
+ }
+ }
+
+ public Set<String> classReferences(String className) {
+ try {
+ HashSet<String> referencedClasses = new HashSet<>();
+ ClassNameRecordingRemapper m = new ClassNameRecordingRemapper(referencedClasses);
+ ClassReader cr = new ClassReader(module.getClass(className));
+ int ASM5 = 5 << 16 | 0 << 8 | 0;
+ //TraceClassVisitor tcv = new TraceClassVisitor(null, new PrintWriter(System.err));
+ ClassVisitor cv1 = new ClassVisitor(ASM5) {};
+ ClassVisitor cv = new ClassRemapper(cv1, m);
+ cr.accept(cv, ClassReader.SKIP_DEBUG);
+ System.err.println(className + " refs: " + referencedClasses);
+ return referencedClasses;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public void loadReferences() {
+ ConcreteModule cm = (ConcreteModule)module;
+ try {
+ for(String className : cm.getClasses().keySet()) {
+ Set<String> refs = classReferences(className);
+ for(String s : refs) {
+ String internalName = s.replace('/', '.');
+ try {
+ classLoader.loadClass(internalName);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+