src/share/classes/com/sun/tools/javac/comp/Annotate.java

Print this page




  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  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import com.sun.tools.javac.util.*;
  29 import com.sun.tools.javac.code.*;
  30 import com.sun.tools.javac.code.Symbol.*;
  31 import com.sun.tools.javac.tree.*;
  32 import com.sun.tools.javac.tree.JCTree.*;
  33 


  34 /** Enter annotations on symbols.  Annotations accumulate in a queue,
  35  *  which is processed at the top level of any set of recursive calls
  36  *  requesting it be processed.
  37  *
  38  *  <p><b>This is NOT part of any supported API.
  39  *  If you write code that depends on this, you do so at your own risk.
  40  *  This code and its internal interfaces are subject to change or
  41  *  deletion without notice.</b>
  42  */
  43 public class Annotate {
  44     protected static final Context.Key<Annotate> annotateKey =
  45         new Context.Key<Annotate>();
  46 
  47     public static Annotate instance(Context context) {
  48         Annotate instance = context.get(annotateKey);
  49         if (instance == null)
  50             instance = new Annotate(context);
  51         return instance;
  52     }
  53 


 131      *  Attribute. Used from MemberEnter for attaching the attributes
 132      *  to the annotated symbol.
 133      */
 134     Attribute.Compound enterAnnotation(JCAnnotation a,
 135                                        Type expected,
 136                                        Env<AttrContext> env) {
 137         // The annotation might have had its type attributed (but not checked)
 138         // by attr.attribAnnotationTypes during MemberEnter, in which case we do not
 139         // need to do it again.
 140         Type at = (a.annotationType.type != null ? a.annotationType.type
 141                   : attr.attribType(a.annotationType, env));
 142         a.type = chk.checkType(a.annotationType.pos(), at, expected);
 143         if (a.type.isErroneous())
 144             return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
 145         if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
 146             log.error(a.annotationType.pos(),
 147                       "not.annotation.type", a.type.toString());
 148             return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
 149         }
 150         List<JCExpression> args = a.args;
 151         if (args.length() == 1 && args.head.getTag() != JCTree.ASSIGN) {
 152             // special case: elided "value=" assumed
 153             args.head = make.at(args.head.pos).
 154                 Assign(make.Ident(names.value), args.head);
 155         }
 156         ListBuffer<Pair<MethodSymbol,Attribute>> buf =
 157             new ListBuffer<Pair<MethodSymbol,Attribute>>();
 158         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
 159             JCExpression t = tl.head;
 160             if (t.getTag() != JCTree.ASSIGN) {
 161                 log.error(t.pos(), "annotation.value.must.be.name.value");
 162                 continue;
 163             }
 164             JCAssign assign = (JCAssign)t;
 165             if (assign.lhs.getTag() != JCTree.IDENT) {
 166                 log.error(t.pos(), "annotation.value.must.be.name.value");
 167                 continue;
 168             }
 169             JCIdent left = (JCIdent)assign.lhs;
 170             Symbol method = rs.resolveQualifiedMethod(left.pos(),
 171                                                           env,
 172                                                           a.type,
 173                                                           left.name,
 174                                                           List.<Type>nil(),
 175                                                           null);
 176             left.sym = method;
 177             left.type = method.type;
 178             if (method.owner != a.type.tsym)
 179                 log.error(left.pos(), "no.annotation.member", left.name, a.type);
 180             Type result = method.type.getReturnType();
 181             Attribute value = enterAttributeValue(result, assign.rhs, env);
 182             if (!method.type.isErroneous())
 183                 buf.append(new Pair<MethodSymbol,Attribute>
 184                            ((MethodSymbol)method, value));
 185             t.type = result;


 205                 return new Attribute.Error(expected);
 206             if (result.constValue() == null) {
 207                 log.error(tree.pos(), "attribute.value.must.be.constant");
 208                 return new Attribute.Error(expected);
 209             }
 210             result = cfolder.coerce(result, expected);
 211             return new Attribute.Constant(expected, result.constValue());
 212         }
 213         if (expected.tsym == syms.classType.tsym) {
 214             Type result = attr.attribExpr(tree, env, expected);
 215             if (result.isErroneous())
 216                 return new Attribute.Error(expected);
 217             if (TreeInfo.name(tree) != names._class) {
 218                 log.error(tree.pos(), "annotation.value.must.be.class.literal");
 219                 return new Attribute.Error(expected);
 220             }
 221             return new Attribute.Class(types,
 222                                        (((JCFieldAccess) tree).selected).type);
 223         }
 224         if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
 225             if (tree.getTag() != JCTree.ANNOTATION) {
 226                 log.error(tree.pos(), "annotation.value.must.be.annotation");
 227                 expected = syms.errorType;
 228             }
 229             return enterAnnotation((JCAnnotation)tree, expected, env);
 230         }
 231         if (expected.tag == TypeTags.ARRAY) { // should really be isArray()
 232             if (tree.getTag() != JCTree.NEWARRAY) {
 233                 tree = make.at(tree.pos).
 234                     NewArray(null, List.<JCExpression>nil(), List.of(tree));
 235             }
 236             JCNewArray na = (JCNewArray)tree;
 237             if (na.elemtype != null) {
 238                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 239                 return new Attribute.Error(expected);
 240             }
 241             ListBuffer<Attribute> buf = new ListBuffer<Attribute>();
 242             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 243                 buf.append(enterAttributeValue(types.elemtype(expected),
 244                                                l.head,
 245                                                env));
 246             }
 247             na.type = expected;
 248             return new Attribute.
 249                 Array(expected, buf.toArray(new Attribute[buf.length()]));
 250         }
 251         if (expected.tag == TypeTags.CLASS &&
 252             (expected.tsym.flags() & Flags.ENUM) != 0) {


  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  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import com.sun.tools.javac.util.*;
  29 import com.sun.tools.javac.code.*;
  30 import com.sun.tools.javac.code.Symbol.*;
  31 import com.sun.tools.javac.tree.*;
  32 import com.sun.tools.javac.tree.JCTree.*;
  33 
  34 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  35 
  36 /** Enter annotations on symbols.  Annotations accumulate in a queue,
  37  *  which is processed at the top level of any set of recursive calls
  38  *  requesting it be processed.
  39  *
  40  *  <p><b>This is NOT part of any supported API.
  41  *  If you write code that depends on this, you do so at your own risk.
  42  *  This code and its internal interfaces are subject to change or
  43  *  deletion without notice.</b>
  44  */
  45 public class Annotate {
  46     protected static final Context.Key<Annotate> annotateKey =
  47         new Context.Key<Annotate>();
  48 
  49     public static Annotate instance(Context context) {
  50         Annotate instance = context.get(annotateKey);
  51         if (instance == null)
  52             instance = new Annotate(context);
  53         return instance;
  54     }
  55 


 133      *  Attribute. Used from MemberEnter for attaching the attributes
 134      *  to the annotated symbol.
 135      */
 136     Attribute.Compound enterAnnotation(JCAnnotation a,
 137                                        Type expected,
 138                                        Env<AttrContext> env) {
 139         // The annotation might have had its type attributed (but not checked)
 140         // by attr.attribAnnotationTypes during MemberEnter, in which case we do not
 141         // need to do it again.
 142         Type at = (a.annotationType.type != null ? a.annotationType.type
 143                   : attr.attribType(a.annotationType, env));
 144         a.type = chk.checkType(a.annotationType.pos(), at, expected);
 145         if (a.type.isErroneous())
 146             return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
 147         if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
 148             log.error(a.annotationType.pos(),
 149                       "not.annotation.type", a.type.toString());
 150             return new Attribute.Compound(a.type, List.<Pair<MethodSymbol,Attribute>>nil());
 151         }
 152         List<JCExpression> args = a.args;
 153         if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
 154             // special case: elided "value=" assumed
 155             args.head = make.at(args.head.pos).
 156                 Assign(make.Ident(names.value), args.head);
 157         }
 158         ListBuffer<Pair<MethodSymbol,Attribute>> buf =
 159             new ListBuffer<Pair<MethodSymbol,Attribute>>();
 160         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
 161             JCExpression t = tl.head;
 162             if (!t.hasTag(ASSIGN)) {
 163                 log.error(t.pos(), "annotation.value.must.be.name.value");
 164                 continue;
 165             }
 166             JCAssign assign = (JCAssign)t;
 167             if (!assign.lhs.hasTag(IDENT)) {
 168                 log.error(t.pos(), "annotation.value.must.be.name.value");
 169                 continue;
 170             }
 171             JCIdent left = (JCIdent)assign.lhs;
 172             Symbol method = rs.resolveQualifiedMethod(left.pos(),
 173                                                           env,
 174                                                           a.type,
 175                                                           left.name,
 176                                                           List.<Type>nil(),
 177                                                           null);
 178             left.sym = method;
 179             left.type = method.type;
 180             if (method.owner != a.type.tsym)
 181                 log.error(left.pos(), "no.annotation.member", left.name, a.type);
 182             Type result = method.type.getReturnType();
 183             Attribute value = enterAttributeValue(result, assign.rhs, env);
 184             if (!method.type.isErroneous())
 185                 buf.append(new Pair<MethodSymbol,Attribute>
 186                            ((MethodSymbol)method, value));
 187             t.type = result;


 207                 return new Attribute.Error(expected);
 208             if (result.constValue() == null) {
 209                 log.error(tree.pos(), "attribute.value.must.be.constant");
 210                 return new Attribute.Error(expected);
 211             }
 212             result = cfolder.coerce(result, expected);
 213             return new Attribute.Constant(expected, result.constValue());
 214         }
 215         if (expected.tsym == syms.classType.tsym) {
 216             Type result = attr.attribExpr(tree, env, expected);
 217             if (result.isErroneous())
 218                 return new Attribute.Error(expected);
 219             if (TreeInfo.name(tree) != names._class) {
 220                 log.error(tree.pos(), "annotation.value.must.be.class.literal");
 221                 return new Attribute.Error(expected);
 222             }
 223             return new Attribute.Class(types,
 224                                        (((JCFieldAccess) tree).selected).type);
 225         }
 226         if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
 227             if (!tree.hasTag(ANNOTATION)) {
 228                 log.error(tree.pos(), "annotation.value.must.be.annotation");
 229                 expected = syms.errorType;
 230             }
 231             return enterAnnotation((JCAnnotation)tree, expected, env);
 232         }
 233         if (expected.tag == TypeTags.ARRAY) { // should really be isArray()
 234             if (!tree.hasTag(NEWARRAY)) {
 235                 tree = make.at(tree.pos).
 236                     NewArray(null, List.<JCExpression>nil(), List.of(tree));
 237             }
 238             JCNewArray na = (JCNewArray)tree;
 239             if (na.elemtype != null) {
 240                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 241                 return new Attribute.Error(expected);
 242             }
 243             ListBuffer<Attribute> buf = new ListBuffer<Attribute>();
 244             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 245                 buf.append(enterAttributeValue(types.elemtype(expected),
 246                                                l.head,
 247                                                env));
 248             }
 249             na.type = expected;
 250             return new Attribute.
 251                 Array(expected, buf.toArray(new Attribute[buf.length()]));
 252         }
 253         if (expected.tag == TypeTags.CLASS &&
 254             (expected.tsym.flags() & Flags.ENUM) != 0) {