/** * {@inheritDoc} */ public int getModifiers() { return Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC | (instrumentedType.isInterface() ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE); }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { if (!typeDescription.isInterface()) { throw new IllegalStateException(source + " method carries default method call parameter on non-interface type"); } return implementationTarget.invokeDefault(source.asSignatureToken(), typeDescription); } }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { if (!typeDescription.isInterface()) { throw new IllegalStateException(source + " method carries default method call parameter on non-interface type"); } return implementationTarget.invokeDefault(source.asSignatureToken(), typeDescription); } }
/** * {@inheritDoc} */ public boolean isPrimaryBound(TypePool typePool) { return !typePool.describe(name).resolve().isInterface(); }
/** * {@inheritDoc} */ public int getModifiers() { return Opcodes.ACC_SYNTHETIC | getBaseModifiers() | (getDeclaringType().isInterface() ? Opcodes.ACC_PUBLIC : Opcodes.ACC_FINAL); }
/** * Resolves a type locator based upon an annotation value. * * @param typeDescription The annotation's value. * @return The appropriate type locator. */ protected static TypeLocator of(TypeDescription typeDescription) { if (typeDescription.represents(void.class)) { return ForParameterType.INSTANCE; } else if (!typeDescription.isInterface()) { throw new IllegalStateException("Cannot assign proxy to " + typeDescription); } else { return new ForType(typeDescription); } }
/** * {@inheritDoc} */ public boolean isPrimaryBound(TypePool typePool) { return !typePool.describe(name).resolve().isInterface(); }
/** * {@inheritDoc} */ public int getModifiers() { return Opcodes.ACC_SYNTHETIC | (methodDescription.isStatic() ? Opcodes.ACC_STATIC : EMPTY_MASK) | (methodDescription.isNative() ? Opcodes.ACC_NATIVE : EMPTY_MASK) | (instrumentedType.isInterface() ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE); }
/** * {@inheritDoc} */ public boolean isPrimaryBound(TypePool typePool) { return !typePool.describe(name).resolve().isInterface(); }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { if (!typeDescription.isInterface()) { throw new IllegalStateException(source + " method carries default method call parameter on non-interface type"); } return implementationTarget.invokeDefault(source.asSignatureToken(), TargetType.resolve(typeDescription, implementationTarget.getInstrumentedType())); } }
/** * {@inheritDoc} */ public Object asConstantPoolValue() { StringBuilder stringBuilder = new StringBuilder().append('('); for (TypeDescription parameterType : getParameterTypes()) { stringBuilder.append(parameterType.getDescriptor()); } String descriptor = stringBuilder.append(')').append(getReturnType().getDescriptor()).toString(); return new Handle(getHandleType().getIdentifier(), getOwnerType().getInternalName(), getName(), descriptor, getOwnerType().isInterface()); }
/** * Extracts the only method from a given type description which is validated for the required properties for * using the type as a proxy base type. * * @param typeDescription The type description to evaluate. * @return The only method which was found to be compatible to the proxy requirements. */ private static MethodDescription.InDefinedShape onlyMethod(TypeDescription typeDescription) { if (!typeDescription.isInterface()) { throw new IllegalArgumentException(typeDescription + " is not an interface"); } else if (!typeDescription.getInterfaces().isEmpty()) { throw new IllegalArgumentException(typeDescription + " must not extend other interfaces"); } else if (!typeDescription.isPublic()) { throw new IllegalArgumentException(typeDescription + " is not public"); } MethodList<MethodDescription.InDefinedShape> methodCandidates = typeDescription.getDeclaredMethods().filter(isAbstract()); if (methodCandidates.size() != 1) { throw new IllegalArgumentException(typeDescription + " must declare exactly one abstract method"); } return methodCandidates.getOnly(); }
/** * Extracts a handle type for invoking the given method. * * @param methodDescription The method for which a handle type should be found. * @return The handle type for the given method. */ protected static HandleType of(MethodDescription.InDefinedShape methodDescription) { if (methodDescription.isStatic()) { return INVOKE_STATIC; } else if (methodDescription.isPrivate()) { return INVOKE_SPECIAL; } else if (methodDescription.isConstructor()) { return INVOKE_SPECIAL_CONSTRUCTOR; } else if (methodDescription.getDeclaringType().isInterface()) { return INVOKE_INTERFACE; } else { return INVOKE_VIRTUAL; } }
/** * {@inheritDoc} */ protected String getCommonSuperClass(String leftTypeName, String rightTypeName) { TypeDescription leftType = typePool.describe(leftTypeName.replace('/', '.')).resolve(); TypeDescription rightType = typePool.describe(rightTypeName.replace('/', '.')).resolve(); if (leftType.isAssignableFrom(rightType)) { return leftType.getInternalName(); } else if (leftType.isAssignableTo(rightType)) { return rightType.getInternalName(); } else if (leftType.isInterface() || rightType.isInterface()) { return TypeDescription.OBJECT.getInternalName(); } else { do { leftType = leftType.getSuperClass().asErasure(); } while (!leftType.isAssignableFrom(rightType)); return leftType.getInternalName(); } } }
/** * {@inheritDoc} */ public Appender appender(Target implementationTarget) { if (implementationTarget.getInstrumentedType().isInterface()) { throw new IllegalStateException("Cannot implement meaningful toString method for " + implementationTarget.getInstrumentedType()); } String prefix = prefixResolver.resolve(implementationTarget.getInstrumentedType()); if (prefix == null) { throw new IllegalStateException("Prefix for toString method cannot be null"); } return new Appender(prefix, start, end, separator, definer, implementationTarget.getInstrumentedType().getDeclaredFields().filter(not(isStatic().or(ignored)))); }
/** * {@inheritDoc} */ public StackManipulation virtual(TypeDescription invocationTarget) { if (methodDescription.isConstructor() || methodDescription.isStatic()) { return Illegal.INSTANCE; } else if (methodDescription.isPrivate()) { return methodDescription.getDeclaringType().equals(invocationTarget) ? this : Illegal.INSTANCE; } else if (invocationTarget.isInterface()) { return methodDescription.getDeclaringType().represents(Object.class) ? this : INTERFACE.new Invocation(methodDescription, invocationTarget); } else { return VIRTUAL.new Invocation(methodDescription, invocationTarget); } }
/** * Creates a method invocation with an implicitly determined invocation type. * * @param methodDescription The method to be invoked. * @return A stack manipulation with implicitly determined invocation type. */ public static WithImplicitInvocationTargetType invoke(MethodDescription.InDefinedShape methodDescription) { if (methodDescription.isTypeInitializer()) { return IllegalInvocation.INSTANCE; } else if (methodDescription.isStatic()) { // Check this property first, private static methods must use INVOKESTATIC return STATIC.new Invocation(methodDescription); } else if (methodDescription.isConstructor()) { return SPECIAL_CONSTRUCTOR.new Invocation(methodDescription); // Check this property second, constructors might be private } else if (methodDescription.isPrivate()) { return (methodDescription.getDeclaringType().isInterface() ? INTERFACE_PRIVATE : VIRTUAL_PRIVATE).new Invocation(methodDescription); } else if (methodDescription.getDeclaringType().isInterface()) { // Check this property last, default methods must be called by INVOKESPECIAL return INTERFACE.new Invocation(methodDescription); } else { return VIRTUAL.new Invocation(methodDescription); } }
/** * {@inheritDoc} */ public ByteCodeAppender appender(Target implementationTarget) { if (implementationTarget.getInstrumentedType().isInterface()) { throw new IllegalStateException("Cannot implement meaningful hash code method for " + implementationTarget.getInstrumentedType()); } return new Appender(offsetProvider.resolve(implementationTarget.getInstrumentedType()), multiplier, implementationTarget.getInstrumentedType().getDeclaredFields().filter(not(isStatic().or(ignored))), nonNullable); }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { methodVisitor.visitMethodInsn(opcode == legacyOpcode || implementationContext.getClassFileVersion().isAtLeast(ClassFileVersion.JAVA_V11) ? opcode : legacyOpcode, typeDescription.getInternalName(), methodDescription.getInternalName(), methodDescription.getDescriptor(), typeDescription.isInterface()); int parameterSize = methodDescription.getStackSize(), returnValueSize = methodDescription.getReturnType().getStackSize().getSize(); return new Size(returnValueSize - parameterSize, Math.max(0, returnValueSize - parameterSize)); }
/** * {@inheritDoc} */ public ByteCodeAppender appender(Target implementationTarget) { if (implementationTarget.getInstrumentedType().isInterface()) { throw new IllegalStateException("Cannot implement meaningful equals method for " + implementationTarget.getInstrumentedType()); } List<FieldDescription.InDefinedShape> fields = new ArrayList<FieldDescription.InDefinedShape>(implementationTarget.getInstrumentedType() .getDeclaredFields() .filter(not(isStatic().or(ignored)))); Collections.sort(fields, comparator); return new Appender(implementationTarget.getInstrumentedType(), new StackManipulation.Compound( superClassCheck.resolve(implementationTarget.getInstrumentedType()), MethodVariableAccess.loadThis(), MethodVariableAccess.REFERENCE.loadFrom(1), ConditionalReturn.onIdentity().returningTrue(), typeCompatibilityCheck.resolve(implementationTarget.getInstrumentedType()) ), fields, nonNullable); }