< 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 >