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

Wed, 02 Mar 2011 21:13:55 -0800

author
jjg
date
Wed, 02 Mar 2011 21:13:55 -0800
changeset 904
4baab658f357
parent 581
f2fdd52e4e87
child 953
c55928005af4
permissions
-rw-r--r--

6639645: Modeling type implementing missing interfaces
Reviewed-by: darcy, mcimadamore

     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 }

mercurial