Skip to content

Commit

Permalink
Use signature token rather then method token to avoid matching based …
Browse files Browse the repository at this point in the history
…on non-essential properties.
  • Loading branch information
raphw committed Dec 19, 2020
1 parent 2738fbc commit 7e0a874
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
Expand All @@ -42,6 +43,22 @@ public interface MethodList<T extends MethodDescription> extends FilterableList<
*/
ByteCodeElement.Token.TokenList<MethodDescription.Token> asTokenList(ElementMatcher<? super TypeDescription> matcher);

/**
* Returns a list of signature tokens for this list of methods.
*
* @return A list of signature tokens for this list of methods.
*/
List<MethodDescription.SignatureToken> asSignatureTokenList();

/**
* Returns a list of signature tokens for this list of methods.
*
* @param matcher A matcher for resolving methods to {@link net.bytebuddy.description.method.MethodDescription.Token}s.
* @param typeDescription The type description to resolve the {@link net.bytebuddy.description.method.MethodDescription.SignatureToken}s to.
* @return A list of signature tokens for this list of methods.
*/
List<MethodDescription.SignatureToken> asSignatureTokenList(ElementMatcher<? super TypeDescription> matcher, TypeDescription typeDescription);

/**
* Returns this list of these method descriptions resolved to their defined shape.
*
Expand Down Expand Up @@ -72,6 +89,28 @@ public ByteCodeElement.Token.TokenList<MethodDescription.Token> asTokenList(Elem
return new ByteCodeElement.Token.TokenList<MethodDescription.Token>(tokens);
}

/**
* {@inheritDoc}
*/
public List<MethodDescription.SignatureToken> asSignatureTokenList() {
List<MethodDescription.SignatureToken> tokens = new ArrayList<MethodDescription.SignatureToken>(size());
for (MethodDescription methodDescription : this) {
tokens.add(methodDescription.asSignatureToken());
}
return tokens;
}

/**
* {@inheritDoc}
*/
public List<MethodDescription.SignatureToken> asSignatureTokenList(ElementMatcher<? super TypeDescription> matcher, TypeDescription typeDescription) {
List<MethodDescription.SignatureToken> tokens = new ArrayList<MethodDescription.SignatureToken>(size());
for (MethodDescription methodDescription : this) {
tokens.add(methodDescription.asToken(matcher).asSignatureToken(typeDescription));
}
return tokens;
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -311,6 +350,20 @@ public ByteCodeElement.Token.TokenList<MethodDescription.Token> asTokenList(Elem
return new ByteCodeElement.Token.TokenList<MethodDescription.Token>();
}

/**
* {@inheritDoc}
*/
public List<MethodDescription.SignatureToken> asSignatureTokenList() {
return Collections.<MethodDescription.SignatureToken>emptyList();
}

/**
* {@inheritDoc}
*/
public List<MethodDescription.SignatureToken> asSignatureTokenList(ElementMatcher<? super TypeDescription> matcher, TypeDescription typeDescription) {
return Collections.<MethodDescription.SignatureToken>emptyList();
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@

import java.util.*;

import static net.bytebuddy.matcher.ElementMatchers.is;

/**
* A method rebase resolver is responsible for mapping methods of an instrumented type to an alternative signature.
* This way a method can exist in two versions within a class:
Expand Down Expand Up @@ -507,21 +505,21 @@ protected Default(Map<MethodDescription.InDefinedShape, Resolution> resolutions,
* Creates a new method rebase resolver.
*
* @param instrumentedType The instrumented type.
* @param rebaseableMethodTokens Tokens describing all methods that can possibly be rebased.
* @param rebaseables Tokens describing all methods that can possibly be rebased.
* @param classFileVersion The class file version for the instrumentation.
* @param auxiliaryTypeNamingStrategy The naming strategy for naming a potential auxiliary type.
* @param methodNameTransformer A transformer for method names.
* @return A method rebase resolver that is capable of rebasing any of the provided methods.
*/
public static MethodRebaseResolver make(TypeDescription instrumentedType,
Set<? extends MethodDescription.Token> rebaseableMethodTokens,
Set<? extends MethodDescription.SignatureToken> rebaseables,
ClassFileVersion classFileVersion,
AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
MethodNameTransformer methodNameTransformer) {
DynamicType placeholderType = null;
Map<MethodDescription.InDefinedShape, Resolution> resolutions = new HashMap<MethodDescription.InDefinedShape, Resolution>();
for (MethodDescription.InDefinedShape instrumentedMethod : instrumentedType.getDeclaredMethods()) {
if (rebaseableMethodTokens.contains(instrumentedMethod.asToken(is(instrumentedType)))) {
if (rebaseables.contains(instrumentedMethod.asSignatureToken())) {
Resolution resolution;
if (instrumentedMethod.isConstructor()) {
if (placeholderType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
Expand All @@ -31,14 +30,12 @@
import net.bytebuddy.implementation.attribute.AnnotationValueFilter;
import net.bytebuddy.implementation.attribute.TypeAttributeAppender;
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.LatentMatcher;
import net.bytebuddy.pool.TypePool;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static net.bytebuddy.matcher.ElementMatchers.is;

Expand Down Expand Up @@ -226,10 +223,11 @@ public DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrateg
typeValidation,
visibilityBridgeStrategy,
InliningImplementationMatcher.of(ignoredMethods, originalType));
HashSet<MethodDescription.SignatureToken> rebaseables = new HashSet<MethodDescription.SignatureToken>(
originalType.getDeclaredMethods().asSignatureTokenList(is(originalType), instrumentedType));
rebaseables.retainAll(methodRegistry.getInstrumentedMethods().asSignatureTokenList());
MethodRebaseResolver methodRebaseResolver = MethodRebaseResolver.Default.make(methodRegistry.getInstrumentedType(),
new HashSet<MethodDescription.Token>(originalType.getDeclaredMethods()
.asTokenList(is(originalType))
.filter(RebaseableMatcher.of(methodRegistry.getInstrumentedType(), methodRegistry.getInstrumentedMethods()))),
rebaseables,
classFileVersion,
auxiliaryTypeNamingStrategy,
methodNameTransformer);
Expand All @@ -251,43 +249,4 @@ public DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrateg
classFileLocator,
methodRebaseResolver).make(typeResolutionStrategy.resolve());
}

/**
* A matcher that filters any method that should not be rebased, i.e. that is not already defined by the original type.
*/
@HashCodeAndEqualsPlugin.Enhance
protected static class RebaseableMatcher implements ElementMatcher<MethodDescription.Token> {

/**
* A set of method tokens representing all instrumented methods.
*/
private final Set<MethodDescription.Token> tokens;

/**
* Creates a new matcher for identifying rebasable methods.
*
* @param tokens A set of method tokens representing all instrumented methods.
*/
protected RebaseableMatcher(Set<MethodDescription.Token> tokens) {
this.tokens = tokens;
}

/**
* Returns a matcher that filters any method that should not be rebased.
*
* @param instrumentedType The instrumented type.
* @param instrumentedMethods All instrumented methods.
* @return A suitable matcher that filters all methods that should not be rebased.
*/
protected static ElementMatcher<MethodDescription.Token> of(TypeDescription instrumentedType, MethodList<?> instrumentedMethods) {
return new RebaseableMatcher(new HashSet<MethodDescription.Token>(instrumentedMethods.asTokenList(is(instrumentedType))));
}

/**
* {@inheritDoc}
*/
public boolean matches(MethodDescription.Token target) {
return tokens.contains(target);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void testTokenMap() throws Exception {
@Test
public void testCreationWithoutConstructor() throws Exception {
MethodRebaseResolver methodRebaseResolver = MethodRebaseResolver.Default.make(instrumentedType,
Collections.singleton(token),
Collections.singleton(signatureToken),
classFileVersion,
auxiliaryTypeNamingStrategy,
methodNameTransformer);
Expand All @@ -117,7 +117,7 @@ public void testCreationWithoutConstructor() throws Exception {
public void testCreationWithConstructor() throws Exception {
when(methodDescription.isConstructor()).thenReturn(true);
MethodRebaseResolver methodRebaseResolver = MethodRebaseResolver.Default.make(instrumentedType,
Collections.singleton(token),
Collections.singleton(signatureToken),
classFileVersion,
auxiliaryTypeNamingStrategy,
methodNameTransformer);
Expand Down

This file was deleted.

0 comments on commit 7e0a874

Please sign in to comment.