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

Wed, 28 Aug 2013 15:40:33 -0700

author
jjg
date
Wed, 28 Aug 2013 15:40:33 -0700
changeset 1984
189942cdf585
parent 1960
e811fb09a1dc
child 2103
b1b4a6dcc282
permissions
-rw-r--r--

8010310: [javadoc] Error processing sources with -private
Reviewed-by: vromero, mcimadamore

     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.getTag()) {
    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.getTag()) {
    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         public boolean hasUnknownPosition() {
   234             return position == null || position.type == TargetType.UNKNOWN;
   235         }
   237         public boolean isContainerTypeCompound() {
   238             if (isSynthesized() && values.size() == 1)
   239                 return getFirstEmbeddedTC() != null;
   240             return false;
   241         }
   243         private TypeCompound getFirstEmbeddedTC() {
   244             if (values.size() == 1) {
   245                 Pair<MethodSymbol, Attribute> val = values.get(0);
   246                 if (val.fst.getSimpleName().contentEquals("value")
   247                         && val.snd instanceof Array) {
   248                     Array arr = (Array) val.snd;
   249                     if (arr.values.length != 0
   250                             && arr.values[0] instanceof Attribute.TypeCompound)
   251                         return (Attribute.TypeCompound) arr.values[0];
   252                 }
   253             }
   254             return null;
   255         }
   257         public boolean tryFixPosition() {
   258             if (!isContainerTypeCompound())
   259                 return false;
   261             TypeCompound from = getFirstEmbeddedTC();
   262             if (from != null && from.position != null &&
   263                     from.position.type != TargetType.UNKNOWN) {
   264                 position = from.position;
   265                 return true;
   266             }
   267             return false;
   268         }
   269     }
   271     /** The value for an annotation element of an array type.
   272      */
   273     public static class Array extends Attribute {
   274         public final Attribute[] values;
   275         public Array(Type type, Attribute[] values) {
   276             super(type);
   277             this.values = values;
   278         }
   280         public Array(Type type, List<Attribute> values) {
   281             super(type);
   282             this.values = values.toArray(new Attribute[values.size()]);
   283         }
   285         public void accept(Visitor v) { v.visitArray(this); }
   286         public String toString() {
   287             StringBuilder buf = new StringBuilder();
   288             buf.append('{');
   289             boolean first = true;
   290             for (Attribute value : values) {
   291                 if (!first)
   292                     buf.append(", ");
   293                 first = false;
   294                 buf.append(value);
   295             }
   296             buf.append('}');
   297             return buf.toString();
   298         }
   299         public List<Attribute> getValue() {
   300             return List.from(values);
   301         }
   302         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   303             return v.visitArray(getValue(), p);
   304         }
   305     }
   307     /** The value for an annotation element of an enum type.
   308      */
   309     public static class Enum extends Attribute {
   310         public VarSymbol value;
   311         public Enum(Type type, VarSymbol value) {
   312             super(type);
   313             this.value = Assert.checkNonNull(value);
   314         }
   315         public void accept(Visitor v) { v.visitEnum(this); }
   316         public String toString() {
   317             return value.enclClass() + "." + value;     // qualified name
   318         }
   319         public VarSymbol getValue() {
   320             return value;
   321         }
   322         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   323             return v.visitEnumConstant(value, p);
   324         }
   325     }
   327     public static class Error extends Attribute {
   328         public Error(Type type) {
   329             super(type);
   330         }
   331         public void accept(Visitor v) { v.visitError(this); }
   332         public String toString() {
   333             return "<error>";
   334         }
   335         public String getValue() {
   336             return toString();
   337         }
   338         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
   339             return v.visitString(toString(), p);
   340         }
   341     }
   343     public static class UnresolvedClass extends Error {
   344         public Type classType;
   345         public UnresolvedClass(Type type, Type classType) {
   346             super(type);
   347             this.classType = classType;
   348         }
   349     }
   351     /** A visitor type for dynamic dispatch on the kind of attribute value. */
   352     public static interface Visitor {
   353         void visitConstant(Attribute.Constant value);
   354         void visitClass(Attribute.Class clazz);
   355         void visitCompound(Attribute.Compound compound);
   356         void visitArray(Attribute.Array array);
   357         void visitEnum(Attribute.Enum e);
   358         void visitError(Attribute.Error e);
   359     }
   361     /** A mirror of java.lang.annotation.RetentionPolicy. */
   362     public static enum RetentionPolicy {
   363         SOURCE,
   364         CLASS,
   365         RUNTIME
   366     }
   367 }

mercurial