Tue, 15 Oct 2013 15:57:13 -0700
8026564: import changes from type-annotations forest
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com
1 /*
2 * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import javax.lang.model.element.Element;
29 import javax.lang.model.element.ElementKind;
30 import javax.lang.model.type.TypeKind;
32 import javax.tools.JavaFileObject;
34 import com.sun.tools.javac.code.Attribute.TypeCompound;
35 import com.sun.tools.javac.code.Type.AnnotatedType;
36 import com.sun.tools.javac.code.Type.ArrayType;
37 import com.sun.tools.javac.code.Type.CapturedType;
38 import com.sun.tools.javac.code.Type.ClassType;
39 import com.sun.tools.javac.code.Type.ErrorType;
40 import com.sun.tools.javac.code.Type.ForAll;
41 import com.sun.tools.javac.code.Type.MethodType;
42 import com.sun.tools.javac.code.Type.PackageType;
43 import com.sun.tools.javac.code.Type.TypeVar;
44 import com.sun.tools.javac.code.Type.UndetVar;
45 import com.sun.tools.javac.code.Type.Visitor;
46 import com.sun.tools.javac.code.Type.WildcardType;
47 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
48 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
49 import com.sun.tools.javac.code.Symbol.VarSymbol;
50 import com.sun.tools.javac.code.Symbol.MethodSymbol;
51 import com.sun.tools.javac.comp.Annotate;
52 import com.sun.tools.javac.comp.Annotate.Worker;
53 import com.sun.tools.javac.comp.Attr;
54 import com.sun.tools.javac.comp.AttrContext;
55 import com.sun.tools.javac.comp.Env;
56 import com.sun.tools.javac.tree.JCTree;
57 import com.sun.tools.javac.tree.TreeInfo;
58 import com.sun.tools.javac.tree.JCTree.JCBlock;
59 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
60 import com.sun.tools.javac.tree.JCTree.JCExpression;
61 import com.sun.tools.javac.tree.JCTree.JCLambda;
62 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
63 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
64 import com.sun.tools.javac.tree.JCTree.JCNewClass;
65 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
66 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
67 import com.sun.tools.javac.tree.TreeScanner;
68 import com.sun.tools.javac.tree.JCTree.*;
69 import com.sun.tools.javac.util.Assert;
70 import com.sun.tools.javac.util.Context;
71 import com.sun.tools.javac.util.List;
72 import com.sun.tools.javac.util.ListBuffer;
73 import com.sun.tools.javac.util.Log;
74 import com.sun.tools.javac.util.Names;
75 import com.sun.tools.javac.util.Options;
77 /**
78 * Contains operations specific to processing type annotations.
79 * This class has two functions:
80 * separate declaration from type annotations and insert the type
81 * annotations to their types;
82 * and determine the TypeAnnotationPositions for all type annotations.
83 */
84 public class TypeAnnotations {
85 protected static final Context.Key<TypeAnnotations> typeAnnosKey =
86 new Context.Key<TypeAnnotations>();
88 public static TypeAnnotations instance(Context context) {
89 TypeAnnotations instance = context.get(typeAnnosKey);
90 if (instance == null)
91 instance = new TypeAnnotations(context);
92 return instance;
93 }
95 final Log log;
96 final Names names;
97 final Symtab syms;
98 final Annotate annotate;
99 final Attr attr;
100 private final boolean typeAnnoAsserts;
102 protected TypeAnnotations(Context context) {
103 context.put(typeAnnosKey, this);
104 names = Names.instance(context);
105 log = Log.instance(context);
106 syms = Symtab.instance(context);
107 annotate = Annotate.instance(context);
108 attr = Attr.instance(context);
109 Options options = Options.instance(context);
110 typeAnnoAsserts = options.isSet("TypeAnnotationAsserts");
111 }
113 /**
114 * Separate type annotations from declaration annotations and
115 * determine the correct positions for type annotations.
116 * This version only visits types in signatures and should be
117 * called from MemberEnter.
118 * The method takes the Annotate object as parameter and
119 * adds an Annotate.Worker to the correct Annotate queue for
120 * later processing.
121 */
122 public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
123 annotate.afterRepeated( new Worker() {
124 @Override
125 public void run() {
126 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
128 try {
129 new TypeAnnotationPositions(true).scan(tree);
130 } finally {
131 log.useSource(oldSource);
132 }
133 }
134 } );
135 }
137 public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
138 annotate.validate(new Worker() { //validate annotations
139 @Override
140 public void run() {
141 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
143 try {
144 attr.validateTypeAnnotations(tree, true);
145 } finally {
146 log.useSource(oldSource);
147 }
148 }
149 } );
150 }
152 /**
153 * This version only visits types in bodies, that is, field initializers,
154 * top-level blocks, and method bodies, and should be called from Attr.
155 */
156 public void organizeTypeAnnotationsBodies(JCClassDecl tree) {
157 new TypeAnnotationPositions(false).scan(tree);
158 }
160 public enum AnnotationType { DECLARATION, TYPE, BOTH };
162 /**
163 * Determine whether an annotation is a declaration annotation,
164 * a type annotation, or both.
165 */
166 public AnnotationType annotationType(Attribute.Compound a, Symbol s) {
167 Attribute.Compound atTarget =
168 a.type.tsym.attribute(syms.annotationTargetType.tsym);
169 if (atTarget == null) {
170 return inferTargetMetaInfo(a, s);
171 }
172 Attribute atValue = atTarget.member(names.value);
173 if (!(atValue instanceof Attribute.Array)) {
174 Assert.error("annotationType(): bad @Target argument " + atValue +
175 " (" + atValue.getClass() + ")");
176 return AnnotationType.DECLARATION; // error recovery
177 }
178 Attribute.Array arr = (Attribute.Array) atValue;
179 boolean isDecl = false, isType = false;
180 for (Attribute app : arr.values) {
181 if (!(app instanceof Attribute.Enum)) {
182 Assert.error("annotationType(): unrecognized Attribute kind " + app +
183 " (" + app.getClass() + ")");
184 isDecl = true;
185 continue;
186 }
187 Attribute.Enum e = (Attribute.Enum) app;
188 if (e.value.name == names.TYPE) {
189 if (s.kind == Kinds.TYP)
190 isDecl = true;
191 } else if (e.value.name == names.FIELD) {
192 if (s.kind == Kinds.VAR &&
193 s.owner.kind != Kinds.MTH)
194 isDecl = true;
195 } else if (e.value.name == names.METHOD) {
196 if (s.kind == Kinds.MTH &&
197 !s.isConstructor())
198 isDecl = true;
199 } else if (e.value.name == names.PARAMETER) {
200 if (s.kind == Kinds.VAR &&
201 s.owner.kind == Kinds.MTH &&
202 (s.flags() & Flags.PARAMETER) != 0)
203 isDecl = true;
204 } else if (e.value.name == names.CONSTRUCTOR) {
205 if (s.kind == Kinds.MTH &&
206 s.isConstructor())
207 isDecl = true;
208 } else if (e.value.name == names.LOCAL_VARIABLE) {
209 if (s.kind == Kinds.VAR &&
210 s.owner.kind == Kinds.MTH &&
211 (s.flags() & Flags.PARAMETER) == 0)
212 isDecl = true;
213 } else if (e.value.name == names.ANNOTATION_TYPE) {
214 if (s.kind == Kinds.TYP &&
215 (s.flags() & Flags.ANNOTATION) != 0)
216 isDecl = true;
217 } else if (e.value.name == names.PACKAGE) {
218 if (s.kind == Kinds.PCK)
219 isDecl = true;
220 } else if (e.value.name == names.TYPE_USE) {
221 if (s.kind == Kinds.TYP ||
222 s.kind == Kinds.VAR ||
223 (s.kind == Kinds.MTH && !s.isConstructor() &&
224 !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
225 (s.kind == Kinds.MTH && s.isConstructor()))
226 isType = true;
227 } else if (e.value.name == names.TYPE_PARAMETER) {
228 /* Irrelevant in this case */
229 // TYPE_PARAMETER doesn't aid in distinguishing between
230 // Type annotations and declaration annotations on an
231 // Element
232 } else {
233 Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
234 " (" + e.value.name.getClass() + ")");
235 isDecl = true;
236 }
237 }
238 if (isDecl && isType) {
239 return AnnotationType.BOTH;
240 } else if (isType) {
241 return AnnotationType.TYPE;
242 } else {
243 return AnnotationType.DECLARATION;
244 }
245 }
247 /** Infer the target annotation kind, if none is give.
248 * We only infer declaration annotations.
249 */
250 private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
251 return AnnotationType.DECLARATION;
252 }
255 private class TypeAnnotationPositions extends TreeScanner {
257 private final boolean sigOnly;
259 TypeAnnotationPositions(boolean sigOnly) {
260 this.sigOnly = sigOnly;
261 }
263 /*
264 * When traversing the AST we keep the "frames" of visited
265 * trees in order to determine the position of annotations.
266 */
267 private ListBuffer<JCTree> frames = new ListBuffer<>();
269 protected void push(JCTree t) { frames = frames.prepend(t); }
270 protected JCTree pop() { return frames.next(); }
271 // could this be frames.elems.tail.head?
272 private JCTree peek2() { return frames.toList().tail.head; }
274 @Override
275 public void scan(JCTree tree) {
276 push(tree);
277 super.scan(tree);
278 pop();
279 }
281 /**
282 * Separates type annotations from declaration annotations.
283 * This step is needed because in certain locations (where declaration
284 * and type annotations can be mixed, e.g. the type of a field)
285 * we never build an JCAnnotatedType. This step finds these
286 * annotations and marks them as if they were part of the type.
287 */
288 private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym,
289 TypeAnnotationPosition pos) {
290 List<Attribute.Compound> annotations = sym.getRawAttributes();
291 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>();
292 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
293 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
295 for (Attribute.Compound a : annotations) {
296 switch (annotationType(a, sym)) {
297 case DECLARATION:
298 declAnnos.append(a);
299 break;
300 case BOTH: {
301 declAnnos.append(a);
302 Attribute.TypeCompound ta = toTypeCompound(a, pos);
303 typeAnnos.append(ta);
304 break;
305 }
306 case TYPE: {
307 Attribute.TypeCompound ta = toTypeCompound(a, pos);
308 typeAnnos.append(ta);
309 // Also keep track which annotations are only type annotations
310 onlyTypeAnnos.append(ta);
311 break;
312 }
313 }
314 }
316 sym.resetAnnotations();
317 sym.setDeclarationAttributes(declAnnos.toList());
319 if (typeAnnos.isEmpty()) {
320 return;
321 }
323 List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
325 if (type == null) {
326 // When type is null, put the type annotations to the symbol.
327 // This is used for constructor return annotations, for which
328 // no appropriate type exists.
329 sym.appendUniqueTypeAttributes(typeAnnotations);
330 return;
331 }
333 // type is non-null and annotations are added to that type
334 type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList());
336 if (sym.getKind() == ElementKind.METHOD) {
337 sym.type.asMethodType().restype = type;
338 } else if (sym.getKind() == ElementKind.PARAMETER) {
339 sym.type = type;
340 if (sym.getQualifiedName().equals(names._this)) {
341 sym.owner.type.asMethodType().recvtype = type;
342 // note that the typeAnnotations will also be added to the owner below.
343 } else {
344 MethodType methType = sym.owner.type.asMethodType();
345 List<VarSymbol> params = ((MethodSymbol)sym.owner).params;
346 List<Type> oldArgs = methType.argtypes;
347 ListBuffer<Type> newArgs = new ListBuffer<Type>();
348 while (params.nonEmpty()) {
349 if (params.head == sym) {
350 newArgs.add(type);
351 } else {
352 newArgs.add(oldArgs.head);
353 }
354 oldArgs = oldArgs.tail;
355 params = params.tail;
356 }
357 methType.argtypes = newArgs.toList();
358 }
359 } else {
360 sym.type = type;
361 }
363 sym.appendUniqueTypeAttributes(typeAnnotations);
365 if (sym.getKind() == ElementKind.PARAMETER ||
366 sym.getKind() == ElementKind.LOCAL_VARIABLE ||
367 sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
368 sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
369 // Make sure all type annotations from the symbol are also
370 // on the owner.
371 sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes());
372 }
373 }
375 // This method has a similar purpose as
376 // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
377 // We found a type annotation in a declaration annotation position,
378 // for example, on the return type.
379 // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
380 // need to set its position explicitly.
381 // The method returns a copy of type that contains these annotations.
382 //
383 // As a side effect the method sets the type annotation position of "annotations".
384 // Note that it is assumed that all annotations share the same position.
385 private Type typeWithAnnotations(final JCTree typetree, final Type type,
386 final List<Attribute.TypeCompound> annotations,
387 final List<Attribute.TypeCompound> onlyTypeAnnotations) {
388 // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n",
389 // typetree, type, annotations, onlyTypeAnnotations);
390 if (annotations.isEmpty()) {
391 return type;
392 }
393 if (type.hasTag(TypeTag.ARRAY)) {
394 Type.ArrayType arType = (Type.ArrayType) type.unannotatedType();
395 Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym);
396 Type toreturn;
397 if (type.isAnnotated()) {
398 toreturn = tomodify.annotatedType(type.getAnnotationMirrors());
399 } else {
400 toreturn = tomodify;
401 }
403 JCArrayTypeTree arTree = arrayTypeTree(typetree);
405 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
406 depth = depth.append(TypePathEntry.ARRAY);
407 while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
408 if (arType.elemtype.isAnnotated()) {
409 Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype;
410 arType = (Type.ArrayType) aelemtype.unannotatedType();
411 ArrayType prevToMod = tomodify;
412 tomodify = new Type.ArrayType(null, arType.tsym);
413 prevToMod.elemtype = (Type.AnnotatedType) tomodify.annotatedType(arType.elemtype.getAnnotationMirrors());
414 } else {
415 arType = (Type.ArrayType) arType.elemtype;
416 tomodify.elemtype = new Type.ArrayType(null, arType.tsym);
417 tomodify = (Type.ArrayType) tomodify.elemtype;
418 }
419 arTree = arrayTypeTree(arTree.elemtype);
420 depth = depth.append(TypePathEntry.ARRAY);
421 }
422 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, onlyTypeAnnotations);
423 tomodify.elemtype = arelemType;
424 {
425 // All annotations share the same position; modify the first one.
426 Attribute.TypeCompound a = annotations.get(0);
427 TypeAnnotationPosition p = a.position;
428 p.location = p.location.prependList(depth.toList());
429 }
430 typetree.type = toreturn;
431 return toreturn;
432 } else if (type.hasTag(TypeTag.TYPEVAR)) {
433 // Nothing to do for type variables.
434 return type;
435 } else if (type.getKind() == TypeKind.UNION) {
436 // There is a TypeKind, but no TypeTag.
437 JCTypeUnion tutree = (JCTypeUnion) typetree;
438 JCExpression fst = tutree.alternatives.get(0);
439 Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations);
440 fst.type = res;
441 // TODO: do we want to set res as first element in uct.alternatives?
442 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
443 // Return the un-annotated union-type.
444 return type;
445 } else {
446 Type enclTy = type;
447 Element enclEl = type.asElement();
448 JCTree enclTr = typetree;
450 while (enclEl != null &&
451 enclEl.getKind() != ElementKind.PACKAGE &&
452 enclTy != null &&
453 enclTy.getKind() != TypeKind.NONE &&
454 enclTy.getKind() != TypeKind.ERROR &&
455 (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
456 enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
457 enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
458 // Iterate also over the type tree, not just the type: the type is already
459 // completely resolved and we cannot distinguish where the annotation
460 // belongs for a nested type.
461 if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) {
462 // only change encl in this case.
463 enclTy = enclTy.getEnclosingType();
464 enclEl = enclEl.getEnclosingElement();
465 enclTr = ((JCFieldAccess)enclTr).getExpression();
466 } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) {
467 enclTr = ((JCTypeApply)enclTr).getType();
468 } else {
469 // only other option because of while condition
470 enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType();
471 }
472 }
474 /** We are trying to annotate some enclosing type,
475 * but nothing more exists.
476 */
477 if (enclTy != null &&
478 enclTy.hasTag(TypeTag.NONE)) {
479 switch (onlyTypeAnnotations.size()) {
480 case 0:
481 // Don't issue an error if all type annotations are
482 // also declaration annotations.
483 // If the annotations are also declaration annotations, they are
484 // illegal as type annotations but might be legal as declaration annotations.
485 // The normal declaration annotation checks make sure that the use is valid.
486 break;
487 case 1:
488 log.error(typetree.pos(), "cant.type.annotate.scoping.1",
489 onlyTypeAnnotations);
490 break;
491 default:
492 log.error(typetree.pos(), "cant.type.annotate.scoping",
493 onlyTypeAnnotations);
494 }
495 return type;
496 }
498 // At this point we have visited the part of the nested
499 // type that is written in the source code.
500 // Now count from here to the actual top-level class to determine
501 // the correct nesting.
503 // The genericLocation for the annotation.
504 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
506 Type topTy = enclTy;
507 while (enclEl != null &&
508 enclEl.getKind() != ElementKind.PACKAGE &&
509 topTy != null &&
510 topTy.getKind() != TypeKind.NONE &&
511 topTy.getKind() != TypeKind.ERROR) {
512 topTy = topTy.getEnclosingType();
513 enclEl = enclEl.getEnclosingElement();
515 if (topTy != null && topTy.getKind() != TypeKind.NONE) {
516 // Only count enclosing types.
517 depth = depth.append(TypePathEntry.INNER_TYPE);
518 }
519 }
521 if (depth.nonEmpty()) {
522 // Only need to change the annotation positions
523 // if they are on an enclosed type.
524 // All annotations share the same position; modify the first one.
525 Attribute.TypeCompound a = annotations.get(0);
526 TypeAnnotationPosition p = a.position;
527 p.location = p.location.appendList(depth.toList());
528 }
530 Type ret = typeWithAnnotations(type, enclTy, annotations);
531 typetree.type = ret;
532 return ret;
533 }
534 }
536 private JCArrayTypeTree arrayTypeTree(JCTree typetree) {
537 if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
538 return (JCArrayTypeTree) typetree;
539 } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
540 return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
541 } else {
542 Assert.error("Could not determine array type from type tree: " + typetree);
543 return null;
544 }
545 }
547 /** Return a copy of the first type that only differs by
548 * inserting the annotations to the left-most/inner-most type
549 * or the type given by stopAt.
550 *
551 * We need the stopAt parameter to know where on a type to
552 * put the annotations.
553 * If we have nested classes Outer > Middle > Inner, and we
554 * have the source type "@A Middle.Inner", we will invoke
555 * this method with type = Outer.Middle.Inner,
556 * stopAt = Middle.Inner, and annotations = @A.
557 *
558 * @param type The type to copy.
559 * @param stopAt The type to stop at.
560 * @param annotations The annotations to insert.
561 * @return A copy of type that contains the annotations.
562 */
563 private Type typeWithAnnotations(final Type type,
564 final Type stopAt,
565 final List<Attribute.TypeCompound> annotations) {
566 Visitor<Type, List<TypeCompound>> visitor =
567 new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
568 @Override
569 public Type visitClassType(ClassType t, List<TypeCompound> s) {
570 // assert that t.constValue() == null?
571 if (t == stopAt ||
572 t.getEnclosingType() == Type.noType) {
573 return t.annotatedType(s);
574 } else {
575 ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
576 t.typarams_field, t.tsym);
577 ret.all_interfaces_field = t.all_interfaces_field;
578 ret.allparams_field = t.allparams_field;
579 ret.interfaces_field = t.interfaces_field;
580 ret.rank_field = t.rank_field;
581 ret.supertype_field = t.supertype_field;
582 return ret;
583 }
584 }
586 @Override
587 public Type visitAnnotatedType(AnnotatedType t, List<TypeCompound> s) {
588 return t.unannotatedType().accept(this, s).annotatedType(t.getAnnotationMirrors());
589 }
591 @Override
592 public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
593 return t.annotatedType(s);
594 }
596 @Override
597 public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
598 ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym);
599 return ret;
600 }
602 @Override
603 public Type visitMethodType(MethodType t, List<TypeCompound> s) {
604 // Impossible?
605 return t;
606 }
608 @Override
609 public Type visitPackageType(PackageType t, List<TypeCompound> s) {
610 // Impossible?
611 return t;
612 }
614 @Override
615 public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
616 return t.annotatedType(s);
617 }
619 @Override
620 public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
621 return t.annotatedType(s);
622 }
624 @Override
625 public Type visitForAll(ForAll t, List<TypeCompound> s) {
626 // Impossible?
627 return t;
628 }
630 @Override
631 public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
632 // Impossible?
633 return t;
634 }
636 @Override
637 public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
638 return t.annotatedType(s);
639 }
641 @Override
642 public Type visitType(Type t, List<TypeCompound> s) {
643 return t.annotatedType(s);
644 }
645 };
647 return type.accept(visitor, annotations);
648 }
650 private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
651 // It is safe to alias the position.
652 return new Attribute.TypeCompound(a, p);
653 }
656 /* This is the beginning of the second part of organizing
657 * type annotations: determine the type annotation positions.
658 */
660 private void resolveFrame(JCTree tree, JCTree frame,
661 List<JCTree> path, TypeAnnotationPosition p) {
662 /*
663 System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
664 System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind());
665 */
667 // Note that p.offset is set in
668 // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
670 switch (frame.getKind()) {
671 case TYPE_CAST:
672 JCTypeCast frameTC = (JCTypeCast) frame;
673 p.type = TargetType.CAST;
674 if (frameTC.clazz.hasTag(Tag.TYPEINTERSECTION)) {
675 // This case was already handled by INTERSECTION_TYPE
676 } else {
677 p.type_index = 0;
678 }
679 p.pos = frame.pos;
680 return;
682 case INSTANCE_OF:
683 p.type = TargetType.INSTANCEOF;
684 p.pos = frame.pos;
685 return;
687 case NEW_CLASS:
688 JCNewClass frameNewClass = (JCNewClass) frame;
689 if (frameNewClass.def != null) {
690 // Special handling for anonymous class instantiations
691 JCClassDecl frameClassDecl = frameNewClass.def;
692 if (frameClassDecl.extending == tree) {
693 p.type = TargetType.CLASS_EXTENDS;
694 p.type_index = -1;
695 } else if (frameClassDecl.implementing.contains(tree)) {
696 p.type = TargetType.CLASS_EXTENDS;
697 p.type_index = frameClassDecl.implementing.indexOf(tree);
698 } else {
699 // In contrast to CLASS below, typarams cannot occur here.
700 Assert.error("Could not determine position of tree " + tree +
701 " within frame " + frame);
702 }
703 } else if (frameNewClass.typeargs.contains(tree)) {
704 p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
705 p.type_index = frameNewClass.typeargs.indexOf(tree);
706 } else {
707 p.type = TargetType.NEW;
708 }
709 p.pos = frame.pos;
710 return;
712 case NEW_ARRAY:
713 p.type = TargetType.NEW;
714 p.pos = frame.pos;
715 return;
717 case ANNOTATION_TYPE:
718 case CLASS:
719 case ENUM:
720 case INTERFACE:
721 p.pos = frame.pos;
722 if (((JCClassDecl)frame).extending == tree) {
723 p.type = TargetType.CLASS_EXTENDS;
724 p.type_index = -1;
725 } else if (((JCClassDecl)frame).implementing.contains(tree)) {
726 p.type = TargetType.CLASS_EXTENDS;
727 p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
728 } else if (((JCClassDecl)frame).typarams.contains(tree)) {
729 p.type = TargetType.CLASS_TYPE_PARAMETER;
730 p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
731 } else {
732 Assert.error("Could not determine position of tree " + tree +
733 " within frame " + frame);
734 }
735 return;
737 case METHOD: {
738 JCMethodDecl frameMethod = (JCMethodDecl) frame;
739 p.pos = frame.pos;
740 if (frameMethod.thrown.contains(tree)) {
741 p.type = TargetType.THROWS;
742 p.type_index = frameMethod.thrown.indexOf(tree);
743 } else if (frameMethod.restype == tree) {
744 p.type = TargetType.METHOD_RETURN;
745 } else if (frameMethod.typarams.contains(tree)) {
746 p.type = TargetType.METHOD_TYPE_PARAMETER;
747 p.parameter_index = frameMethod.typarams.indexOf(tree);
748 } else {
749 Assert.error("Could not determine position of tree " + tree +
750 " within frame " + frame);
751 }
752 return;
753 }
755 case PARAMETERIZED_TYPE: {
756 List<JCTree> newPath = path.tail;
758 if (((JCTypeApply)frame).clazz == tree) {
759 // generic: RAW; noop
760 } else if (((JCTypeApply)frame).arguments.contains(tree)) {
761 JCTypeApply taframe = (JCTypeApply) frame;
762 int arg = taframe.arguments.indexOf(tree);
763 p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
765 Type typeToUse;
766 if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
767 // If we are within an anonymous class instantiation, use its type,
768 // because it contains a correctly nested type.
769 typeToUse = newPath.tail.head.type;
770 } else {
771 typeToUse = taframe.type;
772 }
774 locateNestedTypes(typeToUse, p);
775 } else {
776 Assert.error("Could not determine type argument position of tree " + tree +
777 " within frame " + frame);
778 }
780 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
781 return;
782 }
784 case MEMBER_REFERENCE: {
785 JCMemberReference mrframe = (JCMemberReference) frame;
787 if (mrframe.expr == tree) {
788 switch (mrframe.mode) {
789 case INVOKE:
790 p.type = TargetType.METHOD_REFERENCE;
791 break;
792 case NEW:
793 p.type = TargetType.CONSTRUCTOR_REFERENCE;
794 break;
795 default:
796 Assert.error("Unknown method reference mode " + mrframe.mode +
797 " for tree " + tree + " within frame " + frame);
798 }
799 p.pos = frame.pos;
800 } else if (mrframe.typeargs != null &&
801 mrframe.typeargs.contains(tree)) {
802 int arg = mrframe.typeargs.indexOf(tree);
803 p.type_index = arg;
804 switch (mrframe.mode) {
805 case INVOKE:
806 p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
807 break;
808 case NEW:
809 p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
810 break;
811 default:
812 Assert.error("Unknown method reference mode " + mrframe.mode +
813 " for tree " + tree + " within frame " + frame);
814 }
815 p.pos = frame.pos;
816 } else {
817 Assert.error("Could not determine type argument position of tree " + tree +
818 " within frame " + frame);
819 }
820 return;
821 }
823 case ARRAY_TYPE: {
824 ListBuffer<TypePathEntry> index = new ListBuffer<>();
825 index = index.append(TypePathEntry.ARRAY);
826 List<JCTree> newPath = path.tail;
827 while (true) {
828 JCTree npHead = newPath.tail.head;
829 if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
830 newPath = newPath.tail;
831 index = index.append(TypePathEntry.ARRAY);
832 } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
833 newPath = newPath.tail;
834 } else {
835 break;
836 }
837 }
838 p.location = p.location.prependList(index.toList());
839 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
840 return;
841 }
843 case TYPE_PARAMETER:
844 if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
845 JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
846 p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
847 p.parameter_index = clazz.typarams.indexOf(path.tail.head);
848 p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
849 if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
850 // Account for an implicit Object as bound 0
851 p.bound_index += 1;
852 }
853 } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
854 JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
855 p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
856 p.parameter_index = method.typarams.indexOf(path.tail.head);
857 p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
858 if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
859 // Account for an implicit Object as bound 0
860 p.bound_index += 1;
861 }
862 } else {
863 Assert.error("Could not determine position of tree " + tree +
864 " within frame " + frame);
865 }
866 p.pos = frame.pos;
867 return;
869 case VARIABLE:
870 VarSymbol v = ((JCVariableDecl)frame).sym;
871 p.pos = frame.pos;
872 switch (v.getKind()) {
873 case LOCAL_VARIABLE:
874 p.type = TargetType.LOCAL_VARIABLE;
875 break;
876 case FIELD:
877 p.type = TargetType.FIELD;
878 break;
879 case PARAMETER:
880 if (v.getQualifiedName().equals(names._this)) {
881 // TODO: Intro a separate ElementKind?
882 p.type = TargetType.METHOD_RECEIVER;
883 } else {
884 p.type = TargetType.METHOD_FORMAL_PARAMETER;
885 p.parameter_index = methodParamIndex(path, frame);
886 }
887 break;
888 case EXCEPTION_PARAMETER:
889 p.type = TargetType.EXCEPTION_PARAMETER;
890 break;
891 case RESOURCE_VARIABLE:
892 p.type = TargetType.RESOURCE_VARIABLE;
893 break;
894 default:
895 Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
896 }
897 if (v.getKind() != ElementKind.FIELD) {
898 v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes());
899 }
900 return;
902 case ANNOTATED_TYPE: {
903 if (frame == tree) {
904 // This is only true for the first annotated type we see.
905 // For any other annotated types along the path, we do
906 // not care about inner types.
907 JCAnnotatedType atypetree = (JCAnnotatedType) frame;
908 final Type utype = atypetree.underlyingType.type;
909 if (utype == null) {
910 // This might happen during DeferredAttr;
911 // we will be back later.
912 return;
913 }
914 Symbol tsym = utype.tsym;
915 if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
916 utype.getKind().equals(TypeKind.WILDCARD) ||
917 utype.getKind().equals(TypeKind.ARRAY)) {
918 // Type parameters, wildcards, and arrays have the declaring
919 // class/method as enclosing elements.
920 // There is actually nothing to do for them.
921 } else {
922 locateNestedTypes(utype, p);
923 }
924 }
925 List<JCTree> newPath = path.tail;
926 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
927 return;
928 }
930 case UNION_TYPE: {
931 List<JCTree> newPath = path.tail;
932 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
933 return;
934 }
936 case INTERSECTION_TYPE: {
937 JCTypeIntersection isect = (JCTypeIntersection)frame;
938 p.type_index = isect.bounds.indexOf(tree);
939 List<JCTree> newPath = path.tail;
940 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
941 return;
942 }
944 case METHOD_INVOCATION: {
945 JCMethodInvocation invocation = (JCMethodInvocation)frame;
946 if (!invocation.typeargs.contains(tree)) {
947 Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
948 }
949 MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect());
950 if (exsym == null) {
951 Assert.error("could not determine symbol for {" + invocation + "}");
952 } else if (exsym.isConstructor()) {
953 p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
954 } else {
955 p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
956 }
957 p.pos = invocation.pos;
958 p.type_index = invocation.typeargs.indexOf(tree);
959 return;
960 }
962 case EXTENDS_WILDCARD:
963 case SUPER_WILDCARD: {
964 // Annotations in wildcard bounds
965 p.location = p.location.prepend(TypePathEntry.WILDCARD);
966 List<JCTree> newPath = path.tail;
967 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
968 return;
969 }
971 case MEMBER_SELECT: {
972 List<JCTree> newPath = path.tail;
973 resolveFrame(newPath.head, newPath.tail.head, newPath, p);
974 return;
975 }
977 default:
978 Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() +
979 "\n Looking for tree: " + tree);
980 return;
981 }
982 }
984 private void locateNestedTypes(Type type, TypeAnnotationPosition p) {
985 // The number of "steps" to get from the full type to the
986 // left-most outer type.
987 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
989 Type encl = type.getEnclosingType();
990 while (encl != null &&
991 encl.getKind() != TypeKind.NONE &&
992 encl.getKind() != TypeKind.ERROR) {
993 depth = depth.append(TypePathEntry.INNER_TYPE);
994 encl = encl.getEnclosingType();
995 }
996 if (depth.nonEmpty()) {
997 p.location = p.location.prependList(depth.toList());
998 }
999 }
1001 private int methodParamIndex(List<JCTree> path, JCTree param) {
1002 List<JCTree> curr = path;
1003 while (curr.head.getTag() != Tag.METHODDEF &&
1004 curr.head.getTag() != Tag.LAMBDA) {
1005 curr = curr.tail;
1006 }
1007 if (curr.head.getTag() == Tag.METHODDEF) {
1008 JCMethodDecl method = (JCMethodDecl)curr.head;
1009 return method.params.indexOf(param);
1010 } else if (curr.head.getTag() == Tag.LAMBDA) {
1011 JCLambda lambda = (JCLambda)curr.head;
1012 return lambda.params.indexOf(param);
1013 } else {
1014 Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
1015 return -1;
1016 }
1017 }
1019 // Each class (including enclosed inner classes) is visited separately.
1020 // This flag is used to prevent from visiting inner classes.
1021 private boolean isInClass = false;
1023 @Override
1024 public void visitClassDef(JCClassDecl tree) {
1025 if (isInClass)
1026 return;
1027 isInClass = true;
1029 if (sigOnly) {
1030 scan(tree.mods);
1031 scan(tree.typarams);
1032 scan(tree.extending);
1033 scan(tree.implementing);
1034 }
1035 scan(tree.defs);
1036 }
1038 /**
1039 * Resolve declaration vs. type annotations in methods and
1040 * then determine the positions.
1041 */
1042 @Override
1043 public void visitMethodDef(final JCMethodDecl tree) {
1044 if (tree.sym == null) {
1045 if (typeAnnoAsserts) {
1046 Assert.error("Visiting tree node before memberEnter");
1047 } else {
1048 return;
1049 }
1050 }
1051 if (sigOnly) {
1052 if (!tree.mods.annotations.isEmpty()) {
1053 // Nothing to do for separateAnnotationsKinds if
1054 // there are no annotations of either kind.
1055 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1056 pos.type = TargetType.METHOD_RETURN;
1057 if (tree.sym.isConstructor()) {
1058 pos.pos = tree.pos;
1059 // Use null to mark that the annotations go with the symbol.
1060 separateAnnotationsKinds(tree, null, tree.sym, pos);
1061 } else {
1062 pos.pos = tree.restype.pos;
1063 separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(),
1064 tree.sym, pos);
1065 }
1066 }
1067 if (tree.recvparam != null && tree.recvparam.sym != null &&
1068 !tree.recvparam.mods.annotations.isEmpty()) {
1069 // Nothing to do for separateAnnotationsKinds if
1070 // there are no annotations of either kind.
1071 // TODO: make sure there are no declaration annotations.
1072 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1073 pos.type = TargetType.METHOD_RECEIVER;
1074 pos.pos = tree.recvparam.vartype.pos;
1075 separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type,
1076 tree.recvparam.sym, pos);
1077 }
1078 int i = 0;
1079 for (JCVariableDecl param : tree.params) {
1080 if (!param.mods.annotations.isEmpty()) {
1081 // Nothing to do for separateAnnotationsKinds if
1082 // there are no annotations of either kind.
1083 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1084 pos.type = TargetType.METHOD_FORMAL_PARAMETER;
1085 pos.parameter_index = i;
1086 pos.pos = param.vartype.pos;
1087 separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
1088 }
1089 ++i;
1090 }
1091 }
1093 push(tree);
1094 // super.visitMethodDef(tree);
1095 if (sigOnly) {
1096 scan(tree.mods);
1097 scan(tree.restype);
1098 scan(tree.typarams);
1099 scan(tree.recvparam);
1100 scan(tree.params);
1101 scan(tree.thrown);
1102 } else {
1103 scan(tree.defaultValue);
1104 scan(tree.body);
1105 }
1106 pop();
1107 }
1109 /* Store a reference to the current lambda expression, to
1110 * be used by all type annotations within this expression.
1111 */
1112 private JCLambda currentLambda = null;
1114 public void visitLambda(JCLambda tree) {
1115 JCLambda prevLambda = currentLambda;
1116 try {
1117 currentLambda = tree;
1119 int i = 0;
1120 for (JCVariableDecl param : tree.params) {
1121 if (!param.mods.annotations.isEmpty()) {
1122 // Nothing to do for separateAnnotationsKinds if
1123 // there are no annotations of either kind.
1124 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1125 pos.type = TargetType.METHOD_FORMAL_PARAMETER;
1126 pos.parameter_index = i;
1127 pos.pos = param.vartype.pos;
1128 pos.onLambda = tree;
1129 separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
1130 }
1131 ++i;
1132 }
1134 push(tree);
1135 scan(tree.body);
1136 scan(tree.params);
1137 pop();
1138 } finally {
1139 currentLambda = prevLambda;
1140 }
1141 }
1143 /**
1144 * Resolve declaration vs. type annotations in variable declarations and
1145 * then determine the positions.
1146 */
1147 @Override
1148 public void visitVarDef(final JCVariableDecl tree) {
1149 if (tree.mods.annotations.isEmpty()) {
1150 // Nothing to do for separateAnnotationsKinds if
1151 // there are no annotations of either kind.
1152 } else if (tree.sym == null) {
1153 if (typeAnnoAsserts) {
1154 Assert.error("Visiting tree node before memberEnter");
1155 }
1156 // Something is wrong already. Quietly ignore.
1157 } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
1158 // Parameters are handled in visitMethodDef or visitLambda.
1159 } else if (tree.sym.getKind() == ElementKind.FIELD) {
1160 if (sigOnly) {
1161 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1162 pos.type = TargetType.FIELD;
1163 pos.pos = tree.pos;
1164 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1165 }
1166 } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
1167 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1168 pos.type = TargetType.LOCAL_VARIABLE;
1169 pos.pos = tree.pos;
1170 pos.onLambda = currentLambda;
1171 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1172 } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
1173 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1174 pos.type = TargetType.EXCEPTION_PARAMETER;
1175 pos.pos = tree.pos;
1176 pos.onLambda = currentLambda;
1177 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1178 } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
1179 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1180 pos.type = TargetType.RESOURCE_VARIABLE;
1181 pos.pos = tree.pos;
1182 pos.onLambda = currentLambda;
1183 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
1184 } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
1185 // No type annotations can occur here.
1186 } else {
1187 // There is nothing else in a variable declaration that needs separation.
1188 Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
1189 }
1191 push(tree);
1192 // super.visitVarDef(tree);
1193 scan(tree.mods);
1194 scan(tree.vartype);
1195 if (!sigOnly) {
1196 scan(tree.init);
1197 }
1198 pop();
1199 }
1201 @Override
1202 public void visitBlock(JCBlock tree) {
1203 // Do not descend into top-level blocks when only interested
1204 // in the signature.
1205 if (!sigOnly) {
1206 scan(tree.stats);
1207 }
1208 }
1210 @Override
1211 public void visitAnnotatedType(JCAnnotatedType tree) {
1212 push(tree);
1213 findPosition(tree, tree, tree.annotations);
1214 pop();
1215 super.visitAnnotatedType(tree);
1216 }
1218 @Override
1219 public void visitTypeParameter(JCTypeParameter tree) {
1220 findPosition(tree, peek2(), tree.annotations);
1221 super.visitTypeParameter(tree);
1222 }
1224 @Override
1225 public void visitNewClass(JCNewClass tree) {
1226 if (tree.def != null &&
1227 !tree.def.mods.annotations.isEmpty()) {
1228 JCClassDecl classdecl = tree.def;
1229 TypeAnnotationPosition pos = new TypeAnnotationPosition();
1230 pos.type = TargetType.CLASS_EXTENDS;
1231 pos.pos = tree.pos;
1232 if (classdecl.extending == tree.clazz) {
1233 pos.type_index = -1;
1234 } else if (classdecl.implementing.contains(tree.clazz)) {
1235 pos.type_index = classdecl.implementing.indexOf(tree.clazz);
1236 } else {
1237 // In contrast to CLASS elsewhere, typarams cannot occur here.
1238 Assert.error("Could not determine position of tree " + tree);
1239 }
1240 Type before = classdecl.sym.type;
1241 separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
1243 // classdecl.sym.type now contains an annotated type, which
1244 // is not what we want there.
1245 // TODO: should we put this type somewhere in the superclass/interface?
1246 classdecl.sym.type = before;
1247 }
1249 scan(tree.encl);
1250 scan(tree.typeargs);
1251 scan(tree.clazz);
1252 scan(tree.args);
1254 // The class body will already be scanned.
1255 // scan(tree.def);
1256 }
1258 @Override
1259 public void visitNewArray(JCNewArray tree) {
1260 findPosition(tree, tree, tree.annotations);
1261 int dimAnnosCount = tree.dimAnnotations.size();
1262 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
1264 // handle annotations associated with dimensions
1265 for (int i = 0; i < dimAnnosCount; ++i) {
1266 TypeAnnotationPosition p = new TypeAnnotationPosition();
1267 p.pos = tree.pos;
1268 p.onLambda = currentLambda;
1269 p.type = TargetType.NEW;
1270 if (i != 0) {
1271 depth = depth.append(TypePathEntry.ARRAY);
1272 p.location = p.location.appendList(depth.toList());
1273 }
1275 setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
1276 }
1278 // handle "free" annotations
1279 // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
1280 // TODO: is depth.size == i here?
1281 JCExpression elemType = tree.elemtype;
1282 depth = depth.append(TypePathEntry.ARRAY);
1283 while (elemType != null) {
1284 if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
1285 JCAnnotatedType at = (JCAnnotatedType)elemType;
1286 TypeAnnotationPosition p = new TypeAnnotationPosition();
1287 p.type = TargetType.NEW;
1288 p.pos = tree.pos;
1289 p.onLambda = currentLambda;
1290 locateNestedTypes(elemType.type, p);
1291 p.location = p.location.prependList(depth.toList());
1292 setTypeAnnotationPos(at.annotations, p);
1293 elemType = at.underlyingType;
1294 } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
1295 depth = depth.append(TypePathEntry.ARRAY);
1296 elemType = ((JCArrayTypeTree)elemType).elemtype;
1297 } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
1298 elemType = ((JCFieldAccess)elemType).selected;
1299 } else {
1300 break;
1301 }
1302 }
1303 scan(tree.elems);
1304 }
1306 private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) {
1307 if (!annotations.isEmpty()) {
1308 /*
1309 System.err.println("Finding pos for: " + annotations);
1310 System.err.println(" tree: " + tree + " kind: " + tree.getKind());
1311 System.err.println(" frame: " + frame + " kind: " + frame.getKind());
1312 */
1313 TypeAnnotationPosition p = new TypeAnnotationPosition();
1314 p.onLambda = currentLambda;
1315 resolveFrame(tree, frame, frames.toList(), p);
1316 setTypeAnnotationPos(annotations, p);
1317 }
1318 }
1320 private void setTypeAnnotationPos(List<JCAnnotation> annotations,
1321 TypeAnnotationPosition position) {
1322 for (JCAnnotation anno : annotations) {
1323 // attribute might be null during DeferredAttr;
1324 // we will be back later.
1325 if (anno.attribute != null) {
1326 ((Attribute.TypeCompound) anno.attribute).position = position;
1327 }
1328 }
1329 }
1331 @Override
1332 public String toString() {
1333 return super.toString() + ": sigOnly: " + sigOnly;
1334 }
1335 }
1336 }