예제 #1
0
 /**
  * Creates a method handle representation of the given method.
  *
  * @param methodDescription The method ro represent.
  * @return A method handle representing the given method.
  */
 public static MethodHandle of(MethodDescription methodDescription) {
   return new MethodHandle(
       HandleType.of(methodDescription),
       methodDescription.getDeclaringType().asRawType(),
       methodDescription.getInternalName(),
       methodDescription.getReturnType().asRawType(),
       methodDescription.getParameters().asTypeList().asRawTypes());
 }
예제 #2
0
 /**
  * Extracts a handle type for invoking the given method.
  *
  * @param methodDescription The method for which a handle type should be found.
  * @return The handle type for the given method.
  */
 protected static HandleType of(MethodDescription methodDescription) {
   if (methodDescription.isStatic()) {
     return INVOKE_STATIC;
   } else if (methodDescription.isPrivate()) {
     return INVOKE_SPECIAL;
   } else if (methodDescription.isConstructor()) {
     return INVOKE_SPECIAL_CONSTRUCTOR;
   } else if (methodDescription.getDeclaringType().asRawType().isInterface()) {
     return INVOKE_INTERFACE;
   } else {
     return INVOKE_VIRTUAL;
   }
 }
 @Before
 public void setUp() throws Exception {
   when(methodDescription.getDeclaringType()).thenReturn(typeDescription);
   when(methodDescription.getReturnType()).thenReturn(returnType);
   when(methodDescription.getInternalName()).thenReturn(FOO);
   when(methodDescription.getDescriptor()).thenReturn(BAZ);
   when(typeDescription.getInternalName()).thenReturn(BAR);
   when(typeDescription.getDescriptor()).thenReturn(BAR);
   when(methodNameTransformer.transform(methodDescription)).thenReturn(QUX);
   when(otherMethodNameTransformer.transform(methodDescription)).thenReturn(FOO + BAR);
   when(parameterType.getStackSize()).thenReturn(StackSize.ZERO);
   ParameterList parameterList =
       ParameterList.Explicit.latent(methodDescription, Collections.singletonList(parameterType));
   when(methodDescription.getParameters()).thenReturn(parameterList);
 }
예제 #4
0
 /**
  * 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) {
   ParameterList<?> parameters = methodDescription.getParameters();
   LinkedHashMap<String, TypeDescription> typeDescriptions =
       new LinkedHashMap<String, TypeDescription>(
           (methodDescription.isStatic() ? 0 : 1) + parameters.size());
   int currentIndex = 0;
   if (!methodDescription.isStatic()) {
     typeDescriptions.put(
         fieldName(currentIndex++), methodDescription.getDeclaringType().asErasure());
   }
   for (ParameterDescription parameterDescription : parameters) {
     typeDescriptions.put(fieldName(currentIndex++), parameterDescription.getType().asErasure());
   }
   return typeDescriptions;
 }
 @Override
 @Before
 public void setUp() throws Exception {
   when(parameterList.asTypeList()).thenReturn(parameterTypes);
   when(instrumentedType.getSupertype()).thenReturn(superType);
   when(superType.getDeclaredMethods())
       .thenReturn(new MethodList.Explicit(Collections.singletonList(superMethodConstructor)));
   when(superType.getInternalName()).thenReturn(BAR);
   when(superMethod.getDeclaringType()).thenReturn(superType);
   when(superType.getStackSize()).thenReturn(StackSize.ZERO);
   when(superMethod.getReturnType()).thenReturn(returnType);
   when(superMethod.getInternalName()).thenReturn(BAZ);
   when(superMethod.getDescriptor()).thenReturn(FOOBAR);
   when(superMethod.getParameters()).thenReturn(parameterList);
   when(superMethodConstructor.isConstructor()).thenReturn(true);
   when(superMethodConstructor.getParameters()).thenReturn(parameterList);
   when(superMethodConstructor.getReturnType()).thenReturn(returnType);
   when(superMethodConstructor.isSpecializableFor(superType)).thenReturn(true);
   when(superMethodConstructor.getInternalName()).thenReturn(QUXBAZ);
   when(superMethodConstructor.getDescriptor()).thenReturn(BAZBAR);
   super.setUp();
 }
예제 #6
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);
 }