Skip to content

Commit

Permalink
Removed equality dependency for type tokens.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Winterhalter committed Feb 5, 2016
1 parent 891f3dc commit 323b320
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 70 deletions.
Expand Up @@ -2379,7 +2379,7 @@ public Reducing(TypeDescription declaringType, List<? extends TypeVariableToken>


@Override @Override
public TypeDescription onGenericArray(Generic genericArray) { public TypeDescription onGenericArray(Generic genericArray) {
return genericArray.asErasure(); return TargetType.resolve(genericArray.asErasure(), declaringType);
} }


@Override @Override
Expand All @@ -2389,7 +2389,7 @@ public TypeDescription onWildcard(Generic wildcard) {


@Override @Override
public TypeDescription onParameterizedType(Generic parameterizedType) { public TypeDescription onParameterizedType(Generic parameterizedType) {
return parameterizedType.asErasure(); return TargetType.resolve(parameterizedType.asErasure(), declaringType);
} }


@Override @Override
Expand All @@ -2399,12 +2399,12 @@ public TypeDescription onTypeVariable(Generic typeVariable) {
return typeVariableToken.getBounds().get(0).accept(this); return typeVariableToken.getBounds().get(0).accept(this);
} }
} }
return declaringType.findVariable(typeVariable.getSymbol()).asErasure(); return TargetType.resolve(declaringType.findVariable(typeVariable.getSymbol()).asErasure(), declaringType);
} }


@Override @Override
public TypeDescription onNonGenericType(Generic typeDescription) { public TypeDescription onNonGenericType(Generic typeDescription) {
return typeDescription.asErasure(); return TargetType.resolve(typeDescription.asErasure(), declaringType);
} }


@Override @Override
Expand Down
20 changes: 20 additions & 0 deletions byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/TargetType.java
Expand Up @@ -13,6 +13,26 @@ public final class TargetType {
*/ */
public static final TypeDescription DESCRIPTION = new TypeDescription.ForLoadedType(TargetType.class); public static final TypeDescription DESCRIPTION = new TypeDescription.ForLoadedType(TargetType.class);


/**
* Resolves the given type description to the supplied target type if it represents the {@link TargetType} placeholder.
* Array types are resolved to their component type and rebuilt as an array of the actual target type, if necessary.
*
* @param typeDescription The type description that might represent the {@link TargetType} placeholder.
* @param targetType The actual target type.
* @return The resolved type description.
*/
public static TypeDescription resolve(TypeDescription typeDescription, TypeDescription targetType) {
int arity = 0;
TypeDescription componentType = typeDescription;
while (componentType.isArray()) {
componentType = componentType.getComponentType();
arity++;
}
return componentType.represents(TargetType.class)
? TypeDescription.ArrayProjection.of(targetType, arity)
: typeDescription;
}

/** /**
* An unusable constructor to avoid instance creation. * An unusable constructor to avoid instance creation.
*/ */
Expand Down
Expand Up @@ -7,7 +7,6 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;


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


/** /**
Expand Down Expand Up @@ -91,7 +90,7 @@ public ForFieldToken(FieldDescription.Token token) {


@Override @Override
public ElementMatcher<? super FieldDescription> resolve(TypeDescription instrumentedType) { public ElementMatcher<? super FieldDescription> resolve(TypeDescription instrumentedType) {
return new ResolvedMatcher(instrumentedType, token); return new ResolvedMatcher(token.asSignatureToken(instrumentedType));
} }


@Override @Override
Expand All @@ -118,52 +117,39 @@ public String toString() {
protected static class ResolvedMatcher implements ElementMatcher<FieldDescription> { protected static class ResolvedMatcher implements ElementMatcher<FieldDescription> {


/** /**
* The instrumented type. * The signature token representing the matched field.
*/ */
private final TypeDescription instrumentedType; private final FieldDescription.SignatureToken signatureToken;


/** /**
* The token that is matched. * Creates a new resolved matcher.
*/
private final FieldDescription.Token token;

/**
* Creates a new resolved matcher of a latent field matcher for a field token.
* *
* @param instrumentedType The instrumented type. * @param signatureToken The signature token representing the matched field.
* @param token The token that is matched.
*/ */
protected ResolvedMatcher(TypeDescription instrumentedType, FieldDescription.Token token) { protected ResolvedMatcher(FieldDescription.SignatureToken signatureToken) {
this.instrumentedType = instrumentedType; this.signatureToken = signatureToken;
this.token = token;
} }


@Override @Override
public boolean matches(FieldDescription target) { public boolean matches(FieldDescription target) {
return target.asToken(is(instrumentedType)).equals(token); return target.asSignatureToken().equals(signatureToken);
} }


@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (this == other) return true; return this == other || !(other == null || getClass() != other.getClass())
if (other == null || getClass() != other.getClass()) return false; && signatureToken.equals(((ResolvedMatcher) other).signatureToken);
ResolvedMatcher that = (ResolvedMatcher) other;
return instrumentedType.equals(that.instrumentedType)
&& token.equals(that.token);
} }


@Override @Override
public int hashCode() { public int hashCode() {
int result = instrumentedType.hashCode(); return signatureToken.hashCode();
result = 31 * result + token.hashCode();
return result;
} }


@Override @Override
public String toString() { public String toString() {
return "LatentMatcher.ForFieldToken.ResolvedMatcher{" + return "LatentMatcher.ForFieldToken.ResolvedMatcher{" +
"instrumentedType=" + instrumentedType + "signatureToken=" + signatureToken +
", token=" + token +
'}'; '}';
} }
} }
Expand All @@ -190,7 +176,7 @@ public ForMethodToken(MethodDescription.Token token) {


@Override @Override
public ElementMatcher<? super MethodDescription> resolve(TypeDescription instrumentedType) { public ElementMatcher<? super MethodDescription> resolve(TypeDescription instrumentedType) {
return new ResolvedMatcher(instrumentedType, token); return new ResolvedMatcher(token.asSignatureToken(instrumentedType));
} }


@Override @Override
Expand All @@ -217,52 +203,39 @@ public String toString() {
protected static class ResolvedMatcher implements ElementMatcher<MethodDescription> { protected static class ResolvedMatcher implements ElementMatcher<MethodDescription> {


/** /**
* The instrumented type. * The signature token representing the matched field.
*/
private final TypeDescription instrumentedType;

/**
* The token that is matched.
*/ */
private final MethodDescription.Token token; private final MethodDescription.SignatureToken signatureToken;


/** /**
* Creates a new resolved method of a latent method matcher for a method token. * Creates a new resolved matcher.
* *
* @param instrumentedType The instrumented type. * @param signatureToken The signature token representing the matched field.
* @param token The token that is matched.
*/ */
protected ResolvedMatcher(TypeDescription instrumentedType, MethodDescription.Token token) { protected ResolvedMatcher(MethodDescription.SignatureToken signatureToken) {
this.instrumentedType = instrumentedType; this.signatureToken = signatureToken;
this.token = token;
} }


@Override @Override
public boolean matches(MethodDescription target) { public boolean matches(MethodDescription target) {
return target.asToken(is(instrumentedType)).equals(token); return target.asSignatureToken().equals(signatureToken);
} }


@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (this == other) return true; return this == other || !(other == null || getClass() != other.getClass())
if (other == null || getClass() != other.getClass()) return false; && signatureToken.equals(((ResolvedMatcher) other).signatureToken);
ResolvedMatcher that = (ResolvedMatcher) other;
return instrumentedType.equals(that.instrumentedType)
&& token.equals(that.token);
} }


@Override @Override
public int hashCode() { public int hashCode() {
int result = instrumentedType.hashCode(); return signatureToken.hashCode();
result = 31 * result + token.hashCode();
return result;
} }


@Override @Override
public String toString() { public String toString() {
return "LatentMatcher.ForMethodToken.ResolvedMatcher{" + return "LatentMatcher.ForMethodToken.ResolvedMatcher{" +
"instrumentedType=" + instrumentedType + "signatureToken=" + signatureToken +
", token=" + token +
'}'; '}';
} }
} }
Expand Down
@@ -1,5 +1,6 @@
package net.bytebuddy.description.type; package net.bytebuddy.description.type;


import net.bytebuddy.dynamic.TargetType;
import net.bytebuddy.test.utility.MockitoRule; import net.bytebuddy.test.utility.MockitoRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion; import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Before; import org.junit.Before;
Expand Down Expand Up @@ -96,8 +97,18 @@ public void testTypeVariableContextDeclared() throws Exception {
verifyNoMoreInteractions(declaringType); verifyNoMoreInteractions(declaringType);
} }


@Test
public void testTargetTypeResolution() throws Exception {
assertThat(visitor.onGenericArray(TargetType.DESCRIPTION.asGenericType()), is(declaringType));
assertThat(visitor.onParameterizedType(TargetType.DESCRIPTION.asGenericType()), is(declaringType));
assertThat(visitor.onNonGenericType(TargetType.DESCRIPTION.asGenericType()), is(declaringType));
when(typeDescription.getSymbol()).thenReturn(BAR);
when(declaringType.findVariable(BAR)).thenReturn(TargetType.DESCRIPTION.asGenericType());
assertThat(visitor.onTypeVariable(typeDescription), is(declaringType));
}

@Test @Test
public void testObjectProperties() throws Exception { public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(TypeDescription.Generic.Visitor.Reducing.class).apply(); ObjectPropertyAssertion.of(TypeDescription.Generic.Visitor.Reducing.class).apply();
} }
} }
@@ -1,7 +1,12 @@
package net.bytebuddy.dynamic; package net.bytebuddy.dynamic;


import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TestRule;
import org.mockito.Mock;


import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
Expand All @@ -10,9 +15,46 @@
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;


public class TargetTypeTest { public class TargetTypeTest {


@Rule
public TestRule mockitoRule = new MockitoRule(this);

@Mock
private TypeDescription typeDescription, targetType, componentType;

@Test
public void testIsNotTargetType() throws Exception {
when(typeDescription.represents(TargetType.class)).thenReturn(false);
assertThat(TargetType.resolve(typeDescription, targetType), is(typeDescription));
}

@Test
public void testIsTargetType() throws Exception {
when(typeDescription.represents(TargetType.class)).thenReturn(true);
assertThat(TargetType.resolve(typeDescription, targetType), is(targetType));
}

@Test
public void testIsNotTargetTypeArray() throws Exception {
when(typeDescription.isArray()).thenReturn(true);
when(typeDescription.getComponentType()).thenReturn(componentType);
when(componentType.represents(TargetType.class)).thenReturn(false);
assertThat(TargetType.resolve(typeDescription, targetType), is(typeDescription));
}

@Test
public void testIsTargetTypeArray() throws Exception {
when(typeDescription.isArray()).thenReturn(true);
when(typeDescription.getComponentType()).thenReturn(componentType);
when(componentType.represents(TargetType.class)).thenReturn(true);
TypeDescription resolvedType = TargetType.resolve(typeDescription, targetType);
assertThat(resolvedType.isArray(), is(true));
assertThat(resolvedType.getComponentType(), is(targetType));
}

@Test @Test
public void testConstructorIsHidden() throws Exception { public void testConstructorIsHidden() throws Exception {
assertThat(TargetType.class.getDeclaredConstructors().length, is(1)); assertThat(TargetType.class.getDeclaredConstructors().length, is(1));
Expand Down
Expand Up @@ -22,7 +22,10 @@ public class LatentMatcherForFieldTokenTest {
public TestRule mockitoRule = new MockitoRule(this); public TestRule mockitoRule = new MockitoRule(this);


@Mock @Mock
private FieldDescription.Token token, otherToken; private FieldDescription.Token token;

@Mock
private FieldDescription.SignatureToken signatureToken, otherSignatureToken;


@Mock @Mock
private TypeDescription instrumentedType; private TypeDescription instrumentedType;
Expand All @@ -38,13 +41,15 @@ public void setUp() throws Exception {


@Test @Test
public void testMatch() throws Exception { public void testMatch() throws Exception {
when(fieldDescription.asToken(ElementMatchers.is(instrumentedType))).thenReturn(token); when(fieldDescription.asSignatureToken()).thenReturn(signatureToken);
when(token.asSignatureToken(instrumentedType)).thenReturn(signatureToken);
assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(true)); assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(true));
} }


@Test @Test
public void testNoMatch() throws Exception { public void testNoMatch() throws Exception {
when(fieldDescription.asToken(ElementMatchers.is(instrumentedType))).thenReturn(otherToken); when(fieldDescription.asSignatureToken()).thenReturn(otherSignatureToken);
when(token.asSignatureToken(instrumentedType)).thenReturn(signatureToken);
assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(false)); assertThat(new LatentMatcher.ForFieldToken(token).resolve(instrumentedType).matches(fieldDescription), is(false));
} }


Expand Down
Expand Up @@ -5,15 +5,13 @@
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.test.utility.MockitoRule; import net.bytebuddy.test.utility.MockitoRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion; import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TestRule; import org.junit.rules.TestRule;
import org.mockito.Mock; import org.mockito.Mock;


import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;


public class LatentMatcherForMethodTokenTest { public class LatentMatcherForMethodTokenTest {
Expand All @@ -22,29 +20,28 @@ public class LatentMatcherForMethodTokenTest {
public TestRule mockitoRule = new MockitoRule(this); public TestRule mockitoRule = new MockitoRule(this);


@Mock @Mock
private MethodDescription.Token token, otherToken; private MethodDescription.Token token;

@Mock
private MethodDescription.SignatureToken signatureToken, otherToken;


@Mock @Mock
private TypeDescription instrumentedType; private TypeDescription instrumentedType;


@Mock @Mock
private MethodDescription methodDescription; private MethodDescription methodDescription;


@Before
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
when(token.accept(any(TypeDescription.Generic.Visitor.class))).thenReturn(token);
}

@Test @Test
public void testMatch() throws Exception { public void testMatch() throws Exception {
when(methodDescription.asToken(ElementMatchers.is(instrumentedType))).thenReturn(token); when(methodDescription.asSignatureToken()).thenReturn(signatureToken);
when(token.asSignatureToken(instrumentedType)).thenReturn(signatureToken);
assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(true)); assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(true));
} }


@Test @Test
public void testNoMatch() throws Exception { public void testNoMatch() throws Exception {
when(methodDescription.asToken(ElementMatchers.is(instrumentedType))).thenReturn(otherToken); when(methodDescription.asSignatureToken()).thenReturn(signatureToken);
when(token.asSignatureToken(instrumentedType)).thenReturn(otherToken);
assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(false)); assertThat(new LatentMatcher.ForMethodToken(token).resolve(instrumentedType).matches(methodDescription), is(false));
} }


Expand Down

0 comments on commit 323b320

Please sign in to comment.