src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

changeset 2056
5043e7056be8
parent 2047
5f915a0c9615
child 2103
b1b4a6dcc282
equal deleted inserted replaced
2055:184c0d6698c3 2056:5043e7056be8
29 import javax.lang.model.element.ElementKind; 29 import javax.lang.model.element.ElementKind;
30 import javax.lang.model.type.TypeKind; 30 import javax.lang.model.type.TypeKind;
31 31
32 import javax.tools.JavaFileObject; 32 import javax.tools.JavaFileObject;
33 33
34 import com.sun.tools.javac.code.Attribute;
35 import com.sun.tools.javac.code.Attribute.TypeCompound; 34 import com.sun.tools.javac.code.Attribute.TypeCompound;
36 import com.sun.tools.javac.code.Flags;
37 import com.sun.tools.javac.code.Kinds;
38 import com.sun.tools.javac.code.Type.AnnotatedType; 35 import com.sun.tools.javac.code.Type.AnnotatedType;
39 import com.sun.tools.javac.code.Type.ArrayType; 36 import com.sun.tools.javac.code.Type.ArrayType;
40 import com.sun.tools.javac.code.Type.CapturedType; 37 import com.sun.tools.javac.code.Type.CapturedType;
41 import com.sun.tools.javac.code.Type.ClassType; 38 import com.sun.tools.javac.code.Type.ClassType;
42 import com.sun.tools.javac.code.Type.ErrorType; 39 import com.sun.tools.javac.code.Type.ErrorType;
47 import com.sun.tools.javac.code.Type.UndetVar; 44 import com.sun.tools.javac.code.Type.UndetVar;
48 import com.sun.tools.javac.code.Type.Visitor; 45 import com.sun.tools.javac.code.Type.Visitor;
49 import com.sun.tools.javac.code.Type.WildcardType; 46 import com.sun.tools.javac.code.Type.WildcardType;
50 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; 47 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
51 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; 48 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
52 import com.sun.tools.javac.code.TypeTag;
53 import com.sun.tools.javac.code.Symbol.VarSymbol; 49 import com.sun.tools.javac.code.Symbol.VarSymbol;
54 import com.sun.tools.javac.code.Symbol.MethodSymbol; 50 import com.sun.tools.javac.code.Symbol.MethodSymbol;
55 import com.sun.tools.javac.comp.Annotate; 51 import com.sun.tools.javac.comp.Annotate;
56 import com.sun.tools.javac.comp.Annotate.Annotator; 52 import com.sun.tools.javac.comp.Annotate.Annotator;
57 import com.sun.tools.javac.comp.AttrContext; 53 import com.sun.tools.javac.comp.AttrContext;
68 import com.sun.tools.javac.tree.JCTree.JCTypeApply; 64 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
69 import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 65 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
70 import com.sun.tools.javac.tree.TreeScanner; 66 import com.sun.tools.javac.tree.TreeScanner;
71 import com.sun.tools.javac.tree.JCTree.*; 67 import com.sun.tools.javac.tree.JCTree.*;
72 import com.sun.tools.javac.util.Assert; 68 import com.sun.tools.javac.util.Assert;
69 import com.sun.tools.javac.util.Context;
73 import com.sun.tools.javac.util.List; 70 import com.sun.tools.javac.util.List;
74 import com.sun.tools.javac.util.ListBuffer; 71 import com.sun.tools.javac.util.ListBuffer;
75 import com.sun.tools.javac.util.Log; 72 import com.sun.tools.javac.util.Log;
76 import com.sun.tools.javac.util.Names; 73 import com.sun.tools.javac.util.Names;
77 74
81 * separate declaration from type annotations and insert the type 78 * separate declaration from type annotations and insert the type
82 * annotations to their types; 79 * annotations to their types;
83 * and determine the TypeAnnotationPositions for all type annotations. 80 * and determine the TypeAnnotationPositions for all type annotations.
84 */ 81 */
85 public class TypeAnnotations { 82 public class TypeAnnotations {
86 // Class cannot be instantiated. 83 protected static final Context.Key<TypeAnnotations> typeAnnosKey =
87 private TypeAnnotations() {} 84 new Context.Key<TypeAnnotations>();
85
86 public static TypeAnnotations instance(Context context) {
87 TypeAnnotations instance = context.get(typeAnnosKey);
88 if (instance == null)
89 instance = new TypeAnnotations(context);
90 return instance;
91 }
92
93 final Log log;
94 final Names names;
95 final Symtab syms;
96 final Annotate annotate;
97
98 protected TypeAnnotations(Context context) {
99 context.put(typeAnnosKey, this);
100 names = Names.instance(context);
101 log = Log.instance(context);
102 syms = Symtab.instance(context);
103 annotate = Annotate.instance(context);
104 }
88 105
89 /** 106 /**
90 * Separate type annotations from declaration annotations and 107 * Separate type annotations from declaration annotations and
91 * determine the correct positions for type annotations. 108 * determine the correct positions for type annotations.
92 * This version only visits types in signatures and should be 109 * This version only visits types in signatures and should be
93 * called from MemberEnter. 110 * called from MemberEnter.
94 * The method takes the Annotate object as parameter and 111 * The method takes the Annotate object as parameter and
95 * adds an Annotator to the correct Annotate queue for 112 * adds an Annotator to the correct Annotate queue for
96 * later processing. 113 * later processing.
97 */ 114 */
98 public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, 115 public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
99 final Log log, final Env<AttrContext> env, final JCClassDecl tree, final Annotate annotate) {
100 annotate.afterRepeated( new Annotator() { 116 annotate.afterRepeated( new Annotator() {
101 @Override 117 @Override
102 public void enterAnnotation() { 118 public void enterAnnotation() {
103 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); 119 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
104 120
105 try { 121 try {
106 new TypeAnnotationPositions(syms, names, log, true).scan(tree); 122 new TypeAnnotationPositions(true).scan(tree);
107 } finally { 123 } finally {
108 log.useSource(oldSource); 124 log.useSource(oldSource);
109 } 125 }
110 } 126 }
111 } ); 127 } );
113 129
114 /** 130 /**
115 * This version only visits types in bodies, that is, field initializers, 131 * This version only visits types in bodies, that is, field initializers,
116 * top-level blocks, and method bodies, and should be called from Attr. 132 * top-level blocks, and method bodies, and should be called from Attr.
117 */ 133 */
118 public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) { 134 public void organizeTypeAnnotationsBodies(JCClassDecl tree) {
119 new TypeAnnotationPositions(syms, names, log, false).scan(tree); 135 new TypeAnnotationPositions(false).scan(tree);
120 } 136 }
121 137
122 public enum AnnotationType { DECLARATION, TYPE, BOTH }; 138 public enum AnnotationType { DECLARATION, TYPE, BOTH };
123 139
124 /** 140 /**
125 * Determine whether an annotation is a declaration annotation, 141 * Determine whether an annotation is a declaration annotation,
126 * a type annotation, or both. 142 * a type annotation, or both.
127 */ 143 */
128 public static AnnotationType annotationType(Symtab syms, Names names, 144 public AnnotationType annotationType(Attribute.Compound a, Symbol s) {
129 Attribute.Compound a, Symbol s) {
130 Attribute.Compound atTarget = 145 Attribute.Compound atTarget =
131 a.type.tsym.attribute(syms.annotationTargetType.tsym); 146 a.type.tsym.attribute(syms.annotationTargetType.tsym);
132 if (atTarget == null) { 147 if (atTarget == null) {
133 return inferTargetMetaInfo(a, s); 148 return inferTargetMetaInfo(a, s);
134 } 149 }
213 private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) { 228 private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
214 return AnnotationType.DECLARATION; 229 return AnnotationType.DECLARATION;
215 } 230 }
216 231
217 232
218 private static class TypeAnnotationPositions extends TreeScanner { 233 private class TypeAnnotationPositions extends TreeScanner {
219 234
220 private final Symtab syms;
221 private final Names names;
222 private final Log log;
223 private final boolean sigOnly; 235 private final boolean sigOnly;
224 236
225 private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) { 237 TypeAnnotationPositions(boolean sigOnly) {
226 this.syms = syms;
227 this.names = names;
228 this.log = log;
229 this.sigOnly = sigOnly; 238 this.sigOnly = sigOnly;
230 } 239 }
231 240
232 /* 241 /*
233 * When traversing the AST we keep the "frames" of visited 242 * When traversing the AST we keep the "frames" of visited
263 List<Attribute.Compound> annotations = sym.getRawAttributes(); 272 List<Attribute.Compound> annotations = sym.getRawAttributes();
264 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>(); 273 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>();
265 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>(); 274 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
266 275
267 for (Attribute.Compound a : annotations) { 276 for (Attribute.Compound a : annotations) {
268 switch (annotationType(syms, names, a, sym)) { 277 switch (annotationType(a, sym)) {
269 case DECLARATION: 278 case DECLARATION:
270 declAnnos.append(a); 279 declAnnos.append(a);
271 break; 280 break;
272 case BOTH: { 281 case BOTH: {
273 declAnnos.append(a); 282 declAnnos.append(a);
299 sym.appendUniqueTypeAttributes(typeAnnotations); 308 sym.appendUniqueTypeAttributes(typeAnnotations);
300 return; 309 return;
301 } 310 }
302 311
303 // type is non-null and annotations are added to that type 312 // type is non-null and annotations are added to that type
304 type = typeWithAnnotations(typetree, type, typeAnnotations, log); 313 type = typeWithAnnotations(typetree, type, typeAnnotations);
305 314
306 if (sym.getKind() == ElementKind.METHOD) { 315 if (sym.getKind() == ElementKind.METHOD) {
307 sym.type.asMethodType().restype = type; 316 sym.type.asMethodType().restype = type;
308 } else if (sym.getKind() == ElementKind.PARAMETER) { 317 } else if (sym.getKind() == ElementKind.PARAMETER) {
309 sym.type = type; 318 sym.type = type;
350 // need to set its position explicitly. 359 // need to set its position explicitly.
351 // The method returns a copy of type that contains these annotations. 360 // The method returns a copy of type that contains these annotations.
352 // 361 //
353 // As a side effect the method sets the type annotation position of "annotations". 362 // As a side effect the method sets the type annotation position of "annotations".
354 // Note that it is assumed that all annotations share the same position. 363 // Note that it is assumed that all annotations share the same position.
355 private static Type typeWithAnnotations(final JCTree typetree, final Type type, 364 private Type typeWithAnnotations(final JCTree typetree, final Type type,
356 final List<Attribute.TypeCompound> annotations, Log log) { 365 final List<Attribute.TypeCompound> annotations) {
357 // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", 366 // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
358 // typetree, type, annotations); 367 // typetree, type, annotations);
359 if (annotations.isEmpty()) { 368 if (annotations.isEmpty()) {
360 return type; 369 return type;
361 } 370 }
398 tomodify = (Type.ArrayType) tomodify.elemtype; 407 tomodify = (Type.ArrayType) tomodify.elemtype;
399 } 408 }
400 arTree = arrayTypeTree(arTree.elemtype); 409 arTree = arrayTypeTree(arTree.elemtype);
401 depth = depth.append(TypePathEntry.ARRAY); 410 depth = depth.append(TypePathEntry.ARRAY);
402 } 411 }
403 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log); 412 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations);
404 tomodify.elemtype = arelemType; 413 tomodify.elemtype = arelemType;
405 { 414 {
406 // All annotations share the same position; modify the first one. 415 // All annotations share the same position; modify the first one.
407 Attribute.TypeCompound a = annotations.get(0); 416 Attribute.TypeCompound a = annotations.get(0);
408 TypeAnnotationPosition p = a.position; 417 TypeAnnotationPosition p = a.position;
415 return type; 424 return type;
416 } else if (type.getKind() == TypeKind.UNION) { 425 } else if (type.getKind() == TypeKind.UNION) {
417 // There is a TypeKind, but no TypeTag. 426 // There is a TypeKind, but no TypeTag.
418 JCTypeUnion tutree = (JCTypeUnion) typetree; 427 JCTypeUnion tutree = (JCTypeUnion) typetree;
419 JCExpression fst = tutree.alternatives.get(0); 428 JCExpression fst = tutree.alternatives.get(0);
420 Type res = typeWithAnnotations(fst, fst.type, annotations, log); 429 Type res = typeWithAnnotations(fst, fst.type, annotations);
421 fst.type = res; 430 fst.type = res;
422 // TODO: do we want to set res as first element in uct.alternatives? 431 // TODO: do we want to set res as first element in uct.alternatives?
423 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; 432 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
424 // Return the un-annotated union-type. 433 // Return the un-annotated union-type.
425 return type; 434 return type;
503 typetree.type = ret; 512 typetree.type = ret;
504 return ret; 513 return ret;
505 } 514 }
506 } 515 }
507 516
508 private static JCArrayTypeTree arrayTypeTree(JCTree typetree) { 517 private JCArrayTypeTree arrayTypeTree(JCTree typetree) {
509 if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { 518 if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
510 return (JCArrayTypeTree) typetree; 519 return (JCArrayTypeTree) typetree;
511 } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { 520 } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
512 return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType; 521 return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
513 } else { 522 } else {
530 * @param type The type to copy. 539 * @param type The type to copy.
531 * @param stopAt The type to stop at. 540 * @param stopAt The type to stop at.
532 * @param annotations The annotations to insert. 541 * @param annotations The annotations to insert.
533 * @return A copy of type that contains the annotations. 542 * @return A copy of type that contains the annotations.
534 */ 543 */
535 private static Type typeWithAnnotations(final Type type, 544 private Type typeWithAnnotations(final Type type,
536 final Type stopAt, 545 final Type stopAt,
537 final List<Attribute.TypeCompound> annotations) { 546 final List<Attribute.TypeCompound> annotations) {
538 Visitor<Type, List<TypeCompound>> visitor = 547 Visitor<Type, List<TypeCompound>> visitor =
539 new Type.Visitor<Type, List<Attribute.TypeCompound>>() { 548 new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
540 @Override 549 @Override
617 }; 626 };
618 627
619 return type.accept(visitor, annotations); 628 return type.accept(visitor, annotations);
620 } 629 }
621 630
622 private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { 631 private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
623 // It is safe to alias the position. 632 // It is safe to alias the position.
624 return new Attribute.TypeCompound(a, p); 633 return new Attribute.TypeCompound(a, p);
625 } 634 }
626 635
627 636
951 "\n Looking for tree: " + tree); 960 "\n Looking for tree: " + tree);
952 return; 961 return;
953 } 962 }
954 } 963 }
955 964
956 private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { 965 private void locateNestedTypes(Type type, TypeAnnotationPosition p) {
957 // The number of "steps" to get from the full type to the 966 // The number of "steps" to get from the full type to the
958 // left-most outer type. 967 // left-most outer type.
959 ListBuffer<TypePathEntry> depth = new ListBuffer<>(); 968 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
960 969
961 Type encl = type.getEnclosingType(); 970 Type encl = type.getEnclosingType();
968 if (depth.nonEmpty()) { 977 if (depth.nonEmpty()) {
969 p.location = p.location.prependList(depth.toList()); 978 p.location = p.location.prependList(depth.toList());
970 } 979 }
971 } 980 }
972 981
973 private static int methodParamIndex(List<JCTree> path, JCTree param) { 982 private int methodParamIndex(List<JCTree> path, JCTree param) {
974 List<JCTree> curr = path; 983 List<JCTree> curr = path;
975 while (curr.head.getTag() != Tag.METHODDEF && 984 while (curr.head.getTag() != Tag.METHODDEF &&
976 curr.head.getTag() != Tag.LAMBDA) { 985 curr.head.getTag() != Tag.LAMBDA) {
977 curr = curr.tail; 986 curr = curr.tail;
978 } 987 }
1282 resolveFrame(tree, frame, frames.toList(), p); 1291 resolveFrame(tree, frame, frames.toList(), p);
1283 setTypeAnnotationPos(annotations, p); 1292 setTypeAnnotationPos(annotations, p);
1284 } 1293 }
1285 } 1294 }
1286 1295
1287 private static void setTypeAnnotationPos(List<JCAnnotation> annotations, 1296 private void setTypeAnnotationPos(List<JCAnnotation> annotations,
1288 TypeAnnotationPosition position) { 1297 TypeAnnotationPosition position) {
1289 for (JCAnnotation anno : annotations) { 1298 for (JCAnnotation anno : annotations) {
1290 // attribute might be null during DeferredAttr; 1299 // attribute might be null during DeferredAttr;
1291 // we will be back later. 1300 // we will be back later.
1292 if (anno.attribute != null) { 1301 if (anno.attribute != null) {

mercurial