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