Wed, 21 Sep 2011 21:56:53 -0700
7092965: javac should not close processorClassLoader before end of compilation
Reviewed-by: darcy
1 /*
2 * Copyright (c) 2003, 2011, 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 /** The value for an annotation element of an array type.
208 */
209 public static class Array extends Attribute {
210 public final Attribute[] values;
211 public Array(Type type, Attribute[] values) {
212 super(type);
213 this.values = values;
214 }
215 public void accept(Visitor v) { v.visitArray(this); }
216 public String toString() {
217 StringBuilder buf = new StringBuilder();
218 buf.append('{');
219 boolean first = true;
220 for (Attribute value : values) {
221 if (!first)
222 buf.append(", ");
223 first = false;
224 buf.append(value);
225 }
226 buf.append('}');
227 return buf.toString();
228 }
229 public List<Attribute> getValue() {
230 return List.from(values);
231 }
232 public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
233 return v.visitArray(getValue(), p);
234 }
235 }
237 /** The value for an annotation element of an enum type.
238 */
239 public static class Enum extends Attribute {
240 public VarSymbol value;
241 public Enum(Type type, VarSymbol value) {
242 super(type);
243 this.value = Assert.checkNonNull(value);
244 }
245 public void accept(Visitor v) { v.visitEnum(this); }
246 public String toString() {
247 return value.enclClass() + "." + value; // qualified name
248 }
249 public VarSymbol getValue() {
250 return value;
251 }
252 public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
253 return v.visitEnumConstant(value, p);
254 }
255 }
257 public static class Error extends Attribute {
258 public Error(Type type) {
259 super(type);
260 }
261 public void accept(Visitor v) { v.visitError(this); }
262 public String toString() {
263 return "<error>";
264 }
265 public String getValue() {
266 return toString();
267 }
268 public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
269 return v.visitString(toString(), p);
270 }
271 }
273 /** A visitor type for dynamic dispatch on the kind of attribute value. */
274 public static interface Visitor {
275 void visitConstant(Attribute.Constant value);
276 void visitClass(Attribute.Class clazz);
277 void visitCompound(Attribute.Compound compound);
278 void visitArray(Attribute.Array array);
279 void visitEnum(Attribute.Enum e);
280 void visitError(Attribute.Error e);
281 }
283 /** A mirror of java.lang.annotation.RetentionPolicy. */
284 public static enum RetentionPolicy {
285 SOURCE,
286 CLASS,
287 RUNTIME
288 }
289 }