1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Mon Feb 04 18:08:53 2013 -0500 1.3 @@ -0,0 +1,1037 @@ 1.4 +/* 1.5 + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.code; 1.30 + 1.31 +import javax.lang.model.element.Element; 1.32 +import javax.lang.model.element.ElementKind; 1.33 +import javax.lang.model.type.TypeKind; 1.34 + 1.35 +import com.sun.tools.javac.code.Attribute; 1.36 +import com.sun.tools.javac.code.Attribute.TypeCompound; 1.37 +import com.sun.tools.javac.code.Flags; 1.38 +import com.sun.tools.javac.code.Kinds; 1.39 +import com.sun.tools.javac.code.Type.AnnotatedType; 1.40 +import com.sun.tools.javac.code.Type.ArrayType; 1.41 +import com.sun.tools.javac.code.Type.CapturedType; 1.42 +import com.sun.tools.javac.code.Type.ClassType; 1.43 +import com.sun.tools.javac.code.Type.ErrorType; 1.44 +import com.sun.tools.javac.code.Type.ForAll; 1.45 +import com.sun.tools.javac.code.Type.MethodType; 1.46 +import com.sun.tools.javac.code.Type.PackageType; 1.47 +import com.sun.tools.javac.code.Type.TypeVar; 1.48 +import com.sun.tools.javac.code.Type.UndetVar; 1.49 +import com.sun.tools.javac.code.Type.Visitor; 1.50 +import com.sun.tools.javac.code.Type.WildcardType; 1.51 +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; 1.52 +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; 1.53 +import com.sun.tools.javac.code.TypeTag; 1.54 +import com.sun.tools.javac.code.Symbol.VarSymbol; 1.55 +import com.sun.tools.javac.comp.Annotate.Annotator; 1.56 +import com.sun.tools.javac.tree.JCTree; 1.57 +import com.sun.tools.javac.tree.JCTree.JCBlock; 1.58 +import com.sun.tools.javac.tree.JCTree.JCClassDecl; 1.59 +import com.sun.tools.javac.tree.JCTree.JCExpression; 1.60 +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; 1.61 +import com.sun.tools.javac.tree.JCTree.JCTypeApply; 1.62 +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 1.63 +import com.sun.tools.javac.tree.TreeScanner; 1.64 +import com.sun.tools.javac.tree.JCTree.*; 1.65 +import com.sun.tools.javac.util.Assert; 1.66 +import com.sun.tools.javac.util.List; 1.67 +import com.sun.tools.javac.util.ListBuffer; 1.68 +import com.sun.tools.javac.util.Log; 1.69 +import com.sun.tools.javac.util.Names; 1.70 + 1.71 +/** 1.72 + * Contains operations specific to processing type annotations. 1.73 + * This class has two functions: 1.74 + * separate declaration from type annotations and insert the type 1.75 + * annotations to their types; 1.76 + * and determine the TypeAnnotationPositions for all type annotations. 1.77 + */ 1.78 +public class TypeAnnotations { 1.79 + // Class cannot be instantiated. 1.80 + private TypeAnnotations() {} 1.81 + 1.82 + /** 1.83 + * Separate type annotations from declaration annotations and 1.84 + * determine the correct positions for type annotations. 1.85 + * This version only visits types in signatures and should be 1.86 + * called from MemberEnter. 1.87 + * The method returns the Annotator object that should be added 1.88 + * to the correct Annotate queue for later processing. 1.89 + */ 1.90 + public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, 1.91 + final Log log, final JCClassDecl tree) { 1.92 + return new Annotator() { 1.93 + @Override 1.94 + public void enterAnnotation() { 1.95 + new TypeAnnotationPositions(syms, names, log, true).scan(tree); 1.96 + } 1.97 + }; 1.98 + } 1.99 + 1.100 + /** 1.101 + * This version only visits types in bodies, that is, field initializers, 1.102 + * top-level blocks, and method bodies, and should be called from Attr. 1.103 + */ 1.104 + public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) { 1.105 + new TypeAnnotationPositions(syms, names, log, false).scan(tree); 1.106 + } 1.107 + 1.108 + private static class TypeAnnotationPositions extends TreeScanner { 1.109 + 1.110 + private enum AnnotationType { DECLARATION, TYPE, BOTH }; 1.111 + 1.112 + private final Symtab syms; 1.113 + private final Names names; 1.114 + private final Log log; 1.115 + private final boolean sigOnly; 1.116 + 1.117 + private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) { 1.118 + this.syms = syms; 1.119 + this.names = names; 1.120 + this.log = log; 1.121 + this.sigOnly = sigOnly; 1.122 + } 1.123 + 1.124 + /* 1.125 + * When traversing the AST we keep the "frames" of visited 1.126 + * trees in order to determine the position of annotations. 1.127 + */ 1.128 + private ListBuffer<JCTree> frames = ListBuffer.lb(); 1.129 + 1.130 + protected void push(JCTree t) { frames = frames.prepend(t); } 1.131 + protected JCTree pop() { return frames.next(); } 1.132 + // could this be frames.elems.tail.head? 1.133 + private JCTree peek2() { return frames.toList().tail.head; } 1.134 + 1.135 + @Override 1.136 + public void scan(JCTree tree) { 1.137 + push(tree); 1.138 + super.scan(tree); 1.139 + pop(); 1.140 + } 1.141 + 1.142 + /** 1.143 + * Separates type annotations from declaration annotations. 1.144 + * This step is needed because in certain locations (where declaration 1.145 + * and type annotations can be mixed, e.g. the type of a field) 1.146 + * we never build an JCAnnotatedType. This step finds these 1.147 + * annotations and marks them as if they were part of the type. 1.148 + */ 1.149 + private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym, 1.150 + TypeAnnotationPosition pos) { 1.151 + /* 1.152 + System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n", 1.153 + typetree, type, sym, pos); 1.154 + */ 1.155 + List<Attribute.Compound> annotations = sym.getRawAttributes(); 1.156 + ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>(); 1.157 + ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>(); 1.158 + 1.159 + for (Attribute.Compound a : annotations) { 1.160 + switch (annotationType(a, sym)) { 1.161 + case DECLARATION: 1.162 + declAnnos.append(a); 1.163 + break; 1.164 + case BOTH: { 1.165 + declAnnos.append(a); 1.166 + Attribute.TypeCompound ta = toTypeCompound(a, pos); 1.167 + typeAnnos.append(ta); 1.168 + break; 1.169 + } 1.170 + case TYPE: { 1.171 + Attribute.TypeCompound ta = toTypeCompound(a, pos); 1.172 + typeAnnos.append(ta); 1.173 + break; 1.174 + } 1.175 + } 1.176 + } 1.177 + 1.178 + sym.annotations.reset(); 1.179 + sym.annotations.setDeclarationAttributes(declAnnos.toList()); 1.180 + 1.181 + List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList(); 1.182 + 1.183 + if (type == null) { 1.184 + // When type is null, put the type annotations to the symbol. 1.185 + // This is used for constructor return annotations, for which 1.186 + // no appropriate type exists. 1.187 + sym.annotations.appendUniqueTypes(typeAnnotations); 1.188 + return; 1.189 + } 1.190 + 1.191 + // type is non-null and annotations are added to that type 1.192 + type = typeWithAnnotations(typetree, type, typeAnnotations, log); 1.193 + 1.194 + if (sym.getKind() == ElementKind.METHOD) { 1.195 + sym.type.asMethodType().restype = type; 1.196 + } else { 1.197 + sym.type = type; 1.198 + } 1.199 + 1.200 + sym.annotations.appendUniqueTypes(typeAnnotations); 1.201 + if (sym.getKind() == ElementKind.PARAMETER && 1.202 + sym.getQualifiedName().equals(names._this)) { 1.203 + sym.owner.type.asMethodType().recvtype = type; 1.204 + // note that the typeAnnotations will also be added to the owner below. 1.205 + } 1.206 + if (sym.getKind() == ElementKind.PARAMETER || 1.207 + sym.getKind() == ElementKind.LOCAL_VARIABLE || 1.208 + sym.getKind() == ElementKind.RESOURCE_VARIABLE || 1.209 + sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { 1.210 + // Make sure all type annotations from the symbol are also 1.211 + // on the owner. 1.212 + sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors()); 1.213 + } 1.214 + } 1.215 + 1.216 + // This method has a similar purpose as 1.217 + // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)} 1.218 + // We found a type annotation in a declaration annotation position, 1.219 + // for example, on the return type. 1.220 + // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore 1.221 + // need to set its position explicitly. 1.222 + // The method returns a copy of type that contains these annotations. 1.223 + private static Type typeWithAnnotations(final JCTree typetree, final Type type, 1.224 + final List<Attribute.TypeCompound> annotations, Log log) { 1.225 + // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", 1.226 + // typetree, type, annotations); 1.227 + if (annotations.isEmpty()) { 1.228 + return type; 1.229 + } 1.230 + if (type.hasTag(TypeTag.ARRAY)) { 1.231 + Type toreturn; 1.232 + Type.ArrayType tomodify; 1.233 + Type.ArrayType arType; 1.234 + { 1.235 + Type touse = type; 1.236 + if (type.getKind() == TypeKind.ANNOTATED) { 1.237 + Type.AnnotatedType atype = (Type.AnnotatedType)type; 1.238 + toreturn = new Type.AnnotatedType(atype.underlyingType); 1.239 + ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations; 1.240 + touse = atype.underlyingType; 1.241 + arType = (Type.ArrayType) touse; 1.242 + tomodify = new Type.ArrayType(null, arType.tsym); 1.243 + ((Type.AnnotatedType)toreturn).underlyingType = tomodify; 1.244 + } else { 1.245 + arType = (Type.ArrayType) touse; 1.246 + tomodify = new Type.ArrayType(null, arType.tsym); 1.247 + toreturn = tomodify; 1.248 + } 1.249 + } 1.250 + JCArrayTypeTree arTree = arrayTypeTree(typetree); 1.251 + 1.252 + ListBuffer<TypePathEntry> depth = ListBuffer.lb(); 1.253 + depth = depth.append(TypePathEntry.ARRAY); 1.254 + while (arType.elemtype.hasTag(TypeTag.ARRAY)) { 1.255 + if (arType.elemtype.getKind() == TypeKind.ANNOTATED) { 1.256 + Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype; 1.257 + Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType); 1.258 + tomodify.elemtype = newAT; 1.259 + newAT.typeAnnotations = aelemtype.typeAnnotations; 1.260 + arType = (Type.ArrayType) aelemtype.underlyingType; 1.261 + tomodify = new Type.ArrayType(null, arType.tsym); 1.262 + newAT.underlyingType = tomodify; 1.263 + } else { 1.264 + arType = (Type.ArrayType) arType.elemtype; 1.265 + tomodify.elemtype = new Type.ArrayType(null, arType.tsym); 1.266 + tomodify = (Type.ArrayType) tomodify.elemtype; 1.267 + } 1.268 + arTree = arrayTypeTree(arTree.elemtype); 1.269 + depth = depth.append(TypePathEntry.ARRAY); 1.270 + } 1.271 + Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log); 1.272 + tomodify.elemtype = arelemType; 1.273 + for (Attribute.TypeCompound a : annotations) { 1.274 + TypeAnnotationPosition p = a.position; 1.275 + p.location = p.location.prependList(depth.toList()); 1.276 + } 1.277 + return toreturn; 1.278 + } else if (type.hasTag(TypeTag.TYPEVAR)) { 1.279 + // Nothing to do for type variables. 1.280 + return type; 1.281 + } else { 1.282 + Type enclTy = type; 1.283 + Element enclEl = type.asElement(); 1.284 + JCTree enclTr = typetree; 1.285 + 1.286 + while (enclEl != null && 1.287 + enclEl.getKind() != ElementKind.PACKAGE && 1.288 + enclTy != null && 1.289 + enclTy.getKind() != TypeKind.NONE && 1.290 + enclTy.getKind() != TypeKind.ERROR && 1.291 + (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || 1.292 + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || 1.293 + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { 1.294 + // Iterate also over the type tree, not just the type: the type is already 1.295 + // completely resolved and we cannot distinguish where the annotation 1.296 + // belongs for a nested type. 1.297 + if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) { 1.298 + // only change encl in this case. 1.299 + enclTy = enclTy.getEnclosingType(); 1.300 + enclEl = enclEl.getEnclosingElement(); 1.301 + enclTr = ((JCFieldAccess)enclTr).getExpression(); 1.302 + } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) { 1.303 + enclTr = ((JCTypeApply)enclTr).getType(); 1.304 + } else { 1.305 + // only other option because of while condition 1.306 + enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType(); 1.307 + } 1.308 + } 1.309 + 1.310 + /** We are trying to annotate some enclosing type, 1.311 + * but nothing more exists. 1.312 + */ 1.313 + if (enclTy != null && 1.314 + enclTy.getKind() == TypeKind.NONE && 1.315 + (enclTr.getKind() == JCTree.Kind.IDENTIFIER || 1.316 + enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || 1.317 + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || 1.318 + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { 1.319 + // TODO: also if it's "java. @A lang.Object", that is, 1.320 + // if it's on a package? 1.321 + log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString()); 1.322 + return type; 1.323 + } 1.324 + 1.325 + // At this point we have visited the part of the nested 1.326 + // type that is written in the source code. 1.327 + // Now count from here to the actual top-level class to determine 1.328 + // the correct nesting. 1.329 + 1.330 + // The genericLocation for the annotation. 1.331 + ListBuffer<TypePathEntry> depth = ListBuffer.lb(); 1.332 + 1.333 + Type topTy = enclTy; 1.334 + while (enclEl != null && 1.335 + enclEl.getKind() != ElementKind.PACKAGE && 1.336 + topTy != null && 1.337 + topTy.getKind() != TypeKind.NONE && 1.338 + topTy.getKind() != TypeKind.ERROR) { 1.339 + topTy = topTy.getEnclosingType(); 1.340 + enclEl = enclEl.getEnclosingElement(); 1.341 + 1.342 + if (topTy != null && topTy.getKind() != TypeKind.NONE) { 1.343 + // Only count enclosing types. 1.344 + depth = depth.append(TypePathEntry.INNER_TYPE); 1.345 + } 1.346 + } 1.347 + 1.348 + if (depth.nonEmpty()) { 1.349 + // Only need to change the annotation positions 1.350 + // if they are on an enclosed type. 1.351 + for (Attribute.TypeCompound a : annotations) { 1.352 + TypeAnnotationPosition p = a.position; 1.353 + p.location = p.location.appendList(depth.toList()); 1.354 + } 1.355 + } 1.356 + 1.357 + Type ret = typeWithAnnotations(type, enclTy, annotations); 1.358 + return ret; 1.359 + } 1.360 + } 1.361 + 1.362 + private static JCArrayTypeTree arrayTypeTree(JCTree typetree) { 1.363 + if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { 1.364 + return (JCArrayTypeTree) typetree; 1.365 + } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { 1.366 + return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType; 1.367 + } else { 1.368 + Assert.error("Could not determine array type from type tree: " + typetree); 1.369 + return null; 1.370 + } 1.371 + } 1.372 + 1.373 + /** Return a copy of the first type that only differs by 1.374 + * inserting the annotations to the left-most/inner-most type 1.375 + * or the type given by stopAt. 1.376 + * 1.377 + * We need the stopAt parameter to know where on a type to 1.378 + * put the annotations. 1.379 + * If we have nested classes Outer > Middle > Inner, and we 1.380 + * have the source type "@A Middle.Inner", we will invoke 1.381 + * this method with type = Outer.Middle.Inner, 1.382 + * stopAt = Middle.Inner, and annotations = @A. 1.383 + * 1.384 + * @param type The type to copy. 1.385 + * @param stopAt The type to stop at. 1.386 + * @param annotations The annotations to insert. 1.387 + * @return A copy of type that contains the annotations. 1.388 + */ 1.389 + private static Type typeWithAnnotations(final Type type, 1.390 + final Type stopAt, 1.391 + final List<Attribute.TypeCompound> annotations) { 1.392 + Visitor<Type, List<TypeCompound>> visitor = 1.393 + new Type.Visitor<Type, List<Attribute.TypeCompound>>() { 1.394 + @Override 1.395 + public Type visitClassType(ClassType t, List<TypeCompound> s) { 1.396 + // assert that t.constValue() == null? 1.397 + if (t == stopAt || 1.398 + t.getEnclosingType() == Type.noType) { 1.399 + return new AnnotatedType(s, t); 1.400 + } else { 1.401 + ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), 1.402 + t.typarams_field, t.tsym); 1.403 + ret.all_interfaces_field = t.all_interfaces_field; 1.404 + ret.allparams_field = t.allparams_field; 1.405 + ret.interfaces_field = t.interfaces_field; 1.406 + ret.rank_field = t.rank_field; 1.407 + ret.supertype_field = t.supertype_field; 1.408 + return ret; 1.409 + } 1.410 + } 1.411 + 1.412 + @Override 1.413 + public Type visitAnnotatedType(AnnotatedType t, List<TypeCompound> s) { 1.414 + return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s)); 1.415 + } 1.416 + 1.417 + @Override 1.418 + public Type visitWildcardType(WildcardType t, List<TypeCompound> s) { 1.419 + return new AnnotatedType(s, t); 1.420 + } 1.421 + 1.422 + @Override 1.423 + public Type visitArrayType(ArrayType t, List<TypeCompound> s) { 1.424 + ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym); 1.425 + return ret; 1.426 + } 1.427 + 1.428 + @Override 1.429 + public Type visitMethodType(MethodType t, List<TypeCompound> s) { 1.430 + // Impossible? 1.431 + return t; 1.432 + } 1.433 + 1.434 + @Override 1.435 + public Type visitPackageType(PackageType t, List<TypeCompound> s) { 1.436 + // Impossible? 1.437 + return t; 1.438 + } 1.439 + 1.440 + @Override 1.441 + public Type visitTypeVar(TypeVar t, List<TypeCompound> s) { 1.442 + return new AnnotatedType(s, t); 1.443 + } 1.444 + 1.445 + @Override 1.446 + public Type visitCapturedType(CapturedType t, List<TypeCompound> s) { 1.447 + return new AnnotatedType(s, t); 1.448 + } 1.449 + 1.450 + @Override 1.451 + public Type visitForAll(ForAll t, List<TypeCompound> s) { 1.452 + // Impossible? 1.453 + return t; 1.454 + } 1.455 + 1.456 + @Override 1.457 + public Type visitUndetVar(UndetVar t, List<TypeCompound> s) { 1.458 + // Impossible? 1.459 + return t; 1.460 + } 1.461 + 1.462 + @Override 1.463 + public Type visitErrorType(ErrorType t, List<TypeCompound> s) { 1.464 + return new AnnotatedType(s, t); 1.465 + } 1.466 + 1.467 + @Override 1.468 + public Type visitType(Type t, List<TypeCompound> s) { 1.469 + // Error? 1.470 + return t; 1.471 + } 1.472 + }; 1.473 + 1.474 + return type.accept(visitor, annotations); 1.475 + } 1.476 + 1.477 + private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { 1.478 + // It is safe to alias the position. 1.479 + return new Attribute.TypeCompound(a, p); 1.480 + } 1.481 + 1.482 + private AnnotationType annotationType(Attribute.Compound a, Symbol s) { 1.483 + Attribute.Compound atTarget = 1.484 + a.type.tsym.attribute(syms.annotationTargetType.tsym); 1.485 + if (atTarget == null) { 1.486 + return inferTargetMetaInfo(a, s); 1.487 + } 1.488 + Attribute atValue = atTarget.member(names.value); 1.489 + if (!(atValue instanceof Attribute.Array)) { 1.490 + Assert.error("annotationType(): bad @Target argument " + atValue + 1.491 + " (" + atValue.getClass() + ")"); 1.492 + return AnnotationType.DECLARATION; // error recovery 1.493 + } 1.494 + Attribute.Array arr = (Attribute.Array) atValue; 1.495 + boolean isDecl = false, isType = false; 1.496 + for (Attribute app : arr.values) { 1.497 + if (!(app instanceof Attribute.Enum)) { 1.498 + Assert.error("annotationType(): unrecognized Attribute kind " + app + 1.499 + " (" + app.getClass() + ")"); 1.500 + isDecl = true; 1.501 + continue; 1.502 + } 1.503 + Attribute.Enum e = (Attribute.Enum) app; 1.504 + if (e.value.name == names.TYPE) { 1.505 + if (s.kind == Kinds.TYP) 1.506 + isDecl = true; 1.507 + } else if (e.value.name == names.FIELD) { 1.508 + if (s.kind == Kinds.VAR && 1.509 + s.owner.kind != Kinds.MTH) 1.510 + isDecl = true; 1.511 + } else if (e.value.name == names.METHOD) { 1.512 + if (s.kind == Kinds.MTH && 1.513 + !s.isConstructor()) 1.514 + isDecl = true; 1.515 + } else if (e.value.name == names.PARAMETER) { 1.516 + if (s.kind == Kinds.VAR && 1.517 + s.owner.kind == Kinds.MTH && 1.518 + (s.flags() & Flags.PARAMETER) != 0) 1.519 + isDecl = true; 1.520 + } else if (e.value.name == names.CONSTRUCTOR) { 1.521 + if (s.kind == Kinds.MTH && 1.522 + s.isConstructor()) 1.523 + isDecl = true; 1.524 + } else if (e.value.name == names.LOCAL_VARIABLE) { 1.525 + if (s.kind == Kinds.VAR && 1.526 + s.owner.kind == Kinds.MTH && 1.527 + (s.flags() & Flags.PARAMETER) == 0) 1.528 + isDecl = true; 1.529 + } else if (e.value.name == names.ANNOTATION_TYPE) { 1.530 + if (s.kind == Kinds.TYP && 1.531 + (s.flags() & Flags.ANNOTATION) != 0) 1.532 + isDecl = true; 1.533 + } else if (e.value.name == names.PACKAGE) { 1.534 + if (s.kind == Kinds.PCK) 1.535 + isDecl = true; 1.536 + } else if (e.value.name == names.TYPE_USE) { 1.537 + if (s.kind == Kinds.TYP || 1.538 + s.kind == Kinds.VAR || 1.539 + (s.kind == Kinds.MTH && !s.isConstructor() && 1.540 + !s.type.getReturnType().hasTag(TypeTag.VOID)) || 1.541 + (s.kind == Kinds.MTH && s.isConstructor())) 1.542 + isType = true; 1.543 + } else if (e.value.name == names.TYPE_PARAMETER) { 1.544 + /* Irrelevant in this case */ 1.545 + // TYPE_PARAMETER doesn't aid in distinguishing between 1.546 + // Type annotations and declaration annotations on an 1.547 + // Element 1.548 + } else { 1.549 + Assert.error("annotationType(): unrecognized Attribute name " + e.value.name + 1.550 + " (" + e.value.name.getClass() + ")"); 1.551 + isDecl = true; 1.552 + } 1.553 + } 1.554 + if (isDecl && isType) { 1.555 + return AnnotationType.BOTH; 1.556 + } else if (isType) { 1.557 + return AnnotationType.TYPE; 1.558 + } else { 1.559 + return AnnotationType.DECLARATION; 1.560 + } 1.561 + } 1.562 + 1.563 + /** Infer the target annotation kind, if none is give. 1.564 + * We only infer declaration annotations. 1.565 + */ 1.566 + private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) { 1.567 + return AnnotationType.DECLARATION; 1.568 + } 1.569 + 1.570 + 1.571 + /* This is the beginning of the second part of organizing 1.572 + * type annotations: determine the type annotation positions. 1.573 + */ 1.574 + 1.575 + private void resolveFrame(JCTree tree, JCTree frame, 1.576 + List<JCTree> path, TypeAnnotationPosition p) { 1.577 + /* 1.578 + System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind()); 1.579 + System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind()); 1.580 + */ 1.581 + switch (frame.getKind()) { 1.582 + case TYPE_CAST: 1.583 + p.type = TargetType.CAST; 1.584 + p.pos = frame.pos; 1.585 + return; 1.586 + 1.587 + case INSTANCE_OF: 1.588 + p.type = TargetType.INSTANCEOF; 1.589 + p.pos = frame.pos; 1.590 + return; 1.591 + 1.592 + case NEW_CLASS: 1.593 + JCNewClass frameNewClass = (JCNewClass)frame; 1.594 + if (frameNewClass.typeargs.contains(tree)) { 1.595 + p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; 1.596 + p.type_index = frameNewClass.typeargs.indexOf(tree); 1.597 + } else { 1.598 + p.type = TargetType.NEW; 1.599 + } 1.600 + p.pos = frame.pos; 1.601 + return; 1.602 + 1.603 + case NEW_ARRAY: 1.604 + p.type = TargetType.NEW; 1.605 + p.pos = frame.pos; 1.606 + return; 1.607 + 1.608 + case ANNOTATION_TYPE: 1.609 + case CLASS: 1.610 + case ENUM: 1.611 + case INTERFACE: 1.612 + p.pos = frame.pos; 1.613 + if (((JCClassDecl)frame).extending == tree) { 1.614 + p.type = TargetType.CLASS_EXTENDS; 1.615 + p.type_index = -1; 1.616 + } else if (((JCClassDecl)frame).implementing.contains(tree)) { 1.617 + p.type = TargetType.CLASS_EXTENDS; 1.618 + p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree); 1.619 + } else if (((JCClassDecl)frame).typarams.contains(tree)) { 1.620 + p.type = TargetType.CLASS_TYPE_PARAMETER; 1.621 + p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree); 1.622 + } else { 1.623 + Assert.error("Could not determine position of tree " + tree + 1.624 + " within frame " + frame); 1.625 + } 1.626 + return; 1.627 + 1.628 + case METHOD: { 1.629 + JCMethodDecl frameMethod = (JCMethodDecl) frame; 1.630 + p.pos = frame.pos; 1.631 + if (frameMethod.thrown.contains(tree)) { 1.632 + p.type = TargetType.THROWS; 1.633 + p.type_index = frameMethod.thrown.indexOf(tree); 1.634 + } else if (frameMethod.restype == tree) { 1.635 + p.type = TargetType.METHOD_RETURN; 1.636 + } else if (frameMethod.typarams.contains(tree)) { 1.637 + p.type = TargetType.METHOD_TYPE_PARAMETER; 1.638 + p.parameter_index = frameMethod.typarams.indexOf(tree); 1.639 + } else { 1.640 + Assert.error("Could not determine position of tree " + tree + 1.641 + " within frame " + frame); 1.642 + } 1.643 + return; 1.644 + } 1.645 + 1.646 + case PARAMETERIZED_TYPE: { 1.647 + if (((JCTypeApply)frame).clazz == tree) { 1.648 + // generic: RAW; noop 1.649 + } else if (((JCTypeApply)frame).arguments.contains(tree)) { 1.650 + JCTypeApply taframe = (JCTypeApply) frame; 1.651 + int arg = taframe.arguments.indexOf(tree); 1.652 + p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg)); 1.653 + 1.654 + locateNestedTypes(taframe.type, p); 1.655 + } else { 1.656 + Assert.error("Could not determine type argument position of tree " + tree + 1.657 + " within frame " + frame); 1.658 + } 1.659 + 1.660 + List<JCTree> newPath = path.tail; 1.661 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.662 + return; 1.663 + } 1.664 + 1.665 + case ARRAY_TYPE: { 1.666 + ListBuffer<TypePathEntry> index = ListBuffer.lb(); 1.667 + index = index.append(TypePathEntry.ARRAY); 1.668 + List<JCTree> newPath = path.tail; 1.669 + while (true) { 1.670 + JCTree npHead = newPath.tail.head; 1.671 + if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) { 1.672 + newPath = newPath.tail; 1.673 + index = index.append(TypePathEntry.ARRAY); 1.674 + } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { 1.675 + newPath = newPath.tail; 1.676 + } else { 1.677 + break; 1.678 + } 1.679 + } 1.680 + p.location = p.location.prependList(index.toList()); 1.681 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.682 + return; 1.683 + } 1.684 + 1.685 + case TYPE_PARAMETER: 1.686 + if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) { 1.687 + JCClassDecl clazz = (JCClassDecl)path.tail.tail.head; 1.688 + p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND; 1.689 + p.parameter_index = clazz.typarams.indexOf(path.tail.head); 1.690 + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 1.691 + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { 1.692 + // Account for an implicit Object as bound 0 1.693 + p.bound_index += 1; 1.694 + } 1.695 + } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) { 1.696 + JCMethodDecl method = (JCMethodDecl)path.tail.tail.head; 1.697 + p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND; 1.698 + p.parameter_index = method.typarams.indexOf(path.tail.head); 1.699 + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); 1.700 + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { 1.701 + // Account for an implicit Object as bound 0 1.702 + p.bound_index += 1; 1.703 + } 1.704 + } else { 1.705 + Assert.error("Could not determine position of tree " + tree + 1.706 + " within frame " + frame); 1.707 + } 1.708 + p.pos = frame.pos; 1.709 + return; 1.710 + 1.711 + case VARIABLE: 1.712 + VarSymbol v = ((JCVariableDecl)frame).sym; 1.713 + p.pos = frame.pos; 1.714 + switch (v.getKind()) { 1.715 + case LOCAL_VARIABLE: 1.716 + p.type = TargetType.LOCAL_VARIABLE; 1.717 + break; 1.718 + case FIELD: 1.719 + p.type = TargetType.FIELD; 1.720 + break; 1.721 + case PARAMETER: 1.722 + if (v.getQualifiedName().equals(names._this)) { 1.723 + // TODO: Intro a separate ElementKind? 1.724 + p.type = TargetType.METHOD_RECEIVER; 1.725 + } else { 1.726 + p.type = TargetType.METHOD_FORMAL_PARAMETER; 1.727 + p.parameter_index = methodParamIndex(path, frame); 1.728 + } 1.729 + break; 1.730 + case EXCEPTION_PARAMETER: 1.731 + p.type = TargetType.EXCEPTION_PARAMETER; 1.732 + break; 1.733 + case RESOURCE_VARIABLE: 1.734 + p.type = TargetType.RESOURCE_VARIABLE; 1.735 + break; 1.736 + default: 1.737 + Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind()); 1.738 + } 1.739 + return; 1.740 + 1.741 + case ANNOTATED_TYPE: { 1.742 + if (frame == tree) { 1.743 + // This is only true for the first annotated type we see. 1.744 + // For any other annotated types along the path, we do 1.745 + // not care about inner types. 1.746 + JCAnnotatedType atypetree = (JCAnnotatedType) frame; 1.747 + final Type utype = atypetree.underlyingType.type; 1.748 + Symbol tsym = utype.tsym; 1.749 + if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) || 1.750 + utype.getKind().equals(TypeKind.WILDCARD) || 1.751 + utype.getKind().equals(TypeKind.ARRAY)) { 1.752 + // Type parameters, wildcards, and arrays have the declaring 1.753 + // class/method as enclosing elements. 1.754 + // There is actually nothing to do for them. 1.755 + } else { 1.756 + locateNestedTypes(utype, p); 1.757 + } 1.758 + } 1.759 + List<JCTree> newPath = path.tail; 1.760 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.761 + return; 1.762 + } 1.763 + 1.764 + case UNION_TYPE: { 1.765 + // TODO: can we store any information here to help in 1.766 + // determining the final position? 1.767 + List<JCTree> newPath = path.tail; 1.768 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.769 + return; 1.770 + } 1.771 + 1.772 + case METHOD_INVOCATION: { 1.773 + JCMethodInvocation invocation = (JCMethodInvocation)frame; 1.774 + if (!invocation.typeargs.contains(tree)) { 1.775 + Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation); 1.776 + } 1.777 + p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; 1.778 + p.pos = invocation.pos; 1.779 + p.type_index = invocation.typeargs.indexOf(tree); 1.780 + return; 1.781 + } 1.782 + 1.783 + case EXTENDS_WILDCARD: 1.784 + case SUPER_WILDCARD: { 1.785 + // Annotations in wildcard bounds 1.786 + p.location = p.location.prepend(TypePathEntry.WILDCARD); 1.787 + List<JCTree> newPath = path.tail; 1.788 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.789 + return; 1.790 + } 1.791 + 1.792 + case MEMBER_SELECT: { 1.793 + List<JCTree> newPath = path.tail; 1.794 + resolveFrame(newPath.head, newPath.tail.head, newPath, p); 1.795 + return; 1.796 + } 1.797 + 1.798 + default: 1.799 + Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() + 1.800 + "\n Looking for tree: " + tree); 1.801 + return; 1.802 + } 1.803 + } 1.804 + 1.805 + private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { 1.806 + // The number of "steps" to get from the full type to the 1.807 + // left-most outer type. 1.808 + ListBuffer<TypePathEntry> depth = ListBuffer.lb(); 1.809 + 1.810 + Type encl = type.getEnclosingType(); 1.811 + while (encl != null && 1.812 + encl.getKind() != TypeKind.NONE && 1.813 + encl.getKind() != TypeKind.ERROR) { 1.814 + depth = depth.append(TypePathEntry.INNER_TYPE); 1.815 + encl = encl.getEnclosingType(); 1.816 + } 1.817 + if (depth.nonEmpty()) { 1.818 + p.location = p.location.prependList(depth.toList()); 1.819 + } 1.820 + } 1.821 + 1.822 + private static int methodParamIndex(List<JCTree> path, JCTree param) { 1.823 + List<JCTree> curr = path; 1.824 + while (curr.head.getTag() != Tag.METHODDEF) { 1.825 + curr = curr.tail; 1.826 + } 1.827 + JCMethodDecl method = (JCMethodDecl)curr.head; 1.828 + return method.params.indexOf(param); 1.829 + } 1.830 + 1.831 + // Each class (including enclosed inner classes) is visited separately. 1.832 + // This flag is used to prevent from visiting inner classes. 1.833 + private boolean isInClass = false; 1.834 + 1.835 + @Override 1.836 + public void visitClassDef(JCClassDecl tree) { 1.837 + if (isInClass) 1.838 + return; 1.839 + isInClass = true; 1.840 + if (sigOnly) { 1.841 + scan(tree.mods); 1.842 + scan(tree.typarams); 1.843 + scan(tree.extending); 1.844 + scan(tree.implementing); 1.845 + } 1.846 + scan(tree.defs); 1.847 + } 1.848 + 1.849 + /** 1.850 + * Resolve declaration vs. type annotations in methods and 1.851 + * then determine the positions. 1.852 + */ 1.853 + @Override 1.854 + public void visitMethodDef(final JCMethodDecl tree) { 1.855 + if (tree.sym == null) { 1.856 + // Something most be wrong, e.g. a class not found. 1.857 + // Quietly ignore. (See test FailOver15.java) 1.858 + return; 1.859 + } 1.860 + if (sigOnly) { 1.861 + { 1.862 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.863 + pos.type = TargetType.METHOD_RETURN; 1.864 + if (tree.sym.isConstructor()) { 1.865 + pos.pos = tree.pos; 1.866 + // Use null to mark that the annotations go with the symbol. 1.867 + separateAnnotationsKinds(tree, null, tree.sym, pos); 1.868 + } else { 1.869 + pos.pos = tree.restype.pos; 1.870 + separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(), 1.871 + tree.sym, pos); 1.872 + } 1.873 + } 1.874 + if (tree.recvparam != null && tree.recvparam.sym != null) { 1.875 + // TODO: make sure there are no declaration annotations. 1.876 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.877 + pos.type = TargetType.METHOD_RECEIVER; 1.878 + pos.pos = tree.recvparam.vartype.pos; 1.879 + separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type, 1.880 + tree.recvparam.sym, pos); 1.881 + } 1.882 + int i = 0; 1.883 + for (JCVariableDecl param : tree.params) { 1.884 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.885 + pos.type = TargetType.METHOD_FORMAL_PARAMETER; 1.886 + pos.parameter_index = i; 1.887 + pos.pos = param.vartype.pos; 1.888 + separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); 1.889 + ++i; 1.890 + } 1.891 + } 1.892 + 1.893 + push(tree); 1.894 + // super.visitMethodDef(tree); 1.895 + if (sigOnly) { 1.896 + scan(tree.mods); 1.897 + scan(tree.restype); 1.898 + scan(tree.typarams); 1.899 + scan(tree.recvparam); 1.900 + scan(tree.params); 1.901 + scan(tree.thrown); 1.902 + } else { 1.903 + scan(tree.defaultValue); 1.904 + scan(tree.body); 1.905 + } 1.906 + pop(); 1.907 + } 1.908 + 1.909 + /** 1.910 + * Resolve declaration vs. type annotations in variable declarations and 1.911 + * then determine the positions. 1.912 + */ 1.913 + @Override 1.914 + public void visitVarDef(final JCVariableDecl tree) { 1.915 + if (tree.sym == null) { 1.916 + // Something is wrong already. Quietly ignore. 1.917 + } else if (tree.sym.getKind() == ElementKind.FIELD) { 1.918 + if (sigOnly) { 1.919 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.920 + pos.type = TargetType.FIELD; 1.921 + pos.pos = tree.pos; 1.922 + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1.923 + } 1.924 + } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) { 1.925 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.926 + pos.type = TargetType.LOCAL_VARIABLE; 1.927 + pos.pos = tree.pos; 1.928 + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1.929 + } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { 1.930 + // System.out.println("Found exception param: " + tree); 1.931 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.932 + pos.type = TargetType.EXCEPTION_PARAMETER; 1.933 + pos.pos = tree.pos; 1.934 + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1.935 + } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) { 1.936 + TypeAnnotationPosition pos = new TypeAnnotationPosition(); 1.937 + pos.type = TargetType.RESOURCE_VARIABLE; 1.938 + pos.pos = tree.pos; 1.939 + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1.940 + } else { 1.941 + // There is nothing else in a variable declaration that needs separation. 1.942 + // System.out.println("We found a: " + tree); 1.943 + } 1.944 + 1.945 + push(tree); 1.946 + // super.visitVarDef(tree); 1.947 + scan(tree.mods); 1.948 + scan(tree.vartype); 1.949 + if (!sigOnly) { 1.950 + scan(tree.init); 1.951 + } 1.952 + pop(); 1.953 + } 1.954 + 1.955 + @Override 1.956 + public void visitBlock(JCBlock tree) { 1.957 + // Do not descend into top-level blocks when only interested 1.958 + // in the signature. 1.959 + if (!sigOnly) { 1.960 + scan(tree.stats); 1.961 + } 1.962 + } 1.963 + 1.964 + @Override 1.965 + public void visitAnnotatedType(JCAnnotatedType tree) { 1.966 + push(tree); 1.967 + findPosition(tree, tree, tree.annotations); 1.968 + pop(); 1.969 + super.visitAnnotatedType(tree); 1.970 + } 1.971 + 1.972 + @Override 1.973 + public void visitTypeParameter(JCTypeParameter tree) { 1.974 + findPosition(tree, peek2(), tree.annotations); 1.975 + super.visitTypeParameter(tree); 1.976 + } 1.977 + 1.978 + @Override 1.979 + public void visitNewArray(JCNewArray tree) { 1.980 + findPosition(tree, tree, tree.annotations); 1.981 + int dimAnnosCount = tree.dimAnnotations.size(); 1.982 + ListBuffer<TypePathEntry> depth = ListBuffer.lb(); 1.983 + 1.984 + // handle annotations associated with dimensions 1.985 + for (int i = 0; i < dimAnnosCount; ++i) { 1.986 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.987 + p.pos = tree.pos; 1.988 + p.type = TargetType.NEW; 1.989 + if (i != 0) { 1.990 + depth = depth.append(TypePathEntry.ARRAY); 1.991 + p.location = p.location.appendList(depth.toList()); 1.992 + } 1.993 + 1.994 + setTypeAnnotationPos(tree.dimAnnotations.get(i), p); 1.995 + } 1.996 + 1.997 + // handle "free" annotations 1.998 + // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; 1.999 + // TODO: is depth.size == i here? 1.1000 + JCExpression elemType = tree.elemtype; 1.1001 + while (elemType != null) { 1.1002 + if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { 1.1003 + JCAnnotatedType at = (JCAnnotatedType)elemType; 1.1004 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.1005 + p.type = TargetType.NEW; 1.1006 + p.pos = tree.pos; 1.1007 + p.location = p.location.appendList(depth.toList()); 1.1008 + setTypeAnnotationPos(at.annotations, p); 1.1009 + elemType = at.underlyingType; 1.1010 + } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) { 1.1011 + depth = depth.append(TypePathEntry.ARRAY); 1.1012 + elemType = ((JCArrayTypeTree)elemType).elemtype; 1.1013 + } else { 1.1014 + break; 1.1015 + } 1.1016 + } 1.1017 + scan(tree.elems); 1.1018 + } 1.1019 + 1.1020 + private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) { 1.1021 + if (!annotations.isEmpty()) { 1.1022 + /* 1.1023 + System.out.println("Finding pos for: " + annotations); 1.1024 + System.out.println(" tree: " + tree); 1.1025 + System.out.println(" frame: " + frame); 1.1026 + */ 1.1027 + TypeAnnotationPosition p = new TypeAnnotationPosition(); 1.1028 + resolveFrame(tree, frame, frames.toList(), p); 1.1029 + setTypeAnnotationPos(annotations, p); 1.1030 + } 1.1031 + } 1.1032 + 1.1033 + private static void setTypeAnnotationPos(List<JCAnnotation> annotations, 1.1034 + TypeAnnotationPosition position) { 1.1035 + for (JCAnnotation anno : annotations) { 1.1036 + ((Attribute.TypeCompound) anno.attribute).position = position; 1.1037 + } 1.1038 + } 1.1039 + } 1.1040 +}