T specialize(ImmutableMap<Class<?>, Class<?>> classRemapping) { String specializedClassName = specializedClassNamePrefix + specializedClassCounter.get(); ClassWriter specializedClassWriter = new ClassWriter(0); SimpleRemapper remapper = new SimpleRemapper(createRemapping(classRemapping, specializedClassName)); ClassVisitor classTransformer = new ClassRemapper(specializedClassWriter, remapper); try { ClassReader prototypeClassReader = new ClassReader(getPrototypeClassBytecode()); prototypeClassReader.accept(classTransformer, 0); byte[] specializedClassBytecode = specializedClassWriter.toByteArray(); Class<T> specializedClass = defineClass(specializedClassName, specializedClassBytecode); specializedClassCounter.incrementAndGet(); return specializedClass.newInstance(); } catch (InstantiationException | IllegalAccessException | IOException e) { throw new RuntimeException(e); } }
@Override public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { String newDesc = remapper.mapMethodDesc(desc); MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName( className, name, desc), newDesc, remapper.mapSignature( signature, false), exceptions == null ? null : remapper.mapTypes(exceptions)); return mv == null ? null : createMethodRemapper(mv); }
@Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { FieldVisitor fv = super.visitField(access, remapper.mapFieldName(className, name, desc), remapper.mapDesc(desc), remapper.mapSignature(signature, true), remapper.mapValue(value)); return fv == null ? null : createFieldRemapper(fv); }
@Override public ModuleVisitor visitModule(final String name, final int flags, final String version) { ModuleVisitor moduleVisitor = super.visitModule(remapper.mapModuleName(name), flags, version); return moduleVisitor == null ? null : createModuleRemapper(moduleVisitor); }
@Override public void visitSource(String source, String debug) { if (!SpecialSource.kill_source) { super.visitSource(source, debug); } }
@Override public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitAnnotation(remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { String newDesc = remapper.mapMethodDesc(desc); MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName( className, name, desc), newDesc, remapper.mapSignature( signature, false), exceptions == null ? null : remapper.mapTypes(exceptions)); return mv == null ? null : createMethodRemapper(mv); }
@Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { FieldVisitor fv = super.visitField(access, remapper.mapFieldName(className, name, desc), remapper.mapDesc(desc), remapper.mapSignature(signature, true), remapper.mapValue(value)); return fv == null ? null : createFieldRemapper(fv); }
@Override public ModuleVisitor visitModule(final String name, final int flags, final String version) { ModuleVisitor moduleVisitor = super.visitModule(remapper.mapModuleName(name), flags, version); return moduleVisitor == null ? null : createModuleRemapper(moduleVisitor); }
@Override public void visitSource( final String source, final String debug ) { if ( source == null ) { super.visitSource( source, debug ); } else { final String fqSource = pkg + source; final String mappedSource = remapper.map( fqSource ); final String filename = mappedSource.substring( mappedSource.lastIndexOf( '/' ) + 1 ); super.visitSource( filename, debug ); } } };
byte[] instrumentToBytes(MutableClass mutableClass) { instrument(mutableClass); ClassNode classNode = mutableClass.classNode; ClassWriter writer = new InstrumentingClassWriter(mutableClass.classNodeProvider, classNode); Remapper remapper = new Remapper() { @Override public String map(final String internalName) { return mutableClass.config.mappedTypeName(internalName); } }; ClassRemapper visitor = new ClassRemapper(writer, remapper); classNode.accept(visitor); return writer.toByteArray(); }
@Override public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitAnnotation(remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); }
@Override public MethodVisitor visitMethod( final int access, final String name, final String descriptor, final String signature, final String[] exceptions) { String remappedDescriptor = remapper.mapMethodDesc(descriptor); MethodVisitor methodVisitor = super.visitMethod( access, remapper.mapMethodName(className, name, descriptor), remappedDescriptor, remapper.mapSignature(signature, false), exceptions == null ? null : remapper.mapTypes(exceptions)); return methodVisitor == null ? null : createMethodRemapper(methodVisitor); }
@Override public FieldVisitor visitField( final int access, final String name, final String descriptor, final String signature, final Object value) { FieldVisitor fieldVisitor = super.visitField( access, remapper.mapFieldName(className, name, descriptor), remapper.mapDesc(descriptor), remapper.mapSignature(signature, true), (value == null) ? null : remapper.mapValue(value)); return fieldVisitor == null ? null : createFieldRemapper(fieldVisitor); }
@Override public ModuleVisitor visitModule(final String name, final int flags, final String version) { ModuleVisitor moduleVisitor = super.visitModule(remapper.mapModuleName(name), flags, version); return moduleVisitor == null ? null : createModuleRemapper(moduleVisitor); }
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { String key = findKeyFromValue(name).orElseGet(() -> null); if(key == null) { return super.findClass(name); } String path = key.replace('.', '/').concat(".class"); try (InputStream resource = getResourceAsStream(path)) { ClassReader reader = new ClassReader(resource); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); Remapper remapper = new Remapper() { @Override public String map(String from) { String to = remappings.get(from.replace('/', '.')); if (to == null) { return from; } return to.replace('.', '/'); } }; reader.accept(new ClassRemapper(writer, remapper), ClassReader.EXPAND_FRAMES); byte[] classBytes = writer.toByteArray(); return defineClass(name, classBytes, 0, classBytes.length); } catch (IOException e) { throw new ClassNotFoundException("IOException while loading", e); } } }
@Override public AnnotationVisitor visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor); }
@Override public MethodVisitor visitMethod( final int access, final String name, final String descriptor, final String signature, final String[] exceptions) { String remappedDescriptor = remapper.mapMethodDesc(descriptor); MethodVisitor methodVisitor = super.visitMethod( access, remapper.mapMethodName(className, name, descriptor), remappedDescriptor, remapper.mapSignature(signature, false), exceptions == null ? null : remapper.mapTypes(exceptions)); return methodVisitor == null ? null : createMethodRemapper(methodVisitor); }
@Override public FieldVisitor visitField( final int access, final String name, final String descriptor, final String signature, final Object value) { FieldVisitor fieldVisitor = super.visitField( access, remapper.mapFieldName(className, name, descriptor), remapper.mapDesc(descriptor), remapper.mapSignature(signature, true), (value == null) ? null : remapper.mapValue(value)); return fieldVisitor == null ? null : createFieldRemapper(fieldVisitor); }