Skip to content

Commit

Permalink
Fixed generic type resolution. Adapted equals method of the TypeDescr…
Browse files Browse the repository at this point in the history
…iption class to be comparable to lazily resolved generic types that do not implement the TypeDescription interface.
  • Loading branch information
Rafael Winterhalter committed Jun 2, 2015
1 parent 05deab3 commit cdc02f8
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 25 deletions.
Expand Up @@ -732,13 +732,14 @@ public void remove() {

@Override
public boolean equals(Object other) {
return other == this || other instanceof TypeDescription
&& getName().equals(((TypeDescription) other).getName());
return other == this || other instanceof GenericTypeDescription
&& ((GenericTypeDescription) other).getSort().isRawType()
&& getInternalName().equals(((GenericTypeDescription) other).asRawType().getInternalName());
}

@Override
public int hashCode() {
return getName().hashCode();
return getInternalName().hashCode();
}

@Override
Expand Down
Expand Up @@ -153,6 +153,7 @@ public SignatureVisitor onRawType(TypeDescription typeDescription) {
signatureVisitor.visitBaseType(typeDescription.getDescriptor().charAt(ONLY_CHARACTER));
} else {
signatureVisitor.visitClassType(typeDescription.getInternalName());
signatureVisitor.visitEnd();
}
return signatureVisitor;
}
Expand All @@ -170,11 +171,9 @@ public SignatureVisitor onWildcardType(GenericTypeDescription genericTypeDescrip
if (upperBounds.getOnly().asRawType().represents(Object.class) && lowerBounds.isEmpty()) {
signatureVisitor.visitTypeArgument();
} else if (!lowerBounds.isEmpty() /* && upperBounds.isEmpty() */) {
upperBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.EXTENDS)));
signatureVisitor.visitEnd();
} else /* if (upperBounds.isEmpty() /* && !lowerBounds.isEmpty()) */ {
lowerBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.SUPER)));
signatureVisitor.visitEnd();
lowerBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.EXTENDS)));
} else /* if (!upperBounds.isEmpty() && lowerBounds.isEmpty()) */ {
upperBounds.getOnly().accept(new ForSignatureVisitor(signatureVisitor.visitTypeArgument(SignatureVisitor.SUPER)));
}
return signatureVisitor;
}
Expand Down Expand Up @@ -874,8 +873,8 @@ public int hashCode() {
}

@Override
public boolean equals(Object obj) {
return resolve().equals(obj);
public boolean equals(Object other) {
return resolve().equals(other);
}

@Override
Expand Down
Expand Up @@ -4,6 +4,7 @@
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.generic.AbstractGenericTypeDescriptionTest;
import net.bytebuddy.description.type.generic.GenericTypeDescription;
import net.bytebuddy.dynamic.loading.ByteArrayClassLoader;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.test.utility.ClassFileExtraction;
Expand All @@ -26,6 +27,7 @@

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -166,26 +168,31 @@ public void testDeclaringType() throws Exception {

@Test
public void testHashCode() throws Exception {
assertThat(describe(SampleClass.class).hashCode(), is(SampleClass.class.getName().hashCode()));
assertThat(describe(SampleInterface.class).hashCode(), is(SampleInterface.class.getName().hashCode()));
assertThat(describe(SampleAnnotation.class).hashCode(), is(SampleAnnotation.class.getName().hashCode()));
assertThat(describe(SampleClass.class).hashCode(), is(Type.getInternalName(SampleClass.class).hashCode()));
assertThat(describe(SampleInterface.class).hashCode(), is(Type.getInternalName(SampleInterface.class).hashCode()));
assertThat(describe(SampleAnnotation.class).hashCode(), is(Type.getInternalName(SampleAnnotation.class).hashCode()));
assertThat(describe(SampleClass.class).hashCode(), is(describe(SampleClass.class).hashCode()));
assertThat(describe(SampleClass.class).hashCode(), not(is(describe(SampleInterface.class).hashCode())));
assertThat(describe(SampleClass.class).hashCode(), not(is(describe(SampleAnnotation.class).hashCode())));
assertThat(describe(Object[].class).hashCode(), is(describe(Object[].class).hashCode()));
assertThat(describe(Object[].class).hashCode(), not(is(describe(Object.class).hashCode())));
assertThat(describe(void.class).hashCode(), is(void.class.getName().hashCode()));
assertThat(describe(void.class).hashCode(), is(Type.getInternalName(void.class).hashCode()));
}

@Test
public void testEquals() throws Exception {
TypeDescription identical = describe(SampleClass.class);
assertThat(identical, equalTo(identical));
TypeDescription equalFirst = mock(TypeDescription.class);
when(equalFirst.getName()).thenReturn(SampleClass.class.getName());
when(equalFirst.getSort()).thenReturn(GenericTypeDescription.Sort.RAW);
when(equalFirst.asRawType()).thenReturn(equalFirst);
when(equalFirst.getInternalName()).thenReturn(Type.getInternalName(SampleClass.class));
assertThat(describe(SampleClass.class), equalTo(equalFirst));
assertThat(describe(SampleClass.class), not(equalTo(describe(SampleInterface.class))));
assertThat(describe(SampleClass.class), not(equalTo((TypeDescription) new TypeDescription.ForLoadedType(SampleInterface.class))));
GenericTypeDescription nonRawType = mock(GenericTypeDescription.class);
when(nonRawType.getSort()).thenReturn(GenericTypeDescription.Sort.VARIABLE);
assertThat(describe(SampleClass.class), not(equalTo(nonRawType)));
assertThat(describe(SampleClass.class), not(equalTo(new Object())));
assertThat(describe(SampleClass.class), not(equalTo(null)));
assertThat(describe(Object[].class), equalTo((TypeDescription) new TypeDescription.ForLoadedType(Object[].class)));
Expand Down
Expand Up @@ -8,8 +8,8 @@
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.test.utility.DebuggingWrapper;
import org.junit.Ignore;
import org.junit.Test;
import org.objectweb.asm.util.ASMifier;

import java.util.ArrayList;
import java.util.concurrent.Callable;
Expand All @@ -19,7 +19,6 @@
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

@Ignore
public class GenericSignatureResolutionTest {

private static final String FOO = "foo";
Expand All @@ -41,7 +40,6 @@ public void testGenericType() throws Exception {
public void testGenericField() throws Exception {
DynamicType.Unloaded<?> unloaded = new ByteBuddy()
.redefine(GenericField.class)
.classVisitor(DebuggingWrapper.makeDefault())
.make();
Class<?> type = unloaded.load(null, ClassLoadingStrategy.Default.WRAPPER).getLoaded();
FieldDescription createdField = new FieldDescription.ForLoadedField(type.getDeclaredField(FOO));
Expand Down
Expand Up @@ -4,6 +4,7 @@
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeList;
import net.bytebuddy.description.type.generic.GenericTypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.LoadedTypeInitializer;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
Expand All @@ -20,9 +21,7 @@
import java.io.Serializable;
import java.util.Collections;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
import static org.mockito.Mockito.*;
Expand Down Expand Up @@ -248,16 +247,18 @@ public void testGetStackSize() throws Exception {
@Test
public void testHashCode() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
assertThat(instrumentedType.hashCode(), is(instrumentedType.getName().hashCode()));
assertThat(instrumentedType.hashCode(), is(instrumentedType.getInternalName().hashCode()));
}

@Test
public void testEquals() throws Exception {
InstrumentedType instrumentedType = makePlainInstrumentedType();
TypeDescription other = mock(TypeDescription.class);
when(other.getName()).thenReturn(instrumentedType.getName());
assertThat(instrumentedType.equals(other), is(true));
verify(other, atLeast(1)).getName();
when(other.getInternalName()).thenReturn(instrumentedType.getInternalName());
when(other.getSort()).thenReturn(GenericTypeDescription.Sort.RAW);
when(other.asRawType()).thenReturn(other);
assertThat(instrumentedType, equalTo(other));
verify(other, atLeast(1)).getInternalName();
}

@Test
Expand Down
Expand Up @@ -5,6 +5,7 @@
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.generic.GenericTypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
import net.bytebuddy.implementation.bytecode.StackSize;
Expand Down Expand Up @@ -46,6 +47,8 @@ public void setUp() throws Exception {
when(instrumentedType.getDeclaredFields()).thenReturn(new FieldList.Explicit(Collections.singletonList(fieldDescription)));
when(fieldDescription.getFieldType()).thenReturn(fieldType);
when(fieldType.getStackSize()).thenReturn(StackSize.ZERO);
when(fieldType.getSort()).thenReturn(GenericTypeDescription.Sort.RAW);
when(fieldType.asRawType()).thenReturn(fieldType);
}

@Override
Expand Down

0 comments on commit cdc02f8

Please sign in to comment.