public void generateClass(ClassVisitor v) { ClassEmitter ce = new ClassEmitter(v); Method newInstance = ReflectUtils.findNewInstance(keyInterface); if (!newInstance.getReturnType().equals(Object.class)) { throw new IllegalArgumentException("newInstance method must return Object"); } Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes()); ce.begin_class( Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), KEY_FACTORY, new Type[] {Type.getType(keyInterface)}, Constants.SOURCE_FILE); EmitUtils.null_constructor(ce); EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance)); int seed = 0; CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, TypeUtils.parseConstructor(parameterTypes), null); e.load_this(); e.super_invoke_constructor(); e.load_this(); for (int i = 0; i < parameterTypes.length; i++) { seed += parameterTypes[i].hashCode(); ce.declare_field( Constants.ACC_PRIVATE | Constants.ACC_FINAL, getFieldName(i), parameterTypes[i], null); e.dup(); e.load_arg(i); e.putfield(getFieldName(i)); } e.return_value(); e.end_method(); // hash code e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null); int hc = (constant != 0) ? constant : PRIMES[(int) (Math.abs(seed) % PRIMES.length)]; int hm = (multiplier != 0) ? multiplier : PRIMES[(int) (Math.abs(seed * 13) % PRIMES.length)]; e.push(hc); for (int i = 0; i < parameterTypes.length; i++) { e.load_this(); e.getfield(getFieldName(i)); EmitUtils.hash_code(e, parameterTypes[i], hm, customizer); } e.return_value(); e.end_method(); // equals e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null); Label fail = e.make_label(); e.load_arg(0); e.instance_of_this(); e.if_jump(e.EQ, fail); for (int i = 0; i < parameterTypes.length; i++) { e.load_this(); e.getfield(getFieldName(i)); e.load_arg(0); e.checkcast_this(); e.getfield(getFieldName(i)); EmitUtils.not_equals(e, parameterTypes[i], fail, customizer); } e.push(1); e.return_value(); e.mark(fail); e.push(0); e.return_value(); e.end_method(); // toString e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null); e.new_instance(Constants.TYPE_STRING_BUFFER); e.dup(); e.invoke_constructor(Constants.TYPE_STRING_BUFFER); for (int i = 0; i < parameterTypes.length; i++) { if (i > 0) { e.push(", "); e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING); } e.load_this(); e.getfield(getFieldName(i)); EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizer); } e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING); e.return_value(); e.end_method(); ce.end_class(); }