/** * Attaches all types to the given method description. * * @param methodDescription The method description to which visited types should be attached to. * @return A substitutor that attaches visited types to the given method's type context. */ public static ForAttachment of(MethodDescription methodDescription) { return new ForAttachment(methodDescription.getDeclaringType(), methodDescription); }
/** * {@inheritDoc} */ public boolean matches(T target) { Set<TypeDescription> duplicates = new HashSet<TypeDescription>(); for (TypeDefinition typeDefinition : target.getDeclaringType()) { if (matches(target, typeDefinition) || matches(target, typeDefinition.getInterfaces(), duplicates)) { return true; } } return false; }
/** * {@inheritDoc} */ public Entry<U> extendBy(MethodDescription methodDescription, Harmonizer<U> harmonizer) { Harmonized<U> key = this.key.extend(methodDescription.asDefined(), harmonizer); Visibility visibility = this.visibility.expandTo(methodDescription.getVisibility()); return methodDescription.getDeclaringType().equals(this.methodDescription.getDeclaringType()) ? Ambiguous.of(key, methodDescription, this.methodDescription, visibility) : Resolved.of(key, methodDescription, this.methodDescription, visibility); }
@Override protected StackManipulation resolve(MethodDescription interceptedMethod, TypeDescription returnType, Assigner assigner, Assigner.Typing typing) { return Removal.of(interceptedMethod.isConstructor() ? interceptedMethod.getDeclaringType() : interceptedMethod.getReturnType()); } };
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) { return new StackManipulation.Compound(TypeCreation.of(invokedMethod.getDeclaringType().asErasure()), Duplication.SINGLE); }
/** {@inheritDoc} */ public StackManipulation resolve(Assigner assigner, Assigner.Typing typing, MethodDescription source, MethodDescription target) { return Removal.of(target.isConstructor() ? target.getDeclaringType() : target.getReturnType()); } };
/** * Attaches all types to the given parameter description. * * @param parameterDescription The parameter description to which visited types should be attached to. * @return A substitutor that attaches visited types to the given parameter's type context. */ public static ForAttachment of(ParameterDescription parameterDescription) { return new ForAttachment(parameterDescription.getDeclaringMethod().getDeclaringType(), parameterDescription.getDeclaringMethod()); }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) { return Removal.of(invokedMethod.isConstructor() ? invokedMethod.getDeclaringType() : invokedMethod.getReturnType()); } },
/** * {@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; }
/** * Creates a linked hash map of field names to their types where each field represents a parameter of the method. * * @param methodDescription The method to extract into fields. * @return A map of fields in the order they need to be loaded onto the operand stack for invoking the original * method, including a reference to the instance of the instrumented type that is invoked if applicable. */ private static LinkedHashMap<String, TypeDescription> extractFields(MethodDescription methodDescription) { LinkedHashMap<String, TypeDescription> typeDescriptions = new LinkedHashMap<String, TypeDescription>(); int currentIndex = 0; if (!methodDescription.isStatic()) { typeDescriptions.put(fieldName(currentIndex++), methodDescription.getDeclaringType().asErasure()); } for (ParameterDescription parameterDescription : methodDescription.getParameters()) { typeDescriptions.put(fieldName(currentIndex++), parameterDescription.getType().asErasure()); } return typeDescriptions; }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) { StackManipulation stackManipulation = assigner.assign(parameterDescription.getType(), invokedMethod.getDeclaringType().asGenericType(), typing); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + parameterDescription.getType()); } return new StackManipulation.Compound(MethodVariableAccess.load(parameterDescription), stackManipulation); } }
/** * {@inheritDoc} */ public MethodDescription transform(TypeDescription instrumentedType, MethodDescription methodDescription) { return new TransformedMethod(instrumentedType, methodDescription.getDeclaringType(), transformer.transform(instrumentedType, methodDescription.asToken(none())), methodDescription.asDefined()); }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) { StackManipulation stackManipulation = assigner.assign(fieldDescription.getType(), invokedMethod.getDeclaringType().asGenericType(), typing); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldDescription); } return new StackManipulation.Compound( FieldAccess.forField(fieldDescription).read(), stackManipulation ); }
@Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof MethodDescription)) { return false; } MethodDescription methodDescription = (MethodDescription) other; return getInternalName().equals(methodDescription.getInternalName()) && getDeclaringType().equals(methodDescription.getDeclaringType()) && getReturnType().asErasure().equals(methodDescription.getReturnType().asErasure()) && getParameters().asTypeList().asErasures().equals(methodDescription.getParameters().asTypeList().asErasures()); }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) { StackManipulation stackManipulation = assigner.assign(methodDescription.getReturnType(), invokedMethod.getDeclaringType().asGenericType(), typing); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + methodDescription.getReturnType()); } return new StackManipulation.Compound(appender.toStackManipulation(instrumentedMethod, methodDescription, targetHandler), stackManipulation); } }
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) { StackManipulation stackManipulation = assigner.assign(invokedMethod.isConstructor() ? invokedMethod.getDeclaringType().asGenericType() : invokedMethod.getReturnType(), instrumentedMethod.getReturnType(), typing); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot return " + invokedMethod.getReturnType() + " from " + instrumentedMethod); } return new StackManipulation.Compound(stackManipulation, MethodReturn.of(instrumentedMethod.getReturnType())); } },
/** * {@inheritDoc} */ public StackManipulation toStackManipulation(MethodDescription invokedMethod, Assigner assigner, Assigner.Typing typing) { if (!invokedMethod.isInvokableOn(fieldDescription.getType().asErasure())) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldDescription); } StackManipulation stackManipulation = assigner.assign(fieldDescription.getType(), invokedMethod.getDeclaringType().asGenericType(), typing); if (!stackManipulation.isValid()) { throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldDescription); } return new StackManipulation.Compound(invokedMethod.isStatic() || fieldDescription.isStatic() ? StackManipulation.Trivial.INSTANCE : MethodVariableAccess.loadThis(), FieldAccess.forField(fieldDescription).read(), stackManipulation); }
/** {@inheritDoc} */ public StackManipulation resolve(Assigner assigner, Assigner.Typing typing, MethodDescription source, MethodDescription target) { return new StackManipulation.Compound(assigner.assign(target.isConstructor() ? target.getDeclaringType().asGenericType() : target.getReturnType(), source.getReturnType(), typing), MethodReturn.of(source.getReturnType())); } },
/** * Creates an entry for an override where a method overrides another method within a super class. * * @param key The merged key for both methods. * @param override The method declared by the extending type, potentially a bridge method. * @param original The method that is overridden by the extending type. * @param visibility The minimal required visibility for this entry. * @param <V> The type of the harmonized key to determine method equality. * @return An entry representing the merger of both methods. */ private static <V> Entry<V> of(Harmonized<V> key, MethodDescription override, MethodDescription original, Visibility visibility) { visibility = visibility.expandTo(original.getVisibility()).expandTo(override.getVisibility()); return override.isBridge() ? new Resolved<V>(key, original, visibility, (original.getDeclaringType().getModifiers() & MADE_VISIBLE) == 0) : new Resolved<V>(key, override, visibility, NOT_MADE_VISIBLE); }
/** * {@inheritDoc} */ public Resolved resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) { return new Resolved.Simple(MethodVariableAccess.allArgumentsOf(instrumentedMethod).prependThisReference(), instrumentedMethod.isStatic() ? instrumentedMethod.getParameters().asTypeList().asErasures() : CompoundList.of(instrumentedMethod.getDeclaringType().asErasure(), instrumentedMethod.getParameters().asTypeList().asErasures())); }