src/share/classes/com/sun/tools/classfile/Type.java

Fri, 16 Oct 2009 12:56:50 -0700

author
jjg
date
Fri, 16 Oct 2009 12:56:50 -0700
changeset 427
6ba399eff2cb
parent 280
b5872f0790e7
child 554
9d9f26857129
permissions
-rw-r--r--

6888367: classfile library parses signature attributes incorrectly
Reviewed-by: ksrini

jjg@46 1 /*
jjg@46 2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
jjg@46 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@46 4 *
jjg@46 5 * This code is free software; you can redistribute it and/or modify it
jjg@46 6 * under the terms of the GNU General Public License version 2 only, as
jjg@46 7 * published by the Free Software Foundation. Sun designates this
jjg@46 8 * particular file as subject to the "Classpath" exception as provided
jjg@46 9 * by Sun in the LICENSE file that accompanied this code.
jjg@46 10 *
jjg@46 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@46 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@46 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@46 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@46 15 * accompanied this code).
jjg@46 16 *
jjg@46 17 * You should have received a copy of the GNU General Public License version
jjg@46 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@46 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@46 20 *
jjg@46 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
jjg@46 22 * CA 95054 USA or visit www.sun.com if you need additional information or
jjg@46 23 * have any questions.
jjg@46 24 */
jjg@46 25
jjg@46 26 package com.sun.tools.classfile;
jjg@46 27
jjg@280 28 import java.util.Arrays;
jjg@280 29 import java.util.HashSet;
jjg@46 30 import java.util.List;
jjg@280 31 import java.util.Set;
jjg@46 32
jjg@46 33 /*
jjg@427 34 * Family of classes used to represent the parsed form of a {@link Descriptor}
jjg@427 35 * or {@link Signature}.
jjg@427 36 *
jjg@46 37 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
jjg@46 38 * you write code that depends on this, you do so at your own risk.
jjg@46 39 * This code and its internal interfaces are subject to change or
jjg@46 40 * deletion without notice.</b>
jjg@46 41 */
jjg@280 42 public abstract class Type {
jjg@46 43 protected Type() { }
jjg@280 44 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
jjg@46 45
jjg@46 46 protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
jjg@46 47 sb.append(prefix);
jjg@46 48 String sep = "";
jjg@46 49 for (Type t: types) {
jjg@46 50 sb.append(sep);
jjg@46 51 sb.append(t);
jjg@46 52 sep = ", ";
jjg@46 53 }
jjg@46 54 sb.append(suffix);
jjg@46 55 }
jjg@46 56
jjg@46 57 protected static void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
jjg@46 58 if (types != null && types.size() > 0)
jjg@46 59 append(sb, prefix, types, suffix);
jjg@46 60 }
jjg@46 61
jjg@280 62 public interface Visitor<R,P> {
jjg@280 63 R visitSimpleType(SimpleType type, P p);
jjg@280 64 R visitArrayType(ArrayType type, P p);
jjg@280 65 R visitMethodType(MethodType type, P p);
jjg@280 66 R visitClassSigType(ClassSigType type, P p);
jjg@280 67 R visitClassType(ClassType type, P p);
jjg@427 68 R visitTypeParamType(TypeParamType type, P p);
jjg@280 69 R visitWildcardType(WildcardType type, P p);
jjg@280 70 }
jjg@280 71
jjg@427 72 /**
jjg@427 73 * Represents a type signature with a simple name. The name may be that of a
jjg@427 74 * primitive type, such "{@code int}, {@code float}, etc
jjg@427 75 * or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc.
jjg@427 76 *
jjg@427 77 * See:
jjg@427 78 * JVMS 4.3.2
jjg@427 79 * BaseType:
jjg@427 80 * {@code B}, {@code C}, {@code D}, {@code F}, {@code I},
jjg@427 81 * {@code J}, {@code S}, {@code Z};
jjg@427 82 * VoidDescriptor:
jjg@427 83 * {@code V};
jjg@427 84 * JVMS 4.3.4
jjg@427 85 * TypeVariableSignature:
jjg@427 86 * {@code T} Identifier {@code ;}
jjg@427 87 */
jjg@46 88 public static class SimpleType extends Type {
jjg@46 89 public SimpleType(String name) {
jjg@46 90 this.name = name;
jjg@46 91 }
jjg@46 92
jjg@280 93 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 94 return visitor.visitSimpleType(this, data);
jjg@280 95 }
jjg@280 96
jjg@280 97 public boolean isPrimitiveType() {
jjg@280 98 return primitiveTypes.contains(name);
jjg@280 99 }
jjg@280 100 // where
jjg@280 101 private static final Set<String> primitiveTypes = new HashSet<String>(Arrays.asList(
jjg@280 102 "boolean", "byte", "char", "double", "float", "int", "long", "short", "void"));
jjg@280 103
jjg@46 104 @Override
jjg@46 105 public String toString() {
jjg@46 106 return name;
jjg@46 107 }
jjg@46 108
jjg@46 109 public final String name;
jjg@46 110 }
jjg@46 111
jjg@427 112 /**
jjg@427 113 * Represents an array type signature.
jjg@427 114 *
jjg@427 115 * See:
jjg@427 116 * JVMS 4.3.4
jjg@427 117 * ArrayTypeSignature:
jjg@427 118 * {@code [} TypeSignature {@code ]}
jjg@427 119 */
jjg@46 120 public static class ArrayType extends Type {
jjg@46 121 public ArrayType(Type elemType) {
jjg@46 122 this.elemType = elemType;
jjg@46 123 }
jjg@46 124
jjg@280 125 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 126 return visitor.visitArrayType(this, data);
jjg@280 127 }
jjg@280 128
jjg@46 129 @Override
jjg@46 130 public String toString() {
jjg@46 131 return elemType + "[]";
jjg@46 132 }
jjg@46 133
jjg@46 134 public final Type elemType;
jjg@46 135 }
jjg@46 136
jjg@427 137 /**
jjg@427 138 * Represents a method type signature.
jjg@427 139 *
jjg@427 140 * See;
jjg@427 141 * JVMS 4.3.4
jjg@427 142 * MethodTypeSignature:
jjg@427 143 * FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType
jjg@427 144 * ThrowsSignature*
jjg@427 145 */
jjg@46 146 public static class MethodType extends Type {
jjg@427 147 public MethodType(List<? extends Type> paramTypes, Type resultType) {
jjg@427 148 this(null, paramTypes, resultType, null);
jjg@46 149 }
jjg@46 150
jjg@427 151 public MethodType(List<? extends TypeParamType> typeParamTypes,
jjg@427 152 List<? extends Type> paramTypes,
jjg@46 153 Type returnType,
jjg@46 154 List<? extends Type> throwsTypes) {
jjg@427 155 this.typeParamTypes = typeParamTypes;
jjg@427 156 this.paramTypes = paramTypes;
jjg@46 157 this.returnType = returnType;
jjg@46 158 this.throwsTypes = throwsTypes;
jjg@46 159 }
jjg@46 160
jjg@280 161 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 162 return visitor.visitMethodType(this, data);
jjg@280 163 }
jjg@280 164
jjg@46 165 @Override
jjg@46 166 public String toString() {
jjg@46 167 StringBuilder sb = new StringBuilder();
jjg@427 168 appendIfNotEmpty(sb, "<", typeParamTypes, "> ");
jjg@46 169 sb.append(returnType);
jjg@427 170 append(sb, " (", paramTypes, ")");
jjg@46 171 appendIfNotEmpty(sb, " throws ", throwsTypes, "");
jjg@46 172 return sb.toString();
jjg@46 173 }
jjg@46 174
jjg@427 175 public final List<? extends TypeParamType> typeParamTypes;
jjg@427 176 public final List<? extends Type> paramTypes;
jjg@46 177 public final Type returnType;
jjg@46 178 public final List<? extends Type> throwsTypes;
jjg@46 179 }
jjg@46 180
jjg@427 181 /**
jjg@427 182 * Represents a class signature. These describe the signature of
jjg@427 183 * a class that has type arguments.
jjg@427 184 *
jjg@427 185 * See:
jjg@427 186 * JVMS 4.3.4
jjg@427 187 * ClassSignature:
jjg@427 188 * FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
jjg@427 189 */
jjg@46 190 public static class ClassSigType extends Type {
jjg@427 191 public ClassSigType(List<TypeParamType> typeParamTypes, Type superclassType,
jjg@427 192 List<Type> superinterfaceTypes) {
jjg@427 193 this.typeParamTypes = typeParamTypes;
jjg@46 194 this.superclassType = superclassType;
jjg@46 195 this.superinterfaceTypes = superinterfaceTypes;
jjg@46 196 }
jjg@46 197
jjg@280 198 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 199 return visitor.visitClassSigType(this, data);
jjg@280 200 }
jjg@280 201
jjg@46 202 @Override
jjg@46 203 public String toString() {
jjg@46 204 StringBuilder sb = new StringBuilder();
jjg@427 205 appendIfNotEmpty(sb, "<", typeParamTypes, ">");
jjg@65 206 if (superclassType != null) {
jjg@46 207 sb.append(" extends ");
jjg@46 208 sb.append(superclassType);
jjg@46 209 }
jjg@46 210 appendIfNotEmpty(sb, " implements ", superinterfaceTypes, "");
jjg@46 211 return sb.toString();
jjg@46 212 }
jjg@46 213
jjg@427 214 public final List<TypeParamType> typeParamTypes;
jjg@46 215 public final Type superclassType;
jjg@46 216 public final List<Type> superinterfaceTypes;
jjg@46 217 }
jjg@46 218
jjg@427 219 /**
jjg@427 220 * Represents a class type signature. This is used to represent a
jjg@427 221 * reference to a class, such as in a field, parameter, return type, etc.
jjg@427 222 *
jjg@427 223 * See:
jjg@427 224 * JVMS 4.3.4
jjg@427 225 * ClassTypeSignature:
jjg@427 226 * {@code L} PackageSpecifier_opt SimpleClassTypeSignature
jjg@427 227 * ClassTypeSignatureSuffix* {@code ;}
jjg@427 228 * PackageSpecifier:
jjg@427 229 * Identifier {@code /} PackageSpecifier*
jjg@427 230 * SimpleClassTypeSignature:
jjg@427 231 * Identifier TypeArguments_opt }
jjg@427 232 * ClassTypeSignatureSuffix:
jjg@427 233 * {@code .} SimpleClassTypeSignature
jjg@427 234 */
jjg@46 235 public static class ClassType extends Type {
jjg@427 236 public ClassType(ClassType outerType, String name, List<Type> typeArgs) {
jjg@427 237 this.outerType = outerType;
jjg@46 238 this.name = name;
jjg@46 239 this.typeArgs = typeArgs;
jjg@46 240 }
jjg@46 241
jjg@280 242 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 243 return visitor.visitClassType(this, data);
jjg@280 244 }
jjg@280 245
jjg@427 246 public String getBinaryName() {
jjg@427 247 if (outerType == null)
jjg@427 248 return name;
jjg@427 249 else
jjg@427 250 return (outerType.getBinaryName() + "$" + name);
jjg@427 251 }
jjg@427 252
jjg@46 253 @Override
jjg@46 254 public String toString() {
jjg@46 255 StringBuilder sb = new StringBuilder();
jjg@427 256 if (outerType != null) {
jjg@427 257 sb.append(outerType);
jjg@427 258 sb.append(".");
jjg@427 259 }
jjg@46 260 sb.append(name);
jjg@46 261 appendIfNotEmpty(sb, "<", typeArgs, ">");
jjg@46 262 return sb.toString();
jjg@46 263 }
jjg@46 264
jjg@427 265 public final ClassType outerType;
jjg@46 266 public final String name;
jjg@46 267 public final List<Type> typeArgs;
jjg@46 268 }
jjg@46 269
jjg@427 270 /**
jjg@427 271 * Represents a FormalTypeParameter. These are used to declare the type
jjg@427 272 * parameters for generic classes and methods.
jjg@427 273 *
jjg@427 274 * See:
jjg@427 275 * JVMS 4.3.4
jjg@427 276 * FormalTypeParameters:
jjg@427 277 * {@code <} FormalTypeParameter+ {@code >}
jjg@427 278 * FormalTypeParameter:
jjg@427 279 * Identifier ClassBound InterfaceBound*
jjg@427 280 * ClassBound:
jjg@427 281 * {@code :} FieldTypeSignature_opt
jjg@427 282 * InterfaceBound:
jjg@427 283 * {@code :} FieldTypeSignature
jjg@427 284 */
jjg@427 285 public static class TypeParamType extends Type {
jjg@427 286 public TypeParamType(String name, Type classBound, List<Type> interfaceBounds) {
jjg@46 287 this.name = name;
jjg@46 288 this.classBound = classBound;
jjg@46 289 this.interfaceBounds = interfaceBounds;
jjg@46 290 }
jjg@46 291
jjg@280 292 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@427 293 return visitor.visitTypeParamType(this, data);
jjg@280 294 }
jjg@280 295
jjg@46 296 @Override
jjg@46 297 public String toString() {
jjg@46 298 StringBuilder sb = new StringBuilder();
jjg@46 299 sb.append(name);
jjg@46 300 String sep = " extends ";
jjg@65 301 if (classBound != null) {
jjg@46 302 sb.append(sep);
jjg@46 303 sb.append(classBound);
jjg@46 304 sep = " & ";
jjg@46 305 }
jjg@46 306 if (interfaceBounds != null) {
jjg@46 307 for (Type bound: interfaceBounds) {
jjg@46 308 sb.append(sep);
jjg@46 309 sb.append(bound);
jjg@46 310 sep = " & ";
jjg@46 311 }
jjg@46 312 }
jjg@46 313 return sb.toString();
jjg@46 314 }
jjg@46 315
jjg@46 316 public final String name;
jjg@46 317 public final Type classBound;
jjg@46 318 public final List<Type> interfaceBounds;
jjg@46 319 }
jjg@46 320
jjg@427 321 /**
jjg@427 322 * Represents a wildcard type argument. A type argument that is not a
jjg@427 323 * wildcard type argument will be represented by a ClassType, ArrayType, etc.
jjg@427 324 *
jjg@427 325 * See:
jjg@427 326 * JVMS 4.3.4
jjg@427 327 * TypeArgument:
jjg@427 328 * WildcardIndicator_opt FieldTypeSignature
jjg@427 329 * {@code *}
jjg@427 330 * WildcardIndicator:
jjg@427 331 * {@code +}
jjg@427 332 * {@code -}
jjg@427 333 */
jjg@46 334 public static class WildcardType extends Type {
jjg@427 335 public enum Kind { UNBOUNDED, EXTENDS, SUPER };
jjg@46 336 public WildcardType() {
jjg@427 337 this(Kind.UNBOUNDED, null);
jjg@46 338 }
jjg@427 339 public WildcardType(Kind kind, Type boundType) {
jjg@46 340 this.kind = kind;
jjg@46 341 this.boundType = boundType;
jjg@46 342 }
jjg@46 343
jjg@280 344 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@280 345 return visitor.visitWildcardType(this, data);
jjg@280 346 }
jjg@280 347
jjg@46 348 @Override
jjg@46 349 public String toString() {
jjg@427 350 switch (kind) {
jjg@427 351 case UNBOUNDED:
jjg@427 352 return "?";
jjg@427 353 case EXTENDS:
jjg@427 354 return "? extends " + boundType;
jjg@427 355 case SUPER:
jjg@427 356 return "? super " + boundType;
jjg@427 357 default:
jjg@427 358 throw new AssertionError();
jjg@427 359 }
jjg@46 360 }
jjg@46 361
jjg@427 362 public final Kind kind;
jjg@46 363 public final Type boundType;
jjg@46 364 }
jjg@46 365 }

mercurial