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

Sat, 29 Dec 2012 17:33:17 -0800

author
jjg
date
Sat, 29 Dec 2012 17:33:17 -0800
changeset 1473
31780dd06ec7
parent 953
c55928005af4
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8004727: Add compiler support for parameter reflection
Reviewed-by: jjg
Contributed-by: eric.mccorkle@oracle.com

     1 /*
     2  * Copyright (c) 2008, 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.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() { }
    45     public boolean isObject() {
    46         return false;
    47     }
    49     public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
    51     protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
    52         sb.append(prefix);
    53         String sep = "";
    54         for (Type t: types) {
    55             sb.append(sep);
    56             sb.append(t);
    57             sep = ", ";
    58         }
    59         sb.append(suffix);
    60     }
    62     protected static void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
    63         if (types != null && types.size() > 0)
    64             append(sb, prefix, types, suffix);
    65     }
    67     public interface Visitor<R,P> {
    68         R visitSimpleType(SimpleType type, P p);
    69         R visitArrayType(ArrayType type, P p);
    70         R visitMethodType(MethodType type, P p);
    71         R visitClassSigType(ClassSigType type, P p);
    72         R visitClassType(ClassType type, P p);
    73         R visitTypeParamType(TypeParamType type, P p);
    74         R visitWildcardType(WildcardType type, P p);
    75     }
    77     /**
    78      * Represents a type signature with a simple name. The name may be that of a
    79      * primitive type, such "{@code int}, {@code float}, etc
    80      * or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc.
    81      *
    82      * See:
    83      * JVMS 4.3.2
    84      *      BaseType:
    85      *          {@code B}, {@code C}, {@code D}, {@code F}, {@code I},
    86      *          {@code J}, {@code S}, {@code Z};
    87      *      VoidDescriptor:
    88      *          {@code V};
    89      * JVMS 4.3.4
    90      *      TypeVariableSignature:
    91      *          {@code T} Identifier {@code ;}
    92      */
    93     public static class SimpleType extends Type {
    94         public SimpleType(String name) {
    95             this.name = name;
    96         }
    98         public <R, D> R accept(Visitor<R, D> visitor, D data) {
    99             return visitor.visitSimpleType(this, data);
   100         }
   102         public boolean isPrimitiveType() {
   103             return primitiveTypes.contains(name);
   104         }
   105         // where
   106         private static final Set<String> primitiveTypes = new HashSet<String>(Arrays.asList(
   107             "boolean", "byte", "char", "double", "float", "int", "long", "short", "void"));
   109         @Override
   110         public String toString() {
   111             return name;
   112         }
   114         public final String name;
   115     }
   117     /**
   118      * Represents an array type signature.
   119      *
   120      * See:
   121      * JVMS 4.3.4
   122      *      ArrayTypeSignature:
   123      *          {@code [} TypeSignature {@code ]}
   124      */
   125     public static class ArrayType extends Type {
   126         public ArrayType(Type elemType) {
   127             this.elemType = elemType;
   128         }
   130         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   131             return visitor.visitArrayType(this, data);
   132         }
   134         @Override
   135         public String toString() {
   136             return elemType + "[]";
   137         }
   139         public final Type elemType;
   140     }
   142     /**
   143      * Represents a method type signature.
   144      *
   145      * See;
   146      * JVMS 4.3.4
   147      *      MethodTypeSignature:
   148      *          FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType
   149      *              ThrowsSignature*
   150      */
   151     public static class MethodType extends Type {
   152         public MethodType(List<? extends Type> paramTypes, Type resultType) {
   153             this(null, paramTypes, resultType, null);
   154         }
   156         public MethodType(List<? extends TypeParamType> typeParamTypes,
   157                 List<? extends Type> paramTypes,
   158                 Type returnType,
   159                 List<? extends Type> throwsTypes) {
   160             this.typeParamTypes = typeParamTypes;
   161             this.paramTypes = paramTypes;
   162             this.returnType = returnType;
   163             this.throwsTypes = throwsTypes;
   164         }
   166         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   167             return visitor.visitMethodType(this, data);
   168         }
   170         @Override
   171         public String toString() {
   172             StringBuilder sb = new StringBuilder();
   173             appendIfNotEmpty(sb, "<", typeParamTypes, "> ");
   174             sb.append(returnType);
   175             append(sb, " (", paramTypes, ")");
   176             appendIfNotEmpty(sb, " throws ", throwsTypes, "");
   177             return sb.toString();
   178         }
   180         public final List<? extends TypeParamType> typeParamTypes;
   181         public final List<? extends Type> paramTypes;
   182         public final Type returnType;
   183         public final List<? extends Type> throwsTypes;
   184     }
   186     /**
   187      * Represents a class signature. These describe the signature of
   188      * a class that has type arguments.
   189      *
   190      * See:
   191      * JVMS 4.3.4
   192      *      ClassSignature:
   193      *          FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
   194      */
   195     public static class ClassSigType extends Type {
   196         public ClassSigType(List<TypeParamType> typeParamTypes, Type superclassType,
   197                 List<Type> superinterfaceTypes) {
   198             this.typeParamTypes = typeParamTypes;
   199             this.superclassType = superclassType;
   200             this.superinterfaceTypes = superinterfaceTypes;
   201         }
   203         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   204             return visitor.visitClassSigType(this, data);
   205         }
   207         @Override
   208         public String toString() {
   209             StringBuilder sb = new StringBuilder();
   210             appendIfNotEmpty(sb, "<", typeParamTypes, ">");
   211             if (superclassType != null) {
   212                 sb.append(" extends ");
   213                 sb.append(superclassType);
   214             }
   215             appendIfNotEmpty(sb, " implements ", superinterfaceTypes, "");
   216             return sb.toString();
   217         }
   219         public final List<TypeParamType> typeParamTypes;
   220         public final Type superclassType;
   221         public final List<Type> superinterfaceTypes;
   222     }
   224     /**
   225      * Represents a class type signature. This is used to represent a
   226      * reference to a class, such as in a field, parameter, return type, etc.
   227      *
   228      * See:
   229      * JVMS 4.3.4
   230      *      ClassTypeSignature:
   231      *          {@code L} PackageSpecifier_opt SimpleClassTypeSignature
   232      *                  ClassTypeSignatureSuffix* {@code ;}
   233      *      PackageSpecifier:
   234      *          Identifier {@code /} PackageSpecifier*
   235      *      SimpleClassTypeSignature:
   236      *          Identifier TypeArguments_opt }
   237      *      ClassTypeSignatureSuffix:
   238      *          {@code .} SimpleClassTypeSignature
   239      */
   240     public static class ClassType extends Type {
   241         public ClassType(ClassType outerType, String name, List<Type> typeArgs) {
   242             this.outerType = outerType;
   243             this.name = name;
   244             this.typeArgs = typeArgs;
   245         }
   247         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   248             return visitor.visitClassType(this, data);
   249         }
   251         public String getBinaryName() {
   252             if (outerType == null)
   253                 return name;
   254             else
   255                 return (outerType.getBinaryName() + "$" + name);
   256         }
   258         @Override
   259         public String toString() {
   260             StringBuilder sb = new StringBuilder();
   261             if (outerType != null) {
   262                 sb.append(outerType);
   263                 sb.append(".");
   264             }
   265             sb.append(name);
   266             appendIfNotEmpty(sb, "<", typeArgs, ">");
   267             return sb.toString();
   268         }
   270         @Override
   271         public boolean isObject() {
   272             return (outerType == null)
   273                     && name.equals("java/lang/Object")
   274                     && (typeArgs == null || typeArgs.isEmpty());
   275         }
   277         public final ClassType outerType;
   278         public final String name;
   279         public final List<Type> typeArgs;
   280     }
   282     /**
   283      * Represents a FormalTypeParameter. These are used to declare the type
   284      * parameters for generic classes and methods.
   285      *
   286      * See:
   287      * JVMS 4.3.4
   288      *     FormalTypeParameters:
   289      *          {@code <} FormalTypeParameter+ {@code >}
   290      *     FormalTypeParameter:
   291      *          Identifier ClassBound InterfaceBound*
   292      *     ClassBound:
   293      *          {@code :} FieldTypeSignature_opt
   294      *     InterfaceBound:
   295      *          {@code :} FieldTypeSignature
   296      */
   297     public static class TypeParamType extends Type {
   298         public TypeParamType(String name, Type classBound, List<Type> interfaceBounds) {
   299             this.name = name;
   300             this.classBound = classBound;
   301             this.interfaceBounds = interfaceBounds;
   302         }
   304         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   305             return visitor.visitTypeParamType(this, data);
   306         }
   308         @Override
   309         public String toString() {
   310             StringBuilder sb = new StringBuilder();
   311             sb.append(name);
   312             String sep = " extends ";
   313             if (classBound != null) {
   314                 sb.append(sep);
   315                 sb.append(classBound);
   316                 sep = " & ";
   317             }
   318             if (interfaceBounds != null) {
   319                 for (Type bound: interfaceBounds) {
   320                     sb.append(sep);
   321                     sb.append(bound);
   322                     sep = " & ";
   323                 }
   324             }
   325             return sb.toString();
   326         }
   328         public final String name;
   329         public final Type classBound;
   330         public final List<Type> interfaceBounds;
   331     }
   333     /**
   334      * Represents a wildcard type argument.  A type argument that is not a
   335      * wildcard type argument will be represented by a ClassType, ArrayType, etc.
   336      *
   337      * See:
   338      * JVMS 4.3.4
   339      *      TypeArgument:
   340      *          WildcardIndicator_opt FieldTypeSignature
   341      *          {@code *}
   342      *      WildcardIndicator:
   343      *          {@code +}
   344      *          {@code -}
   345      */
   346     public static class WildcardType extends Type {
   347         public enum Kind { UNBOUNDED, EXTENDS, SUPER };
   348         public WildcardType() {
   349             this(Kind.UNBOUNDED, null);
   350         }
   351         public WildcardType(Kind kind, Type boundType) {
   352             this.kind = kind;
   353             this.boundType = boundType;
   354         }
   356         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   357             return visitor.visitWildcardType(this, data);
   358         }
   360         @Override
   361         public String toString() {
   362             switch (kind) {
   363                 case UNBOUNDED:
   364                     return "?";
   365                 case EXTENDS:
   366                     return "? extends " + boundType;
   367                 case SUPER:
   368                     return "? super " + boundType;
   369                 default:
   370                     throw new AssertionError();
   371             }
   372         }
   374         public final Kind kind;
   375         public final Type boundType;
   376     }
   377 }

mercurial