langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Type.java
changeset 30846 2b3f379840f0
parent 25874 83c19f00452c
equal deleted inserted replaced
30845:43ddd58a5a56 30846:2b3f379840f0
       
     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  */
       
    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 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 
       
    45     public boolean isObject() {
       
    46         return false;
       
    47     }
       
    48 
       
    49     public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
       
    50 
       
    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     }
       
    61 
       
    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     }
       
    66 
       
    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     }
       
    76 
       
    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         }
       
    97 
       
    98         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
    99             return visitor.visitSimpleType(this, data);
       
   100         }
       
   101 
       
   102         public boolean isPrimitiveType() {
       
   103             return primitiveTypes.contains(name);
       
   104         }
       
   105         // where
       
   106         private static final Set<String> primitiveTypes = new HashSet<>(Arrays.asList(
       
   107             "boolean", "byte", "char", "double", "float", "int", "long", "short", "void"));
       
   108 
       
   109         @Override
       
   110         public String toString() {
       
   111             return name;
       
   112         }
       
   113 
       
   114         public final String name;
       
   115     }
       
   116 
       
   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         }
       
   129 
       
   130         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   131             return visitor.visitArrayType(this, data);
       
   132         }
       
   133 
       
   134         @Override
       
   135         public String toString() {
       
   136             return elemType + "[]";
       
   137         }
       
   138 
       
   139         public final Type elemType;
       
   140     }
       
   141 
       
   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         }
       
   155 
       
   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         }
       
   165 
       
   166         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   167             return visitor.visitMethodType(this, data);
       
   168         }
       
   169 
       
   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         }
       
   179 
       
   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     }
       
   185 
       
   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         }
       
   202 
       
   203         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   204             return visitor.visitClassSigType(this, data);
       
   205         }
       
   206 
       
   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         }
       
   218 
       
   219         public final List<TypeParamType> typeParamTypes;
       
   220         public final Type superclassType;
       
   221         public final List<Type> superinterfaceTypes;
       
   222     }
       
   223 
       
   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         }
       
   246 
       
   247         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   248             return visitor.visitClassType(this, data);
       
   249         }
       
   250 
       
   251         public String getBinaryName() {
       
   252             if (outerType == null)
       
   253                 return name;
       
   254             else
       
   255                 return (outerType.getBinaryName() + "$" + name);
       
   256         }
       
   257 
       
   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         }
       
   269 
       
   270         @Override
       
   271         public boolean isObject() {
       
   272             return (outerType == null)
       
   273                     && name.equals("java/lang/Object")
       
   274                     && (typeArgs == null || typeArgs.isEmpty());
       
   275         }
       
   276 
       
   277         public final ClassType outerType;
       
   278         public final String name;
       
   279         public final List<Type> typeArgs;
       
   280     }
       
   281 
       
   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         }
       
   303 
       
   304         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   305             return visitor.visitTypeParamType(this, data);
       
   306         }
       
   307 
       
   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         }
       
   327 
       
   328         public final String name;
       
   329         public final Type classBound;
       
   330         public final List<Type> interfaceBounds;
       
   331     }
       
   332 
       
   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 
       
   349         public WildcardType() {
       
   350             this(Kind.UNBOUNDED, null);
       
   351         }
       
   352         public WildcardType(Kind kind, Type boundType) {
       
   353             this.kind = kind;
       
   354             this.boundType = boundType;
       
   355         }
       
   356 
       
   357         public <R, D> R accept(Visitor<R, D> visitor, D data) {
       
   358             return visitor.visitWildcardType(this, data);
       
   359         }
       
   360 
       
   361         @Override
       
   362         public String toString() {
       
   363             switch (kind) {
       
   364                 case UNBOUNDED:
       
   365                     return "?";
       
   366                 case EXTENDS:
       
   367                     return "? extends " + boundType;
       
   368                 case SUPER:
       
   369                     return "? super " + boundType;
       
   370                 default:
       
   371                     throw new AssertionError();
       
   372             }
       
   373         }
       
   374 
       
   375         public final Kind kind;
       
   376         public final Type boundType;
       
   377     }
       
   378 }