Mon, 28 Feb 2011 11:48:53 +0000
7015430: Incorrect thrown type determined for unchecked invocations
Summary: Thrown types do not get updated after 15.12.2.8, and do not get erased as per 15.12.2.6
Reviewed-by: jjg, dlsmith
1 /*
2 * Copyright (c) 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.classfile;
28 import java.util.Arrays;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
33 /*
34 * Family of classes used to represent the parsed form of a {@link Descriptor}
35 * or {@link Signature}.
36 *
37 * <p><b>This is NOT part of any supported API.
38 * If you write code that depends on this, you do so at your own risk.
39 * This code and its internal interfaces are subject to change or
40 * deletion without notice.</b>
41 */
42 public abstract class Type {
43 protected Type() { }
44 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
46 protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
47 sb.append(prefix);
48 String sep = "";
49 for (Type t: types) {
50 sb.append(sep);
51 sb.append(t);
52 sep = ", ";
53 }
54 sb.append(suffix);
55 }
57 protected static void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
58 if (types != null && types.size() > 0)
59 append(sb, prefix, types, suffix);
60 }
62 public interface Visitor<R,P> {
63 R visitSimpleType(SimpleType type, P p);
64 R visitArrayType(ArrayType type, P p);
65 R visitMethodType(MethodType type, P p);
66 R visitClassSigType(ClassSigType type, P p);
67 R visitClassType(ClassType type, P p);
68 R visitTypeParamType(TypeParamType type, P p);
69 R visitWildcardType(WildcardType type, P p);
70 }
72 /**
73 * Represents a type signature with a simple name. The name may be that of a
74 * primitive type, such "{@code int}, {@code float}, etc
75 * or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc.
76 *
77 * See:
78 * JVMS 4.3.2
79 * BaseType:
80 * {@code B}, {@code C}, {@code D}, {@code F}, {@code I},
81 * {@code J}, {@code S}, {@code Z};
82 * VoidDescriptor:
83 * {@code V};
84 * JVMS 4.3.4
85 * TypeVariableSignature:
86 * {@code T} Identifier {@code ;}
87 */
88 public static class SimpleType extends Type {
89 public SimpleType(String name) {
90 this.name = name;
91 }
93 public <R, D> R accept(Visitor<R, D> visitor, D data) {
94 return visitor.visitSimpleType(this, data);
95 }
97 public boolean isPrimitiveType() {
98 return primitiveTypes.contains(name);
99 }
100 // where
101 private static final Set<String> primitiveTypes = new HashSet<String>(Arrays.asList(
102 "boolean", "byte", "char", "double", "float", "int", "long", "short", "void"));
104 @Override
105 public String toString() {
106 return name;
107 }
109 public final String name;
110 }
112 /**
113 * Represents an array type signature.
114 *
115 * See:
116 * JVMS 4.3.4
117 * ArrayTypeSignature:
118 * {@code [} TypeSignature {@code ]}
119 */
120 public static class ArrayType extends Type {
121 public ArrayType(Type elemType) {
122 this.elemType = elemType;
123 }
125 public <R, D> R accept(Visitor<R, D> visitor, D data) {
126 return visitor.visitArrayType(this, data);
127 }
129 @Override
130 public String toString() {
131 return elemType + "[]";
132 }
134 public final Type elemType;
135 }
137 /**
138 * Represents a method type signature.
139 *
140 * See;
141 * JVMS 4.3.4
142 * MethodTypeSignature:
143 * FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType
144 * ThrowsSignature*
145 */
146 public static class MethodType extends Type {
147 public MethodType(List<? extends Type> paramTypes, Type resultType) {
148 this(null, paramTypes, resultType, null);
149 }
151 public MethodType(List<? extends TypeParamType> typeParamTypes,
152 List<? extends Type> paramTypes,
153 Type returnType,
154 List<? extends Type> throwsTypes) {
155 this.typeParamTypes = typeParamTypes;
156 this.paramTypes = paramTypes;
157 this.returnType = returnType;
158 this.throwsTypes = throwsTypes;
159 }
161 public <R, D> R accept(Visitor<R, D> visitor, D data) {
162 return visitor.visitMethodType(this, data);
163 }
165 @Override
166 public String toString() {
167 StringBuilder sb = new StringBuilder();
168 appendIfNotEmpty(sb, "<", typeParamTypes, "> ");
169 sb.append(returnType);
170 append(sb, " (", paramTypes, ")");
171 appendIfNotEmpty(sb, " throws ", throwsTypes, "");
172 return sb.toString();
173 }
175 public final List<? extends TypeParamType> typeParamTypes;
176 public final List<? extends Type> paramTypes;
177 public final Type returnType;
178 public final List<? extends Type> throwsTypes;
179 }
181 /**
182 * Represents a class signature. These describe the signature of
183 * a class that has type arguments.
184 *
185 * See:
186 * JVMS 4.3.4
187 * ClassSignature:
188 * FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
189 */
190 public static class ClassSigType extends Type {
191 public ClassSigType(List<TypeParamType> typeParamTypes, Type superclassType,
192 List<Type> superinterfaceTypes) {
193 this.typeParamTypes = typeParamTypes;
194 this.superclassType = superclassType;
195 this.superinterfaceTypes = superinterfaceTypes;
196 }
198 public <R, D> R accept(Visitor<R, D> visitor, D data) {
199 return visitor.visitClassSigType(this, data);
200 }
202 @Override
203 public String toString() {
204 StringBuilder sb = new StringBuilder();
205 appendIfNotEmpty(sb, "<", typeParamTypes, ">");
206 if (superclassType != null) {
207 sb.append(" extends ");
208 sb.append(superclassType);
209 }
210 appendIfNotEmpty(sb, " implements ", superinterfaceTypes, "");
211 return sb.toString();
212 }
214 public final List<TypeParamType> typeParamTypes;
215 public final Type superclassType;
216 public final List<Type> superinterfaceTypes;
217 }
219 /**
220 * Represents a class type signature. This is used to represent a
221 * reference to a class, such as in a field, parameter, return type, etc.
222 *
223 * See:
224 * JVMS 4.3.4
225 * ClassTypeSignature:
226 * {@code L} PackageSpecifier_opt SimpleClassTypeSignature
227 * ClassTypeSignatureSuffix* {@code ;}
228 * PackageSpecifier:
229 * Identifier {@code /} PackageSpecifier*
230 * SimpleClassTypeSignature:
231 * Identifier TypeArguments_opt }
232 * ClassTypeSignatureSuffix:
233 * {@code .} SimpleClassTypeSignature
234 */
235 public static class ClassType extends Type {
236 public ClassType(ClassType outerType, String name, List<Type> typeArgs) {
237 this.outerType = outerType;
238 this.name = name;
239 this.typeArgs = typeArgs;
240 }
242 public <R, D> R accept(Visitor<R, D> visitor, D data) {
243 return visitor.visitClassType(this, data);
244 }
246 public String getBinaryName() {
247 if (outerType == null)
248 return name;
249 else
250 return (outerType.getBinaryName() + "$" + name);
251 }
253 @Override
254 public String toString() {
255 StringBuilder sb = new StringBuilder();
256 if (outerType != null) {
257 sb.append(outerType);
258 sb.append(".");
259 }
260 sb.append(name);
261 appendIfNotEmpty(sb, "<", typeArgs, ">");
262 return sb.toString();
263 }
265 public final ClassType outerType;
266 public final String name;
267 public final List<Type> typeArgs;
268 }
270 /**
271 * Represents a FormalTypeParameter. These are used to declare the type
272 * parameters for generic classes and methods.
273 *
274 * See:
275 * JVMS 4.3.4
276 * FormalTypeParameters:
277 * {@code <} FormalTypeParameter+ {@code >}
278 * FormalTypeParameter:
279 * Identifier ClassBound InterfaceBound*
280 * ClassBound:
281 * {@code :} FieldTypeSignature_opt
282 * InterfaceBound:
283 * {@code :} FieldTypeSignature
284 */
285 public static class TypeParamType extends Type {
286 public TypeParamType(String name, Type classBound, List<Type> interfaceBounds) {
287 this.name = name;
288 this.classBound = classBound;
289 this.interfaceBounds = interfaceBounds;
290 }
292 public <R, D> R accept(Visitor<R, D> visitor, D data) {
293 return visitor.visitTypeParamType(this, data);
294 }
296 @Override
297 public String toString() {
298 StringBuilder sb = new StringBuilder();
299 sb.append(name);
300 String sep = " extends ";
301 if (classBound != null) {
302 sb.append(sep);
303 sb.append(classBound);
304 sep = " & ";
305 }
306 if (interfaceBounds != null) {
307 for (Type bound: interfaceBounds) {
308 sb.append(sep);
309 sb.append(bound);
310 sep = " & ";
311 }
312 }
313 return sb.toString();
314 }
316 public final String name;
317 public final Type classBound;
318 public final List<Type> interfaceBounds;
319 }
321 /**
322 * Represents a wildcard type argument. A type argument that is not a
323 * wildcard type argument will be represented by a ClassType, ArrayType, etc.
324 *
325 * See:
326 * JVMS 4.3.4
327 * TypeArgument:
328 * WildcardIndicator_opt FieldTypeSignature
329 * {@code *}
330 * WildcardIndicator:
331 * {@code +}
332 * {@code -}
333 */
334 public static class WildcardType extends Type {
335 public enum Kind { UNBOUNDED, EXTENDS, SUPER };
336 public WildcardType() {
337 this(Kind.UNBOUNDED, null);
338 }
339 public WildcardType(Kind kind, Type boundType) {
340 this.kind = kind;
341 this.boundType = boundType;
342 }
344 public <R, D> R accept(Visitor<R, D> visitor, D data) {
345 return visitor.visitWildcardType(this, data);
346 }
348 @Override
349 public String toString() {
350 switch (kind) {
351 case UNBOUNDED:
352 return "?";
353 case EXTENDS:
354 return "? extends " + boundType;
355 case SUPER:
356 return "? super " + boundType;
357 default:
358 throw new AssertionError();
359 }
360 }
362 public final Kind kind;
363 public final Type boundType;
364 }
365 }