void ($ClassVisitor v) { Class<?> sc = (superclass == null) ? Object.class : superclass; if (TypeUtils.isFinal(sc.getModifiers())) { throw new IllegalArgumentException("Cannot subclass final class " + sc); } List<Constructor<?>> constructors = new ArrayList<>(Arrays.asList(sc.getDeclaredConstructors())); filterConstructors(sc, constructors); // Order is very important: must add superclass, then // its superclass chain, then each interface and // its superinterfaces. final Set forcePublic = new HashSet<>(); List<Method> actualMethods = new ArrayList<>(); final Map<Method, Method> covariantMethods = new HashMap<>(); getMethods(sc, interfaces, actualMethods, new ArrayList<>(), forcePublic); //Changes by Peter Gromov & Gregory Shrago for(Class aClass = sc; aClass != null; aClass = aClass.getSuperclass()) { for (final Method method : aClass.getDeclaredMethods()) { if (actualMethods.contains(method)) { removeAllCovariantMethods(actualMethods, method, covariantMethods); } } } ClassEmitter e = new ClassEmitter(v); e.begin_class(Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), $Type.getType(sc), (useFactory ? TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) : TypeUtils.getTypes(interfaces)), Constants.SOURCE_FILE); List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance()); e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, $Type.BOOLEAN_TYPE, null); if (!interceptDuringConstruction) { e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, $Type.BOOLEAN_TYPE, null); } e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null); e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null); for (int i = 0; i < callbackTypes.length; i++) { e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null); } final Map<Method, MethodInfo> methodInfoMap = new HashMap<>(); for (Method method : actualMethods) { if (isJdk8DefaultMethod(method)) { continue; } int modifiers = Constants.ACC_FINAL | (method.getModifiers() & ~Constants.ACC_ABSTRACT & ~Constants.ACC_NATIVE & ~Constants.ACC_SYNCHRONIZED); if (forcePublic.contains(MethodWrapper.create(method))) { modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC; } if (covariantMethods.containsKey(method)) { modifiers |= Constants.ACC_BRIDGE; } methodInfoMap.put(method, ReflectUtils.getMethodInfo(method, modifiers)); } emitMethods(e, methodInfoMap, covariantMethods); emitConstructors(e, constructorInfo); emitSetThreadCallbacks(e); emitSetStaticCallbacks(e); emitBindCallbacks(e); if (useFactory) { int[] keys = getCallbackKeys(); emitNewInstanceCallbacks(e); emitNewInstanceCallback(e); emitNewInstanceMultiarg(e, constructorInfo); emitGetCallback(e, keys); emitSetCallback(e, keys); emitGetCallbacks(e); emitSetCallbacks(e); } e.end_class(); }