All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testifyproject.bytebuddy.asm.MemberRemoval Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
package org.testifyproject.bytebuddy.asm;

import lombok.EqualsAndHashCode;
import org.testifyproject.bytebuddy.description.field.FieldDescription;
import org.testifyproject.bytebuddy.description.field.FieldList;
import org.testifyproject.bytebuddy.description.method.MethodDescription;
import org.testifyproject.bytebuddy.description.method.MethodList;
import org.testifyproject.bytebuddy.description.type.TypeDescription;
import org.testifyproject.bytebuddy.implementation.Implementation;
import org.testifyproject.bytebuddy.matcher.ElementMatcher;
import org.testifyproject.bytebuddy.matcher.ElementMatchers;
import org.testifyproject.bytebuddy.pool.TypePool;
import org.testifyproject.bytebuddy.utility.CompoundList;
import org.testifyproject.bytebuddy.jar.asm.ClassVisitor;
import org.testifyproject.bytebuddy.jar.asm.FieldVisitor;
import org.testifyproject.bytebuddy.jar.asm.MethodVisitor;
import org.testifyproject.bytebuddy.jar.asm.Opcodes;

import java.util.HashMap;
import java.util.Map;

import static org.testifyproject.bytebuddy.matcher.ElementMatchers.isConstructor;
import static org.testifyproject.bytebuddy.matcher.ElementMatchers.isMethod;

/**
 * 

* A visitor wrapper that removes fields or methods that match a given {@link ElementMatcher}. *

*

* Important: This matcher is not capable of removing synthetic bridge methods which will be retained if they are * declared by the same class. As bridge methods only invoke an overridden method, the dispatch should however not be * influenced by their retention. *

*

* Important: The removal of the method is not reflected in the created {@link org.testifyproject.bytebuddy.dynamic.DynamicType}'s * type description of the instrumented type. *

*/ @EqualsAndHashCode(callSuper = false) public class MemberRemoval extends AsmVisitorWrapper.AbstractBase { /** * The matcher that decides upon field removal. */ private final ElementMatcher.Junction fieldMatcher; /** * The matcher that decides upon method removal. */ private final ElementMatcher.Junction methodMatcher; /** * Creates a new member removal instance that does not specify the removal of any methods. */ public MemberRemoval() { this(ElementMatchers.none(), ElementMatchers.none()); } /** * Creates a new member removal instance. * * @param fieldMatcher The matcher that decides upon field removal. * @param methodMatcher The matcher that decides upon field removal. */ protected MemberRemoval(ElementMatcher.Junction fieldMatcher, ElementMatcher.Junction methodMatcher) { this.fieldMatcher = fieldMatcher; this.methodMatcher = methodMatcher; } /** * Specifies that any field that matches the specified matcher should be removed. * * @param matcher The matcher that decides upon field removal. * @return A new member removal instance that removes all previously specified members and any fields that match the specified matcher. */ public MemberRemoval stripFields(ElementMatcher matcher) { return new MemberRemoval(fieldMatcher.or(matcher), methodMatcher); } /** * Specifies that any method that matches the specified matcher should be removed. * * @param matcher The matcher that decides upon method removal. * @return A new member removal instance that removes all previously specified members and any method that matches the specified matcher. */ public MemberRemoval stripMethods(ElementMatcher matcher) { return stripInvokables(isMethod().and(matcher)); } /** * Specifies that any constructor that matches the specified matcher should be removed. * * @param matcher The matcher that decides upon constructor removal. * @return A new member removal instance that removes all previously specified members and any constructor that matches the specified matcher. */ public MemberRemoval stripConstructors(ElementMatcher matcher) { return stripInvokables(isConstructor().and(matcher)); } /** * Specifies that any method or constructor that matches the specified matcher should be removed. * * @param matcher The matcher that decides upon method and constructor removal. * @return A new member removal instance that removes all previously specified members and any method or constructor that matches the specified matcher. */ public MemberRemoval stripInvokables(ElementMatcher matcher) { return new MemberRemoval(fieldMatcher, methodMatcher.or(matcher)); } @Override public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVisitor, Implementation.Context implementationContext, TypePool typePool, FieldList fields, MethodList methods, int writerFlags, int readerFlags) { Map mappedFields = new HashMap(); for (FieldDescription.InDefinedShape fieldDescription : fields) { mappedFields.put(fieldDescription.getInternalName() + fieldDescription.getDescriptor(), fieldDescription); } Map mappedMethods = new HashMap(); for (MethodDescription methodDescription : CompoundList.of(methods, new MethodDescription.Latent.TypeInitializer(instrumentedType))) { mappedMethods.put(methodDescription.getInternalName() + methodDescription.getDescriptor(), methodDescription); } return new MemberRemovingClassVisitor(classVisitor, fieldMatcher, methodMatcher, mappedFields, mappedMethods); } /** * A class visitor that removes members based on element matchers. */ protected static class MemberRemovingClassVisitor extends ClassVisitor { /** * Indicates the removal of a field. */ private static final FieldVisitor REMOVE_FIELD = null; /** * Indicates the removal of a method. */ private static final MethodVisitor REMOVE_METHOD = null; /** * The matcher that determines field removal. */ private final ElementMatcher.Junction fieldMatcher; /** * The matcher that determines method removal. */ private final ElementMatcher.Junction methodMatcher; /** * A mapping of field names and descriptors to their description. */ private final Map fields; /** * A mapping of method names and descriptors to their description. */ private final Map methods; /** * Creates a new member removing class visitor. * * @param classVisitor The class visitor to delegate to. * @param fieldMatcher The matcher that determines field removal. * @param methodMatcher The matcher that determines method removal. * @param fields A mapping of field names and descriptors to their description. * @param methods A mapping of method names and descriptors to their description. */ protected MemberRemovingClassVisitor(ClassVisitor classVisitor, ElementMatcher.Junction fieldMatcher, ElementMatcher.Junction methodMatcher, Map fields, Map methods) { super(Opcodes.ASM6, classVisitor); this.fieldMatcher = fieldMatcher; this.methodMatcher = methodMatcher; this.fields = fields; this.methods = methods; } @Override public FieldVisitor visitField(int modifiers, String internalName, String descriptor, String signature, Object value) { FieldDescription.InDefinedShape fieldDescription = fields.get(internalName + descriptor); return fieldDescription != null && fieldMatcher.matches(fieldDescription) ? REMOVE_FIELD : super.visitField(modifiers, internalName, descriptor, signature, value); } @Override public MethodVisitor visitMethod(int modifiers, String internalName, String descriptor, String signature, String[] exception) { MethodDescription methodDescription = methods.get(internalName + descriptor); return methodDescription != null && methodMatcher.matches(methodDescription) ? REMOVE_METHOD : super.visitMethod(modifiers, internalName, descriptor, signature, exception); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy