--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jan 23 20:57:40 2013 +0000
+++ b/langtools/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;
+ }
}