/** * {@inheritDoc} */ public boolean matches(T target) { return matcher.matches(target.getDeclaredMethods()); }
/** * {@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()); } }
/** * {@inheritDoc} */ public MethodDescription resolve(TypeDescription targetType, ByteCodeElement target, TypeList.Generic parameters, TypeDescription.Generic result) { if (parameters.isEmpty()) { throw new IllegalStateException("Cannot substitute parameterless instruction with " + target); } else if (parameters.get(0).isPrimitive() || parameters.get(0).isArray()) { throw new IllegalStateException("Cannot invoke method on primitive or array type for " + target); } TypeDefinition typeDefinition = parameters.get(0); List<MethodDescription> candidates = CompoundList.<MethodDescription>of(methodGraphCompiler.compile(typeDefinition, instrumentedType) .listNodes() .asMethodList() .filter(matcher), typeDefinition.getDeclaredMethods().filter(isPrivate().<MethodDescription>and(isVisibleTo(instrumentedType)).and(matcher))); if (candidates.size() == 1) { return candidates.get(0); } else { throw new IllegalStateException("Not exactly one method that matches " + matcher + ": " + candidates); } } }
/** * 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; }
/** * Analyzes the given type description without checking if it is already presented in the key store. * * @param typeDefinition The type to analyze. * @param snapshots A map containing snapshots of key stores for previously analyzed types. * @param relevanceMatcher A matcher for filtering methods that should be included in the graph. * @return A key store describing the provided type. */ protected Key.Store<T> doAnalyze(TypeDefinition typeDefinition, Map<TypeDefinition, Key.Store<T>> snapshots, ElementMatcher<? super MethodDescription> relevanceMatcher) { Key.Store<T> store = analyzeNullable(typeDefinition.getSuperClass(), snapshots, relevanceMatcher); Key.Store<T> interfaceStore = new Key.Store<T>(); for (TypeDescription.Generic interfaceType : typeDefinition.getInterfaces()) { interfaceStore = interfaceStore.combineWith(analyze(interfaceType.accept(visitor), interfaceType, snapshots, relevanceMatcher)); } return store.inject(interfaceStore).registerTopLevel(typeDefinition.getDeclaredMethods().filter(relevanceMatcher), harmonizer); }
@Override protected HashCodeMethod hashCodeMethod(TypeDescription instrumentedType) { TypeDefinition typeDefinition = instrumentedType.getSuperClass(); while (typeDefinition != null && !typeDefinition.represents(Object.class)) { if (typeDefinition.asErasure().getDeclaredAnnotations().isAnnotationPresent(Enhance.class)) { return HashCodeMethod.usingSuperClassOffset(); } MethodList<?> hashCode = typeDefinition.getDeclaredMethods().filter(isHashCode()); if (!hashCode.isEmpty()) { return hashCode.getOnly().isAbstract() ? HashCodeMethod.usingDefaultOffset() : HashCodeMethod.usingSuperClassOffset(); } typeDefinition = typeDefinition.getSuperClass(); } return HashCodeMethod.usingDefaultOffset(); }
@Override protected EqualsMethod equalsMethod(TypeDescription instrumentedType) { TypeDefinition typeDefinition = instrumentedType.getSuperClass(); while (typeDefinition != null && !typeDefinition.represents(Object.class)) { if (typeDefinition.asErasure().getDeclaredAnnotations().isAnnotationPresent(Enhance.class)) { return EqualsMethod.requiringSuperClassEquality(); } MethodList<?> hashCode = typeDefinition.getDeclaredMethods().filter(isHashCode()); if (!hashCode.isEmpty()) { return hashCode.getOnly().isAbstract() ? EqualsMethod.isolated() : EqualsMethod.requiringSuperClassEquality(); } typeDefinition = typeDefinition.getSuperClass().asErasure(); } return EqualsMethod.isolated(); } },
final TypeReference targetType = MetadataSystem.instance().lookupType("CallInspectionSample$Target"); final TypeDefinition resolvedType = targetType.resolve(); final MethodDefinition mainMethod = resolvedType.getDeclaredMethods().get(1); final MethodDefinition getTextMethod = resolvedType.getDeclaredMethods().get(2);
/** * {@inheritDoc} */ public MethodGraph.Linked compile(TypeDefinition typeDefinition, TypeDescription viewPoint) { LinkedHashMap<MethodDescription.SignatureToken, MethodGraph.Node> nodes = new LinkedHashMap<MethodDescription.SignatureToken, MethodGraph.Node>(); for (MethodDescription methodDescription : typeDefinition.getDeclaredMethods() .filter( // ignores all methods which refer to unknown types failSafe( isVirtual() .and(not(isBridge())) .and(isVisibleTo(viewPoint)) .and(hasParameters(whereNone(hasType(not(isVisibleTo(viewPoint)))))) ) ) ) { nodes.put(methodDescription.asSignatureToken(), new MethodGraph.Node.Simple(methodDescription)); } return new MethodGraph.Linked.Delegation(new MethodGraph.Simple(nodes), MethodGraph.Empty.INSTANCE, Collections.<TypeDescription, MethodGraph>emptyMap()); } }