From dca99800439788895a4f47e4908f2702aa9bee75 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Fri, 16 Jun 2023 15:35:06 +0200 Subject: [PATCH] ArC: implement equals/hashCode for TypeVariableImpl and WildcardTypeImpl --- .../io/quarkus/arc/impl/TypeVariableImpl.java | 27 +++++++++++ .../io/quarkus/arc/impl/WildcardTypeImpl.java | 22 +++++++++ .../arc/impl/ParameterizedTypeImplTest.java | 47 +++++++++++++++++++ .../arc/impl/TypeVariableImplTest.java | 17 +++++++ .../arc/impl/WildcardTypeImplTest.java | 20 ++++++++ 5 files changed, 133 insertions(+) create mode 100644 independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/ParameterizedTypeImplTest.java create mode 100644 independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/TypeVariableImplTest.java create mode 100644 independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/WildcardTypeImplTest.java diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/TypeVariableImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/TypeVariableImpl.java index de6598e74661d..220cf8980f238 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/TypeVariableImpl.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/TypeVariableImpl.java @@ -7,6 +7,7 @@ import java.lang.reflect.TypeVariable; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.StringJoiner; public class TypeVariableImpl implements TypeVariable { @@ -55,6 +56,32 @@ public AnnotatedType[] getAnnotatedBounds() { throw new UnsupportedOperationException(); } + @Override + public int hashCode() { + // This implementation is not compatible with JDK/guava, + // but since it's not possible to implement a compatible equals() anyway, + // it does not really matter. + final int prime = 31; + int result = 1; + result = prime * result + Objects.hashCode(name); + result = prime * result + Objects.hashCode(bounds); + return result; + } + + @Override + public boolean equals(Object obj) { + // Note that JDK does not make it possible to implement a compatible equals() + // as it checks a specific implementation class in its equals() method + if (this == obj) { + return true; + } + if (!(obj instanceof TypeVariable)) { + return false; + } + TypeVariable other = (TypeVariable) obj; + return Objects.equals(name, other.getName()) && Arrays.equals(getBounds(), other.getBounds()); + } + @Override public String toString() { StringJoiner joiner = new StringJoiner(" & ", " extends ", ""); diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/WildcardTypeImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/WildcardTypeImpl.java index c2211ee0cf22d..fcdb55f8a3095 100644 --- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/WildcardTypeImpl.java +++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/WildcardTypeImpl.java @@ -2,6 +2,7 @@ import java.lang.reflect.Type; import java.lang.reflect.WildcardType; +import java.util.Arrays; /** * This code was mainly copied from Weld codebase. @@ -48,4 +49,25 @@ public Type[] getUpperBounds() { public Type[] getLowerBounds() { return lowerBound; } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof WildcardType)) { + return false; + } + WildcardType other = (WildcardType) obj; + return Arrays.equals(lowerBound, other.getLowerBounds()) && Arrays.equals(upperBound, other.getUpperBounds()); + } + + @Override + public int hashCode() { + // We deliberately use the logic from JDK/guava + return Arrays.hashCode(lowerBound) ^ Arrays.hashCode(upperBound); + } } \ No newline at end of file diff --git a/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/ParameterizedTypeImplTest.java b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/ParameterizedTypeImplTest.java new file mode 100644 index 0000000000000..25d2106a9a926 --- /dev/null +++ b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/ParameterizedTypeImplTest.java @@ -0,0 +1,47 @@ +package io.quarkus.arc.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.util.List; + +import jakarta.enterprise.util.TypeLiteral; + +import org.junit.jupiter.api.Test; + +public class ParameterizedTypeImplTest { + + @SuppressWarnings("serial") + @Test + public void testEqualsAndHashCode() { + // List + ParameterizedTypeImpl parameterizedType1 = new ParameterizedTypeImpl(List.class, WildcardTypeImpl.defaultInstance()); + TypeLiteral> literal1 = new TypeLiteral>() { + }; + assertEquals(parameterizedType1, literal1.getType()); + assertEquals(parameterizedType1.hashCode(), literal1.hashCode()); + assertEquals(parameterizedType1, + new ParameterizedTypeImpl(List.class, WildcardTypeImpl.defaultInstance())); + + // List + ParameterizedTypeImpl parameterizedType2 = new ParameterizedTypeImpl(List.class, String.class); + TypeLiteral> literal2 = new TypeLiteral>() { + }; + assertEquals(parameterizedType2, + new ParameterizedTypeImpl(List.class, String.class)); + assertEquals(parameterizedType2, literal2.getType()); + assertEquals(parameterizedType2.hashCode(), literal2.getType().hashCode()); + + // List + ParameterizedTypeImpl parameterizedType3 = new ParameterizedTypeImpl(List.class, + WildcardTypeImpl.withUpperBound(Number.class)); + TypeLiteral> literal3 = new TypeLiteral>() { + }; + assertEquals(parameterizedType3, literal3.getType()); + assertEquals(parameterizedType3.hashCode(), literal3.getType().hashCode()); + assertEquals(parameterizedType3.hashCode(), new ParameterizedTypeImpl(List.class, + WildcardTypeImpl.withUpperBound(Number.class)).hashCode()); + assertNotEquals(parameterizedType3, parameterizedType1); + } + +} diff --git a/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/TypeVariableImplTest.java b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/TypeVariableImplTest.java new file mode 100644 index 0000000000000..0b63f54c9e67f --- /dev/null +++ b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/TypeVariableImplTest.java @@ -0,0 +1,17 @@ +package io.quarkus.arc.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class TypeVariableImplTest { + + @Test + public void testEqualsAndHashCode() { + assertEquals(new TypeVariableImpl<>("T"), new TypeVariableImpl<>("T")); + assertNotEquals(new TypeVariableImpl<>("T"), new TypeVariableImpl<>("T", String.class)); + assertEquals(new TypeVariableImpl<>("T").hashCode(), new TypeVariableImpl<>("T").hashCode()); + } + +} diff --git a/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/WildcardTypeImplTest.java b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/WildcardTypeImplTest.java new file mode 100644 index 0000000000000..79b55ed8c3c89 --- /dev/null +++ b/independent-projects/arc/runtime/src/test/java/io/quarkus/arc/impl/WildcardTypeImplTest.java @@ -0,0 +1,20 @@ +package io.quarkus.arc.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class WildcardTypeImplTest { + + @Test + public void testEqualsAndHashCode() { + assertEquals(WildcardTypeImpl.defaultInstance(), WildcardTypeImpl.withUpperBound(Object.class)); + assertEquals(WildcardTypeImpl.withLowerBound(String.class), WildcardTypeImpl.withLowerBound(String.class)); + assertNotEquals(WildcardTypeImpl.withLowerBound(String.class), WildcardTypeImpl.withLowerBound(Integer.class)); + assertEquals(WildcardTypeImpl.defaultInstance().hashCode(), WildcardTypeImpl.withUpperBound(Object.class).hashCode()); + assertEquals(WildcardTypeImpl.withLowerBound(String.class).hashCode(), + WildcardTypeImpl.withLowerBound(String.class).hashCode()); + } + +}