src/share/classes/com/sun/tools/javac/code/Attribute.java

Sun, 17 Feb 2013 16:44:55 -0500

author
dholmes
date
Sun, 17 Feb 2013 16:44:55 -0500
changeset 1571
af8417e590f4
parent 1521
71f35e4b93a5
child 1755
ddb4a2bfcd82
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2003, 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 java.util.LinkedHashMap;
    29 import java.util.Map;
    30 import javax.lang.model.element.AnnotationMirror;
    31 import javax.lang.model.element.AnnotationValue;
    32 import javax.lang.model.element.AnnotationValueVisitor;
    33 import javax.lang.model.type.DeclaredType;
    34 import com.sun.tools.javac.code.Symbol.*;
    35 import com.sun.tools.javac.util.*;
    37 /** An annotation value.
    38  *
    39  *  <p><b>This is NOT part of any supported API.
    40  *  If you write code that depends on this, you do so at your own risk.
    41  *  This code and its internal interfaces are subject to change or
    42  *  deletion without notice.</b>
    43  */
    44 public abstract class Attribute implements AnnotationValue {
    46     /** The type of the annotation element. */
    47     public Type type;
    49     public Attribute(Type type) {
    50         this.type = type;
    51     }
    53     public abstract void accept(Visitor v);
    55     public Object getValue() {
    56         throw new UnsupportedOperationException();
    57     }
    59     public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
    60         throw new UnsupportedOperationException();
    61     }
    63     public boolean isSynthesized() {
    64         return false;
    65     }
    67     /** The value for an annotation element of primitive type or String. */
    68     public static class Constant extends Attribute {
    69         public final Object value;
    70         public void accept(Visitor v) { v.visitConstant(this); }
    71         public Constant(Type type, Object value) {
    72             super(type);
    73             this.value = value;
    74         }
    75         public String toString() {
    76             return Constants.format(value, type);
    77         }
    78         public Object getValue() {
    79             return Constants.decode(value, type);
    80         }
    81         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
    82             if (value instanceof String)
    83                 return v.visitString((String) value, p);
    84             if (value instanceof Integer) {
    85                 int i = (Integer) value;
    86                 switch (type.tag) {
    87                 case BOOLEAN:   return v.visitBoolean(i != 0, p);
    88                 case CHAR:      return v.visitChar((char) i, p);
    89                 case BYTE:      return v.visitByte((byte) i, p);
    90                 case SHORT:     return v.visitShort((short) i, p);
    91                 case INT:       return v.visitInt(i, p);
    92                 }
    93             }
    94             switch (type.tag) {
    95             case LONG:          return v.visitLong((Long) value, p);
    96             case FLOAT:         return v.visitFloat((Float) value, p);
    97             case DOUBLE:        return v.visitDouble((Double) value, p);
    98             }
    99             throw new AssertionError("Bad annotation element value: " + value);
   100         }
   101     }
   103     /** The value for an annotation element of type java.lang.Class,
   104      *  represented as a ClassSymbol.
   105      */
   106     public static class Class extends Attribute {
   107         public final Type classType;
   108         public void accept(Visitor v) { v.visitClass(this); }
   109         public Class(Types types, Type type) {
   110             super(makeClassType(types, type));
   111             this.classType = type;
   112         }
   113         static Type makeClassType(Types types, Type type) {
   114             Type arg = type.isPrimitive()
   115                 ? types.boxedClass(type).type
   116                 : types.erasure(type);
   117             return new Type.ClassType(types.syms.classType.getEnclosingType(),
   118                                       List.of(arg),
   119                                       types.syms.classType.tsym);
   120         }
   121         public String toString() {
   122             return classType + ".class";
   123         }
   124         public Type getValue() {
   125             return classType;
   126         }
   127         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   128             return v.visitType(classType, p);
   129         }
   130     }
   132     /** A compound annotation element value, the type of which is an
   133      *  attribute interface.
   134      */
   135     public static class Compound extends Attribute implements AnnotationMirror {
   136         /** The attributes values, as pairs.  Each pair contains a
   137          *  reference to the accessing method in the attribute interface
   138          *  and the value to be returned when that method is called to
   139          *  access this attribute.
   140          */
   141         public final List<Pair<MethodSymbol,Attribute>> values;
   143         private boolean synthesized = false;
   145         @Override
   146         public boolean isSynthesized() {
   147             return synthesized;
   148         }
   150         public void setSynthesized(boolean synthesized) {
   151             this.synthesized = synthesized;
   152         }
   154         public Compound(Type type,
   155                         List<Pair<MethodSymbol,Attribute>> values) {
   156             super(type);
   157             this.values = values;
   158         }
   159         public void accept(Visitor v) { v.visitCompound(this); }
   161         /**
   162          * Returns a string representation of this annotation.
   163          * String is of one of the forms:
   164          *     @com.example.foo(name1=val1, name2=val2)
   165          *     @com.example.foo(val)
   166          *     @com.example.foo
   167          * Omit parens for marker annotations, and omit "value=" when allowed.
   168          */
   169         public String toString() {
   170             StringBuilder buf = new StringBuilder();
   171             buf.append("@");
   172             buf.append(type);
   173             int len = values.length();
   174             if (len > 0) {
   175                 buf.append('(');
   176                 boolean first = true;
   177                 for (Pair<MethodSymbol, Attribute> value : values) {
   178                     if (!first) buf.append(", ");
   179                     first = false;
   181                     Name name = value.fst.name;
   182                     if (len > 1 || name != name.table.names.value) {
   183                         buf.append(name);
   184                         buf.append('=');
   185                     }
   186                     buf.append(value.snd);
   187                 }
   188                 buf.append(')');
   189             }
   190             return buf.toString();
   191         }
   193         public Attribute member(Name member) {
   194             for (Pair<MethodSymbol,Attribute> pair : values)
   195                 if (pair.fst.name == member) return pair.snd;
   196             return null;
   197         }
   199         public Attribute.Compound getValue() {
   200             return this;
   201         }
   203         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   204             return v.visitAnnotation(this, p);
   205         }
   207         public DeclaredType getAnnotationType() {
   208             return (DeclaredType) type;
   209         }
   211         public Map<MethodSymbol, Attribute> getElementValues() {
   212             Map<MethodSymbol, Attribute> valmap =
   213                 new LinkedHashMap<MethodSymbol, Attribute>();
   214             for (Pair<MethodSymbol, Attribute> value : values)
   215                 valmap.put(value.fst, value.snd);
   216             return valmap;
   217         }
   218     }
   220     public static class TypeCompound extends Compound {
   221         public TypeAnnotationPosition position;
   222         public TypeCompound(Compound compound,
   223                 TypeAnnotationPosition position) {
   224             this(compound.type, compound.values, position);
   225         }
   226         public TypeCompound(Type type,
   227                 List<Pair<MethodSymbol, Attribute>> values,
   228                 TypeAnnotationPosition position) {
   229             super(type, values);
   230             this.position = position;
   231         }
   233     }
   235     /** The value for an annotation element of an array type.
   236      */
   237     public static class Array extends Attribute {
   238         public final Attribute[] values;
   239         public Array(Type type, Attribute[] values) {
   240             super(type);
   241             this.values = values;
   242         }
   244         public Array(Type type, List<Attribute> values) {
   245             super(type);
   246             this.values = values.toArray(new Attribute[values.size()]);
   247         }
   249         public void accept(Visitor v) { v.visitArray(this); }
   250         public String toString() {
   251             StringBuilder buf = new StringBuilder();
   252             buf.append('{');
   253             boolean first = true;
   254             for (Attribute value : values) {
   255                 if (!first)
   256                     buf.append(", ");
   257                 first = false;
   258                 buf.append(value);
   259             }
   260             buf.append('}');
   261             return buf.toString();
   262         }
   263         public List<Attribute> getValue() {
   264             return List.from(values);
   265         }
   266         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   267             return v.visitArray(getValue(), p);
   268         }
   269     }
   271     /** The value for an annotation element of an enum type.
   272      */
   273     public static class Enum extends Attribute {
   274         public VarSymbol value;
   275         public Enum(Type type, VarSymbol value) {
   276             super(type);
   277             this.value = Assert.checkNonNull(value);
   278         }
   279         public void accept(Visitor v) { v.visitEnum(this); }
   280         public String toString() {
   281             return value.enclClass() + "." + value;     // qualified name
   282         }
   283         public VarSymbol getValue() {
   284             return value;
   285         }
   286         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   287             return v.visitEnumConstant(value, p);
   288         }
   289     }
   291     public static class Error extends Attribute {
   292         public Error(Type type) {
   293             super(type);
   294         }
   295         public void accept(Visitor v) { v.visitError(this); }
   296         public String toString() {
   297             return "<error>";
   298         }
   299         public String getValue() {
   300             return toString();
   301         }
   302         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   303             return v.visitString(toString(), p);
   304         }
   305     }
   307     /** A visitor type for dynamic dispatch on the kind of attribute value. */
   308     public static interface Visitor {
   309         void visitConstant(Attribute.Constant value);
   310         void visitClass(Attribute.Class clazz);
   311         void visitCompound(Attribute.Compound compound);
   312         void visitArray(Attribute.Array array);
   313         void visitEnum(Attribute.Enum e);
   314         void visitError(Attribute.Error e);
   315     }
   317     /** A mirror of java.lang.annotation.RetentionPolicy. */
   318     public static enum RetentionPolicy {
   319         SOURCE,
   320         CLASS,
   321         RUNTIME
   322     }
   323 }

mercurial