1 /* 2 * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package com.sun.tools.classfile; 27 28 import java.util.Arrays; 29 import java.util.HashSet; 30 import java.util.List; 31 import java.util.Set; 32 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 API supported by Sun Microsystems. If 38 * 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); 45 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 } 56 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 } 61 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 } 71 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 } 92 93 public <R, D> R accept(Visitor<R, D> visitor, D data) { 94 return visitor.visitSimpleType(this, data); 95 } 96 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")); 103 104 @Override 105 public String toString() { 106 return name; 107 } 108 109 public final String name; 110 } 111 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 } 124 125 public <R, D> R accept(Visitor<R, D> visitor, D data) { 126 return visitor.visitArrayType(this, data); 127 } 128 129 @Override 130 public String toString() { 131 return elemType + "[]"; 132 } 133 134 public final Type elemType; 135 } 136 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 } 150 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 } 160 161 public <R, D> R accept(Visitor<R, D> visitor, D data) { 162 return visitor.visitMethodType(this, data); 163 } 164 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 } 174 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 } 180 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 } 197 198 public <R, D> R accept(Visitor<R, D> visitor, D data) { 199 return visitor.visitClassSigType(this, data); 200 } 201 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 } 213 214 public final List<TypeParamType> typeParamTypes; 215 public final Type superclassType; 216 public final List<Type> superinterfaceTypes; 217 } 218 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 } 241 242 public <R, D> R accept(Visitor<R, D> visitor, D data) { 243 return visitor.visitClassType(this, data); 244 } 245 246 public String getBinaryName() { 247 if (outerType == null) 248 return name; 249 else 250 return (outerType.getBinaryName() + "$" + name); 251 } 252 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 } 264 265 public final ClassType outerType; 266 public final String name; 267 public final List<Type> typeArgs; 268 } 269 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 } 291 292 public <R, D> R accept(Visitor<R, D> visitor, D data) { 293 return visitor.visitTypeParamType(this, data); 294 } 295 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 } 315 316 public final String name; 317 public final Type classBound; 318 public final List<Type> interfaceBounds; 319 } 320 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 } 343 344 public <R, D> R accept(Visitor<R, D> visitor, D data) { 345 return visitor.visitWildcardType(this, data); 346 } 347 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 } 361 362 public final Kind kind; 363 public final Type boundType; 364 } 365 }