< prev index next >

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

Print this page

        

*** 32,41 **** --- 32,42 ---- import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; + import java.util.function.IntFunction; import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.JavaLangAccess; import jdk.internal.reflect.ReflectionFactory;
*** 176,185 **** --- 177,245 ---- return result; } + /** + * There are cases where the number of parameters present for a constructor + * in source code and the number of parameters present for that constructor + * in the class file differ. Constructors of enum classes, anonymous classes, + * local classes and member classes may have additional parameters generated + * by compiler. This method fixes an array of "annotations collections" + * by prefixing and/or suffixing it with "empty collection" elements + * for parameters added by compiler. + * + * @param constructor the constructor + * @param annColls an array of annotation collections for parameters in source code + * @param emptyColl an empty collection replicated for compiler generated parameters + * @param arrayFactory a factory for arrays of collections + * @param <A> the type of annotation collection + * @return new array of annotation collections for parameters in class file + */ + public static <A> A[] fixConstructorParameterAnnotations( + Constructor<?> constructor, A[] annColls, A emptyColl, IntFunction<A[]> arrayFactory) + { + int prefixLength = 0; + boolean mayHaveSuffix = false; + Class<?> declaringClass = constructor.getDeclaringClass(); + if (declaringClass.isEnum() || + (declaringClass.isAnonymousClass() && declaringClass.getSuperclass().isEnum())) { + // enum class or enum constant anonymous subclass + prefixLength = 2; + mayHaveSuffix = true; + } else if (declaringClass.isLocalClass() || declaringClass.isAnonymousClass()) { + // local or anonymous class + if (!Modifier.isStatic(declaringClass.getModifiers())) { + prefixLength = 1; + } + mayHaveSuffix = true; + } else if (declaringClass.isMemberClass()) { + // member class + if (!Modifier.isStatic(declaringClass.getModifiers())) { + prefixLength = 1; + } + } + // compute total length of array of arrays + int len = annColls.length + prefixLength; + if (len < constructor.getParameterCount() && mayHaveSuffix) { + len = constructor.getParameterCount(); + } + // prepend empty annotations prefix and/or append suffix if needed + if (len > annColls.length) { + A[] newAnnColls = arrayFactory.apply(len); + Arrays.fill(newAnnColls, 0, prefixLength, emptyColl); + System.arraycopy(annColls, 0, + newAnnColls, prefixLength, + annColls.length); + Arrays.fill(newAnnColls, + prefixLength + annColls.length, newAnnColls.length, + emptyColl); + annColls = newAnnColls; + } + return annColls; + } + /* Reflectively invoke the values-method of the given annotation * (container), cast it to an array of annotations and return the result. */ private static <A extends Annotation> A[] getValueArray(Annotation container) { try {
< prev index next >