示例#1
0
 @Override
 public MethodRegistry.Compiled compile(
     Implementation.Target.Factory implementationTargetFactory) {
   Map<Handler, Handler.Compiled> compilationCache =
       new HashMap<Handler, Handler.Compiled>(implementations.size());
   Map<MethodAttributeAppender.Factory, MethodAttributeAppender> attributeAppenderCache =
       new HashMap<MethodAttributeAppender.Factory, MethodAttributeAppender>(
           implementations.size());
   LinkedHashMap<MethodDescription, Compiled.Entry> entries =
       new LinkedHashMap<MethodDescription, Compiled.Entry>(implementations.size());
   Implementation.Target implementationTarget =
       implementationTargetFactory.make(instrumentedType, methodGraph);
   for (Map.Entry<MethodDescription, Entry> entry : implementations.entrySet()) {
     Handler.Compiled cachedHandler = compilationCache.get(entry.getValue().getHandler());
     if (cachedHandler == null) {
       cachedHandler = entry.getValue().getHandler().compile(implementationTarget);
       compilationCache.put(entry.getValue().getHandler(), cachedHandler);
     }
     MethodAttributeAppender cachedAttributeAppender =
         attributeAppenderCache.get(entry.getValue().getAppenderFactory());
     if (cachedAttributeAppender == null) {
       cachedAttributeAppender = entry.getValue().getAppenderFactory().make(instrumentedType);
       attributeAppenderCache.put(
           entry.getValue().getAppenderFactory(), cachedAttributeAppender);
     }
     entries.put(
         entry.getKey(),
         new Compiled.Entry(
             cachedHandler,
             cachedAttributeAppender,
             entry.getValue().getMethodDescription(),
             entry.getValue().resolveBridgeTypes()));
   }
   return new Compiled(instrumentedType, loadedTypeInitializer, typeInitializer, entries);
 }
示例#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);
 }