/** * {@inheritDoc} */ public boolean matches(T target) { return matcher.matches(target.asSignatureToken()); }
/** * {@inheritDoc} */ public boolean matches(MethodDescription target) { return target.asSignatureToken().equals(signatureToken); } }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { return implementationTarget.invokeDefault(source.asSignatureToken()); } }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { return implementationTarget.invokeDefault(source.asSignatureToken()); } }
/** * {@inheritDoc} */ public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) { return implementationTarget.invokeDefault(source.asSignatureToken()); } }
/** {@inheritDoc} */ public Implementation.SpecialMethodInvocation invoke(Implementation.Target implementationTarget, TypeDescription proxiedType, MethodDescription instrumentedMethod) { return implementationTarget.invokeDominant(instrumentedMethod.asSignatureToken()); } },
/** {@inheritDoc} */ public Implementation.SpecialMethodInvocation invoke(Implementation.Target implementationTarget, TypeDescription proxiedType, MethodDescription instrumentedMethod) { return implementationTarget.invokeDefault(instrumentedMethod.asSignatureToken(), proxiedType); } };
/** * Returns a method graph that contains all of the provided methods as simple nodes. * * @param methodDescriptions A list of method descriptions to be represented as simple nodes. * @return A method graph that represents all of the provided methods as simple nodes. */ public static MethodGraph of(List<? extends MethodDescription> methodDescriptions) { LinkedHashMap<MethodDescription.SignatureToken, Node> nodes = new LinkedHashMap<MethodDescription.SignatureToken, Node>(); for (MethodDescription methodDescription : methodDescriptions) { nodes.put(methodDescription.asSignatureToken(), new Node.Simple(methodDescription)); } return new Simple(nodes); }
/** * {@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); } }
@Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof SpecialMethodInvocation)) { return false; } SpecialMethodInvocation specialMethodInvocation = (SpecialMethodInvocation) other; return getMethodDescription().asSignatureToken().equals(specialMethodInvocation.getMethodDescription().asSignatureToken()) && getTypeDescription().equals(specialMethodInvocation.getTypeDescription()); } }
@Override public int hashCode() { return 31 * getMethodDescription().asSignatureToken().hashCode() + getTypeDescription().hashCode(); }
/** * {@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 StackManipulation toStackManipulation(MethodDescription invokedMethod, Implementation.Target implementationTarget) { if (!invokedMethod.isInvokableOn(instrumentedType)) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " as default method of " + instrumentedType); } StackManipulation stackManipulation = implementationTarget.invokeDefault(invokedMethod.asSignatureToken(), invokedMethod.getDeclaringType().asErasure()); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + instrumentedType); } return stackManipulation; }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Implementation.Target implementationTarget) { if (!invokedMethod.isInvokableOn(implementationTarget.getOriginType().asErasure())) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " as super method of " + instrumentedType); } StackManipulation stackManipulation = implementationTarget.invokeDominant(invokedMethod.asSignatureToken()); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " as a super method"); } return stackManipulation; }
/** * Checks if a type declares a method with the same signature as {@code target}. * * @param target The method to be checked. * @param typeDefinition The type to check for declaring a method with the same signature as {@code target}. * @return {@code true} if the supplied type declares a compatible method. */ private boolean matches(MethodDescription target, TypeDefinition typeDefinition) { for (MethodDescription methodDescription : typeDefinition.getDeclaredMethods().filter(isVirtual())) { if (methodDescription.asSignatureToken().equals(target.asSignatureToken())) { if (matcher.matches(typeDefinition.asGenericType())) { return true; } else { break; } } } return false; }
/** * {@inheritDoc} */ public Linked compile(TypeDefinition typeDefinition, TypeDescription viewPoint) { LinkedHashMap<MethodDescription.SignatureToken, Node> nodes = new LinkedHashMap<MethodDescription.SignatureToken, Node>(); for (MethodDescription methodDescription : typeDefinition.getDeclaredMethods().filter(isVirtual().and(not(isBridge())).and(isVisibleTo(viewPoint)))) { nodes.put(methodDescription.asSignatureToken(), new Node.Simple(methodDescription)); } return new Linked.Delegation(new MethodGraph.Simple(nodes), Empty.INSTANCE, Collections.<TypeDescription, MethodGraph>emptyMap()); } }
/** * Locates a special method invocation to be invoked from a given method. * * @param methodDescription The method that is currently instrumented. * @return A potentially illegal stack manipulation representing the default method invocation for the * given method. */ private StackManipulation locateDefault(MethodDescription methodDescription) { MethodDescription.SignatureToken methodToken = methodDescription.asSignatureToken(); SpecialMethodInvocation specialMethodInvocation = SpecialMethodInvocation.Illegal.INSTANCE; for (TypeDescription typeDescription : prioritizedInterfaces) { specialMethodInvocation = implementationTarget.invokeDefault(methodToken, typeDescription); if (specialMethodInvocation.isValid()) { return specialMethodInvocation; } } for (TypeDescription typeDescription : nonPrioritizedInterfaces) { SpecialMethodInvocation other = implementationTarget.invokeDefault(methodToken, typeDescription); if (specialMethodInvocation.isValid() && other.isValid()) { throw new IllegalStateException(methodDescription + " has an ambiguous default method with " + other.getMethodDescription() + " and " + specialMethodInvocation.getMethodDescription()); } specialMethodInvocation = other; } return specialMethodInvocation; } }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) { StackManipulation superMethodCall = implementationTarget.invokeDominant(instrumentedMethod.asSignatureToken()); if (!superMethodCall.isValid()) { throw new IllegalStateException("Cannot call super (or default) method for " + instrumentedMethod); } StackManipulation.Size stackSize = new StackManipulation.Compound( MethodVariableAccess.allArgumentsOf(instrumentedMethod).prependThisReference(), superMethodCall, terminationHandler.of(instrumentedMethod) ).apply(methodVisitor, implementationContext); return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }
/** * {@inheritDoc} */ public MethodDelegationBinder.ParameterBinding<?> bind(final AnnotationDescription.Loadable<SuperMethod> annotation, MethodDescription source, ParameterDescription target, Implementation.Target implementationTarget, Assigner assigner, Assigner.Typing typing) { if (!target.getType().asErasure().isAssignableFrom(Method.class)) { throw new IllegalStateException("Cannot assign Method type to " + target); } else if (source.isMethod()) { Implementation.SpecialMethodInvocation specialMethodInvocation = annotation.loadSilent().fallbackToDefault() ? implementationTarget.invokeDominant(source.asSignatureToken()) : implementationTarget.invokeSuper(source.asSignatureToken()); if (specialMethodInvocation.isValid()) { return new MethodDelegationBinder.ParameterBinding.Anonymous(new DelegationMethod(specialMethodInvocation, annotation.loadSilent().cached(), annotation.loadSilent().privileged())); } else if (annotation.loadSilent().nullIfImpossible()) { return new MethodDelegationBinder.ParameterBinding.Anonymous(NullConstant.INSTANCE); } else { return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE; } } else if (annotation.loadSilent().nullIfImpossible()) { return new MethodDelegationBinder.ParameterBinding.Anonymous(NullConstant.INSTANCE); } else { return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE; } }