public char[] sourceName() { char[] brackets = new char[dimensions * 2]; for (int i = dimensions * 2 - 1; i >= 0; i -= 2) { brackets[i] = ']'; brackets[i - 1] = '['; } return CharOperation.concat(leafComponentType.sourceName(), brackets); }
/* Take a type and apply annotations to various components of it. By construction when we see the type reference @Outer Outer.@Middle Middle.@Inner Inner, we first construct the binding for Outer.Middle.Inner and then annotate various parts of it. Likewise for PQTR's binding. */ public TypeBinding getAnnotatedType(TypeBinding type, AnnotationBinding[][] annotations) { if (type == null || !type.isValidBinding() || annotations == null || annotations.length == 0) return type; TypeBinding annotatedType = null; switch (type.kind()) { case Binding.ARRAY_TYPE: ArrayBinding arrayBinding = (ArrayBinding) type; annotatedType = getArrayType( arrayBinding.leafComponentType, arrayBinding.dimensions, flattenedAnnotations(annotations)); break; case Binding.BASE_TYPE: case Binding.TYPE: case Binding.GENERIC_TYPE: case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: case Binding.TYPE_PARAMETER: case Binding.WILDCARD_TYPE: case Binding.INTERSECTION_TYPE: case Binding.INTERSECTION_CAST_TYPE: /* Taking the binding of QTR as an example, there could be different annotatable components, but we come in a with a single binding, e.g: @T Z; type => Z annotations => [[@T]] @T Y.@T Z type => Z annotations => [[@T][@T]] @T X.@T Y.@T Z type => Z annotations => [[@T][@T][@T]] java.lang.@T X.@T Y.@T Z type => Z annotations => [[][][@T][@T][@T]] in all these cases the incoming type binding is for Z, but annotations are for different levels. We need to align their layout for proper attribution. */ if (type.isUnresolvedType() && CharOperation.indexOf('$', type.sourceName()) > 0) type = BinaryTypeBinding.resolveType( type, this.environment, true); // must resolve member types before asking for enclosingType int levels = type.depth() + 1; TypeBinding[] types = new TypeBinding[levels]; types[--levels] = type; TypeBinding enclosingType = type.enclosingType(); while (enclosingType != null) { types[--levels] = enclosingType; enclosingType = enclosingType.enclosingType(); } // Locate the outermost type being annotated. Beware annotations.length could be > // types.length (for package qualified names in QTR/PQTR) levels = annotations.length; int i, j = types.length - levels; for (i = 0; i < levels; i++, j++) { if (annotations[i] != null && annotations[i].length > 0) break; } if (i == levels) // empty annotations array ? return type; if (j < 0) // Not kosher, broken type that is not flagged as invalid while reporting // compilation error ? don't touch. return type; // types[j] is the first component being annotated. Its annotations are annotations[i] for (enclosingType = j == 0 ? null : types[j - 1]; i < levels; i++, j++) { final TypeBinding currentType = types[j]; // while handling annotations from SE7 locations, take care not to drop existing // annotations. AnnotationBinding[] currentAnnotations = annotations[i] != null && annotations[i].length > 0 ? annotations[i] : currentType.getTypeAnnotations(); annotatedType = getAnnotatedType(currentType, enclosingType, currentAnnotations); enclosingType = annotatedType; } break; default: throw new IllegalStateException(); } return annotatedType; }