1.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 20:57:40 2013 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 13:27:24 2013 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -453,6 +453,19 @@ 1.11 case POSTINC: 1.12 case POSTDEC: 1.13 return getStartPos(((JCUnary) tree).arg); 1.14 + case ANNOTATED_TYPE: { 1.15 + JCAnnotatedType node = (JCAnnotatedType) tree; 1.16 + if (node.annotations.nonEmpty()) { 1.17 + if (node.underlyingType.hasTag(TYPEARRAY) || 1.18 + node.underlyingType.hasTag(SELECT)) { 1.19 + return getStartPos(node.underlyingType); 1.20 + } else { 1.21 + return getStartPos(node.annotations.head); 1.22 + } 1.23 + } else { 1.24 + return getStartPos(node.underlyingType); 1.25 + } 1.26 + } 1.27 case NEWCLASS: { 1.28 JCNewClass node = (JCNewClass)tree; 1.29 if (node.encl != null) 1.30 @@ -560,6 +573,8 @@ 1.31 return getEndPos(((JCUnary) tree).arg, endPosTable); 1.32 case WHILELOOP: 1.33 return getEndPos(((JCWhileLoop) tree).body, endPosTable); 1.34 + case ANNOTATED_TYPE: 1.35 + return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); 1.36 case ERRONEOUS: { 1.37 JCErroneous node = (JCErroneous)tree; 1.38 if (node.errs != null && node.errs.nonEmpty()) 1.39 @@ -799,6 +814,8 @@ 1.40 return ((JCFieldAccess) tree).sym; 1.41 case TYPEAPPLY: 1.42 return symbol(((JCTypeApply) tree).clazz); 1.43 + case ANNOTATED_TYPE: 1.44 + return symbol(((JCAnnotatedType) tree).underlyingType); 1.45 default: 1.46 return null; 1.47 } 1.48 @@ -1036,17 +1053,24 @@ 1.49 case NULLCHK: 1.50 return Tree.Kind.OTHER; 1.51 1.52 + case ANNOTATION: 1.53 + return Tree.Kind.ANNOTATION; 1.54 + case TYPE_ANNOTATION: 1.55 + return Tree.Kind.TYPE_ANNOTATION; 1.56 + 1.57 default: 1.58 return null; 1.59 } 1.60 } 1.61 1.62 /** 1.63 - * Returns the underlying type of the tree if it is annotated type, 1.64 - * or the tree itself otherwise 1.65 + * Returns the underlying type of the tree if it is an annotated type, 1.66 + * or the tree itself otherwise. 1.67 */ 1.68 public static JCExpression typeIn(JCExpression tree) { 1.69 switch (tree.getTag()) { 1.70 + case ANNOTATED_TYPE: 1.71 + return ((JCAnnotatedType)tree).underlyingType; 1.72 case IDENT: /* simple names */ 1.73 case TYPEIDENT: /* primitive name */ 1.74 case SELECT: /* qualified name */ 1.75 @@ -1054,20 +1078,55 @@ 1.76 case WILDCARD: /* wild cards */ 1.77 case TYPEPARAMETER: /* type parameters */ 1.78 case TYPEAPPLY: /* parameterized types */ 1.79 + case ERRONEOUS: /* error tree TODO: needed for BadCast JSR308 test case. Better way? */ 1.80 return tree; 1.81 default: 1.82 throw new AssertionError("Unexpected type tree: " + tree); 1.83 } 1.84 } 1.85 1.86 + /* Return the inner-most type of a type tree. 1.87 + * For an array that contains an annotated type, return that annotated type. 1.88 + * TODO: currently only used by Pretty. Describe behavior better. 1.89 + */ 1.90 public static JCTree innermostType(JCTree type) { 1.91 - switch (type.getTag()) { 1.92 - case TYPEARRAY: 1.93 - return innermostType(((JCArrayTypeTree)type).elemtype); 1.94 - case WILDCARD: 1.95 - return innermostType(((JCWildcard)type).inner); 1.96 - default: 1.97 - return type; 1.98 + JCTree lastAnnotatedType = null; 1.99 + JCTree cur = type; 1.100 + loop: while (true) { 1.101 + switch (cur.getTag()) { 1.102 + case TYPEARRAY: 1.103 + lastAnnotatedType = null; 1.104 + cur = ((JCArrayTypeTree)cur).elemtype; 1.105 + break; 1.106 + case WILDCARD: 1.107 + lastAnnotatedType = null; 1.108 + cur = ((JCWildcard)cur).inner; 1.109 + break; 1.110 + case ANNOTATED_TYPE: 1.111 + lastAnnotatedType = cur; 1.112 + cur = ((JCAnnotatedType)cur).underlyingType; 1.113 + break; 1.114 + default: 1.115 + break loop; 1.116 + } 1.117 + } 1.118 + if (lastAnnotatedType!=null) { 1.119 + return lastAnnotatedType; 1.120 + } else { 1.121 + return cur; 1.122 } 1.123 } 1.124 + 1.125 + private static class TypeAnnotationFinder extends TreeScanner { 1.126 + public boolean foundTypeAnno = false; 1.127 + public void visitAnnotation(JCAnnotation tree) { 1.128 + foundTypeAnno = foundTypeAnno || tree.hasTag(TYPE_ANNOTATION); 1.129 + } 1.130 + } 1.131 + 1.132 + public static boolean containsTypeAnnotation(JCTree e) { 1.133 + TypeAnnotationFinder finder = new TypeAnnotationFinder(); 1.134 + finder.scan(e); 1.135 + return finder.foundTypeAnno; 1.136 + } 1.137 }