예제 #1
0
 /**
  * Returns a prepared entry for a supplementary method.
  *
  * @param methodDescription The method to be implemented.
  * @return An entry for a supplementary entry that is defined by a method implementation
  *     instance.
  */
 protected Prepared.Entry asSupplementaryEntry(MethodDescription methodDescription) {
   return new Prepared.Entry(
       handler,
       new MethodAttributeAppender.ForMethod(
           methodDescription, AnnotationAppender.ValueFilter.AppendDefaults.INSTANCE),
       methodDescription,
       Collections.<MethodDescription.TypeToken>emptySet());
 }
예제 #2
0
 @Override
 public MethodRegistry.Prepared prepare(
     InstrumentedType instrumentedType,
     MethodGraph.Compiler methodGraphCompiler,
     LatentMethodMatcher methodFilter) {
   LinkedHashMap<MethodDescription, Prepared.Entry> implementations =
       new LinkedHashMap<MethodDescription, Prepared.Entry>();
   Set<Handler> handlers = new HashSet<Handler>(entries.size());
   MethodList<?> helperMethods = instrumentedType.getDeclaredMethods();
   for (Entry entry : entries) {
     if (handlers.add(entry.getHandler())) {
       instrumentedType = entry.getHandler().prepare(instrumentedType);
       ElementMatcher<? super MethodDescription> handledMethods = noneOf(helperMethods);
       helperMethods = instrumentedType.getDeclaredMethods();
       for (MethodDescription helperMethod : helperMethods.filter(handledMethods)) {
         implementations.put(helperMethod, entry.asSupplementaryEntry(helperMethod));
       }
     }
   }
   MethodGraph.Linked methodGraph = methodGraphCompiler.compile(instrumentedType);
   // Casting required for Java 6 compiler.
   ElementMatcher<? super MethodDescription> relevanceMatcher =
       (ElementMatcher<? super MethodDescription>)
           not(anyOf(implementations.keySet())).and(methodFilter.resolve(instrumentedType));
   for (MethodGraph.Node node : methodGraph.listNodes()) {
     MethodDescription methodDescription = node.getRepresentative();
     boolean visibilityBridge = instrumentedType.isPublic() && !instrumentedType.isInterface();
     if (relevanceMatcher.matches(methodDescription)) {
       for (Entry entry : entries) {
         if (entry.resolve(instrumentedType).matches(methodDescription)) {
           implementations.put(
               methodDescription,
               entry.asPreparedEntry(
                   instrumentedType, methodDescription, node.getMethodTypes()));
           visibilityBridge = false;
           break;
         }
       }
     }
     if (visibilityBridge
         && methodDescription.isPublic()
         && !(methodDescription.isAbstract() || methodDescription.isFinal())
         && !node.getSort().isMadeVisible()
         && methodDescription.getDeclaringType().asErasure().isPackagePrivate()) {
       // Visibility bridges are required for public types that inherit a public method from a
       // package-private type.
       // Checking the last condition contradicts any method that is defined by the instrumented
       // type itself.
       implementations.put(
           methodDescription,
           Prepared.Entry.forVisibilityBridge(methodDescription, node.getMethodTypes()));
     }
   }
   MethodDescription typeInitializer =
       new MethodDescription.Latent.TypeInitializer(instrumentedType);
   for (Entry entry : entries) {
     if (entry.resolve(instrumentedType).matches(typeInitializer)) {
       implementations.put(
           typeInitializer,
           entry.asPreparedEntry(
               instrumentedType,
               typeInitializer,
               Collections.<MethodDescription.TypeToken>emptySet()));
       break;
     }
   }
   return new Prepared(
       implementations,
       instrumentedType.getLoadedTypeInitializer(),
       instrumentedType.getTypeInitializer(),
       instrumentedType.asErasure(),
       methodGraph);
 }