use of net.bytebuddy.description.type.TypeDescription in project byte-buddy by raphw.
the class MethodCallProxy method extractFields.
/**
* 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;
}
use of net.bytebuddy.description.type.TypeDescription in project byte-buddy by raphw.
the class MethodCallProxy method make.
@Override
public DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory) {
MethodDescription accessorMethod = methodAccessorFactory.registerAccessorFor(specialMethodInvocation, MethodAccessorFactory.AccessType.DEFAULT);
LinkedHashMap<String, TypeDescription> parameterFields = extractFields(accessorMethod);
DynamicType.Builder<?> builder = new ByteBuddy(classFileVersion).with(PrecomputedMethodGraph.INSTANCE).subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS).name(auxiliaryTypeName).modifiers(DEFAULT_TYPE_MODIFIER).implement(Runnable.class, Callable.class).intercept(new MethodCall(accessorMethod, assigner)).implement(serializableProxy ? new Class<?>[] { Serializable.class } : new Class<?>[0]).defineConstructor().withParameters(parameterFields.values()).intercept(ConstructorCall.INSTANCE);
for (Map.Entry<String, TypeDescription> field : parameterFields.entrySet()) {
builder = builder.defineField(field.getKey(), field.getValue(), Visibility.PRIVATE);
}
return builder.make();
}
use of net.bytebuddy.description.type.TypeDescription in project byte-buddy by raphw.
the class AndroidClassLoadingStrategy method load.
@Override
public Map<TypeDescription, Class<?>> load(ClassLoader classLoader, Map<TypeDescription, byte[]> types) {
DexProcessor.Conversion conversion = dexProcessor.create();
for (Map.Entry<TypeDescription, byte[]> entry : types.entrySet()) {
conversion.register(entry.getKey().getName(), entry.getValue());
}
File jar = new File(privateDirectory, randomString.nextString() + JAR_FILE_EXTENSION);
try {
if (!jar.createNewFile()) {
throw new IllegalStateException("Cannot create " + jar);
}
JarOutputStream zipOutputStream = new JarOutputStream(new FileOutputStream(jar));
try {
zipOutputStream.putNextEntry(new JarEntry(DEX_CLASS_FILE));
conversion.drainTo(zipOutputStream);
zipOutputStream.closeEntry();
} finally {
zipOutputStream.close();
}
return doLoad(classLoader, types.keySet(), jar);
} catch (IOException exception) {
throw new IllegalStateException("Cannot write to zip file " + jar, exception);
} finally {
if (!jar.delete()) {
Logger.getLogger("net.bytebuddy").warning("Could not delete " + jar);
}
}
}
use of net.bytebuddy.description.type.TypeDescription in project byte-buddy by raphw.
the class LambdaFactory method register.
/**
* Registers a class file transformer together with a factory for creating a lambda expression. It is possible to call this method independently
* of the class loader's context as the supplied injector makes sure that the manipulated collection is the one that is held by the system class
* loader.
*
* @param classFileTransformer The class file transformer to register.
* @param classFileFactory The lambda class file factory to use. This factory must define a visible instance method with the signature
* {@code byte[] make(Object, String, Object, Object, Object, Object, boolean, List, List, Collection}. The arguments provided
* are the invokedynamic call site's lookup object, the lambda method's name, the factory method's type, the lambda method's
* type, the target method's handle, the specialized method type of the lambda expression, a boolean to indicate
* serializability, a list of marker interfaces, a list of additional bridges and a collection of class file transformers to
* apply.
* @return {@code true} if this is the first registered transformer. This indicates that the {@code LambdaMetafactory} must be instrumented to delegate
* to this alternative factory.
*/
@SuppressWarnings("all")
public static boolean register(ClassFileTransformer classFileTransformer, Object classFileFactory) {
try {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(LambdaFactory.class);
Class<?> lambdaFactory = ClassInjector.UsingReflection.ofSystemClassLoader().inject(Collections.singletonMap(typeDescription, ClassFileLocator.ForClassLoader.read(LambdaFactory.class).resolve())).get(typeDescription);
@SuppressWarnings("unchecked") Map<ClassFileTransformer, Object> classFileTransformers = (Map<ClassFileTransformer, Object>) lambdaFactory.getField(FIELD_NAME).get(null);
synchronized (classFileTransformers) {
try {
return classFileTransformers.isEmpty();
} finally {
classFileTransformers.put(classFileTransformer, lambdaFactory.getConstructor(Object.class, Method.class).newInstance(classFileFactory, classFileFactory.getClass().getMethod("make", Object.class, String.class, Object.class, Object.class, Object.class, Object.class, boolean.class, List.class, List.class, Collection.class)));
}
}
} catch (RuntimeException exception) {
throw exception;
} catch (Exception exception) {
throw new IllegalStateException("Could not register class file transformer", exception);
}
}
use of net.bytebuddy.description.type.TypeDescription in project byte-buddy by raphw.
the class MethodAttributeAppenderForInstrumentedMethodOtherTest method testExcludingFactory.
@Test
public void testExcludingFactory() throws Exception {
TypeDescription typeDescription = mock(TypeDescription.class);
assertThat(MethodAttributeAppender.ForInstrumentedMethod.EXCLUDING_RECEIVER.make(typeDescription), is((MethodAttributeAppender) MethodAttributeAppender.ForInstrumentedMethod.EXCLUDING_RECEIVER));
}
Aggregations