diff -r 5c956be64b9e -r 71f35e4b93a5 src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 20:57:40 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 13:27:24 2013 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -453,6 +453,19 @@ case POSTINC: case POSTDEC: return getStartPos(((JCUnary) tree).arg); + case ANNOTATED_TYPE: { + JCAnnotatedType node = (JCAnnotatedType) tree; + if (node.annotations.nonEmpty()) { + if (node.underlyingType.hasTag(TYPEARRAY) || + node.underlyingType.hasTag(SELECT)) { + return getStartPos(node.underlyingType); + } else { + return getStartPos(node.annotations.head); + } + } else { + return getStartPos(node.underlyingType); + } + } case NEWCLASS: { JCNewClass node = (JCNewClass)tree; if (node.encl != null) @@ -560,6 +573,8 @@ return getEndPos(((JCUnary) tree).arg, endPosTable); case WHILELOOP: return getEndPos(((JCWhileLoop) tree).body, endPosTable); + case ANNOTATED_TYPE: + return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) @@ -799,6 +814,8 @@ return ((JCFieldAccess) tree).sym; case TYPEAPPLY: return symbol(((JCTypeApply) tree).clazz); + case ANNOTATED_TYPE: + return symbol(((JCAnnotatedType) tree).underlyingType); default: return null; } @@ -1036,17 +1053,24 @@ case NULLCHK: return Tree.Kind.OTHER; + case ANNOTATION: + return Tree.Kind.ANNOTATION; + case TYPE_ANNOTATION: + return Tree.Kind.TYPE_ANNOTATION; + default: return null; } } /** - * Returns the underlying type of the tree if it is annotated type, - * or the tree itself otherwise + * Returns the underlying type of the tree if it is an annotated type, + * or the tree itself otherwise. */ public static JCExpression typeIn(JCExpression tree) { switch (tree.getTag()) { + case ANNOTATED_TYPE: + return ((JCAnnotatedType)tree).underlyingType; case IDENT: /* simple names */ case TYPEIDENT: /* primitive name */ case SELECT: /* qualified name */ @@ -1054,20 +1078,55 @@ case WILDCARD: /* wild cards */ case TYPEPARAMETER: /* type parameters */ case TYPEAPPLY: /* parameterized types */ + case ERRONEOUS: /* error tree TODO: needed for BadCast JSR308 test case. Better way? */ return tree; default: throw new AssertionError("Unexpected type tree: " + tree); } } + /* Return the inner-most type of a type tree. + * For an array that contains an annotated type, return that annotated type. + * TODO: currently only used by Pretty. Describe behavior better. + */ public static JCTree innermostType(JCTree type) { - switch (type.getTag()) { - case TYPEARRAY: - return innermostType(((JCArrayTypeTree)type).elemtype); - case WILDCARD: - return innermostType(((JCWildcard)type).inner); - default: - return type; + JCTree lastAnnotatedType = null; + JCTree cur = type; + loop: while (true) { + switch (cur.getTag()) { + case TYPEARRAY: + lastAnnotatedType = null; + cur = ((JCArrayTypeTree)cur).elemtype; + break; + case WILDCARD: + lastAnnotatedType = null; + cur = ((JCWildcard)cur).inner; + break; + case ANNOTATED_TYPE: + lastAnnotatedType = cur; + cur = ((JCAnnotatedType)cur).underlyingType; + break; + default: + break loop; + } + } + if (lastAnnotatedType!=null) { + return lastAnnotatedType; + } else { + return cur; } } + + private static class TypeAnnotationFinder extends TreeScanner { + public boolean foundTypeAnno = false; + public void visitAnnotation(JCAnnotation tree) { + foundTypeAnno = foundTypeAnno || tree.hasTag(TYPE_ANNOTATION); + } + } + + public static boolean containsTypeAnnotation(JCTree e) { + TypeAnnotationFinder finder = new TypeAnnotationFinder(); + finder.scan(e); + return finder.foundTypeAnno; + } }