< prev index next >

src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 29,38 **** --- 29,40 ---- import java.lang.reflect.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; + import java.util.Objects; + import java.util.StringJoiner; import static sun.reflect.annotation.TypeAnnotation.*; public final class AnnotatedTypeFactory { /**
*** 200,209 **** --- 202,273 ---- return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl()); } + @Override // java.lang.Object + public String toString() { + // Reusable toString implementation, but needs to be + // specialized for quirks of arrays. + return annotationsToString(getAnnotations(), false) + type.toString(); + } + + protected String annotationsToString(Annotation[] annotations, boolean leadingSpace) { + if (annotations != null && annotations.length > 0) { + StringJoiner sj = new StringJoiner(" "); + if (leadingSpace) { + sj.add(""); // Add a space + } + + for (Annotation annotation : annotations) { + sj.add(annotation.toString()); + } + + if (!leadingSpace) { + sj.add(""); + } + return sj.toString(); + } else { + return ""; + } + } + + protected boolean equalsTypeAndAnnotations(AnnotatedType that) { + return getType().equals(that.getType()) && + // Treat ordering of annotations as significant + Arrays.equals(getAnnotations(), that.getAnnotations()) && + Objects.equals(getAnnotatedOwnerType(), that.getAnnotatedOwnerType()); + } + + int baseHashCode() { + return type.hashCode() ^ + // Acceptable to use Objects.hash rather than + // Arrays.deepHashCode since the elements of the array + // are not themselves arrays. + Objects.hash((Object[])getAnnotations()) ^ + Objects.hash(getAnnotatedOwnerType()); + } + + @Override + public boolean equals(Object o) { + if (o instanceof AnnotatedType && + !(o instanceof AnnotatedArrayType) && + !(o instanceof AnnotatedTypeVariable) && + !(o instanceof AnnotatedParameterizedType) && + !(o instanceof AnnotatedWildcardType)) { + AnnotatedType that = (AnnotatedType) o; + return equalsTypeAndAnnotations(that); + } else { + return false; + } + } + + @Override + public int hashCode() { + return baseHashCode(); + } + // Implementation details final LocationInfo getLocation() { return location; } final TypeAnnotation[] getTypeAnnotations() {
*** 242,251 **** --- 306,361 ---- Class<?> c = (Class)t; return c.getComponentType(); } return ((GenericArrayType)t).getGenericComponentType(); } + + @Override + public String toString() { + // To annotate the full type of an array, the annotations + // are placed between the type and the brackets. For + // example, to annotate an array of Strings, the syntax used is + // + // String @TypeAnnotation [] + // + // and *not* + // + // @TypeAnnotation String[]. + // + // The toString output should strive to be reusable in + // source code. Therefore, the general logic of putting + // the annotations before a textual representation of the + // type need to be overridden for arrays. + StringBuilder sb = new StringBuilder(); + + AnnotatedType componentType = this; + while (componentType instanceof AnnotatedArrayType) { + AnnotatedArrayType annotatedArrayType = (AnnotatedArrayType) componentType; + sb.append(annotationsToString(annotatedArrayType.getAnnotations(), true) + "[]"); + componentType = annotatedArrayType.getAnnotatedGenericComponentType(); + } + + sb.insert(0, componentType.toString()); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof AnnotatedArrayType) { + AnnotatedArrayType that = (AnnotatedArrayType) o; + return equalsTypeAndAnnotations(that) && + Objects.equals(getAnnotatedGenericComponentType(), + that.getAnnotatedGenericComponentType()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return baseHashCode() ^ getAnnotatedGenericComponentType().hashCode(); + } } private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable { AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location, TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
*** 264,273 **** --- 374,400 ---- } private TypeVariable<?> getTypeVariable() { return (TypeVariable)getType(); } + + @Override + public boolean equals(Object o) { + if (o instanceof AnnotatedTypeVariable) { + AnnotatedTypeVariable that = (AnnotatedTypeVariable) o; + return equalsTypeAndAnnotations(that) && + Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return baseHashCode() ^ + Objects.hash((Object[])getAnnotatedBounds()); + } } private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedParameterizedType { AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
*** 314,323 **** --- 441,467 ---- } private ParameterizedType getParameterizedType() { return (ParameterizedType)getType(); } + + @Override + public boolean equals(Object o) { + if (o instanceof AnnotatedParameterizedType) { + AnnotatedParameterizedType that = (AnnotatedParameterizedType) o; + return equalsTypeAndAnnotations(that) && + Arrays.equals(getAnnotatedActualTypeArguments(), that.getAnnotatedActualTypeArguments()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return baseHashCode() ^ + Objects.hash((Object[])getAnnotatedActualTypeArguments()); + } } private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType { private final boolean hasUpperBounds; AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
*** 376,382 **** --- 520,547 ---- } private boolean hasUpperBounds() { return hasUpperBounds; } + + @Override + public boolean equals(Object o) { + if (o instanceof AnnotatedWildcardType) { + AnnotatedWildcardType that = (AnnotatedWildcardType) o; + return equalsTypeAndAnnotations(that) && + // Treats ordering as significant + Arrays.equals(getAnnotatedLowerBounds(), that.getAnnotatedLowerBounds()) && + // Treats ordering as significant + Arrays.equals(getAnnotatedUpperBounds(), that.getAnnotatedUpperBounds()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return baseHashCode() ^ + Objects.hash((Object[])getAnnotatedLowerBounds()) ^ + Objects.hash((Object[])getAnnotatedUpperBounds()); + } } }
< prev index next >