1 /*
   2  * Copyright (c) 2018, 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 package java.lang.invoke;
  26 
  27 import java.util.List;
  28 
  29 /**
  30  * An entity that has a field or method type descriptor
  31  *
  32  * @jvms 4.3.2 Field Descriptors
  33  * @jvms 4.3.3 Method Descriptors
  34  *
  35  * @since 12
  36  */
  37 public interface TypeDescriptor {
  38     /**
  39      * Return the type descriptor string for this instance, which must be either
  40      * a field type descriptor (JVMS 4.3.2) or method type descriptor (JVMS 4.3.3).
  41      *
  42      * @return the type descriptor
  43      * @jvms 4.3.2 Field Descriptors
  44      * @jvms 4.3.3 Method Descriptors
  45      */
  46     String descriptorString();
  47 
  48 
  49     /**
  50      * An entity that has a field type descriptor
  51      *
  52      * @param <F> the class implementing {@linkplain TypeDescriptor.OfField}
  53      * @jvms 4.3.2 Field Descriptors
  54      * @since 12
  55      */
  56     interface OfField<F extends TypeDescriptor.OfField<F>> extends TypeDescriptor {
  57         /**
  58          * Does this field descriptor describe an array type?
  59          * @return whether this field descriptor describes an array type
  60          */
  61         boolean isArray();
  62 
  63         /**
  64          * Does this field descriptor describe a primitive type (including void.)
  65          *
  66          * @return whether this field descriptor describes a primitive type
  67          */
  68         boolean isPrimitive();
  69 
  70         /**
  71          * If this field descriptor describes an array type, return
  72          * a descriptor for its component type, otherwise return {@code null}.
  73          * @return the component type, or {@code null} if this field descriptor does
  74          * not describe an array type
  75          */
  76         F componentType();
  77 
  78         /**
  79          * Return a descriptor for the array type whose component type is described by this
  80          * descriptor
  81          * @return the descriptor for the array type
  82          */
  83         F arrayType();
  84     }
  85 
  86 
  87     /**
  88      * An entity that has a method type descriptor
  89      *
  90      * @param <F> the type representing field type descriptors
  91      * @param <M> the class implementing {@linkplain TypeDescriptor.OfMethod}
  92      * @jvms 4.3.2 Field Descriptors
  93      * @jvms 4.3.3 Method Descriptors
  94      * @since 12
  95      */
  96     interface OfMethod<F extends TypeDescriptor.OfField<F>, M extends TypeDescriptor.OfMethod<F, M>>
  97             extends TypeDescriptor {
  98 
  99         /**
 100          * Return the number of parameters in the method type
 101          * @return the number of parameters
 102          */
 103         int parameterCount();
 104 
 105         /**
 106          * Return a field descriptor describing the requested parameter of the method type
 107          * described by this descriptor
 108          * @param i the index of the parameter
 109          * @return a field descriptor for the requested parameter type
 110          * @throws IndexOutOfBoundsException if the index is outside the half-open
 111          * range {[0, parameterCount)}
 112          */
 113         F parameterType(int i);
 114 
 115         /**
 116          * Return a field descriptor describing the return type of the method type described
 117          * by this descriptor
 118          * @return a field descriptor for the return type
 119          */
 120         F returnType();
 121 
 122         /**
 123          * Return an array of field descriptors for the parameter types of the method type
 124          * described by this descriptor
 125          * @return field descriptors for the parameter types
 126          */
 127         F[] parameterArray();
 128 
 129         /**
 130          * Return an immutable list of field descriptors for the parameter types of the method type
 131          * described by this descriptor
 132          * @return field descriptors for the parameter types
 133          */
 134         List<F> parameterList();
 135 
 136         /**
 137          * Return a method descriptor that is identical to this one, except that the return
 138          * type has been changed to the specified type
 139          *
 140          * @param newReturn a field descriptor for the new return type
 141          * @throws NullPointerException if any argument is {@code null}
 142          * @return the new method descriptor
 143          */
 144         M changeReturnType(F newReturn);
 145 
 146         /**
 147          * Return a method descriptor that is identical to this one,
 148          * except that a single parameter type has been changed to the specified type.
 149          *
 150          * @param index the index of the parameter to change
 151          * @param paramType a field descriptor describing the new parameter type
 152          * @return the new method descriptor
 153          * @throws NullPointerException if any argument is {@code null}
 154          * @throws IndexOutOfBoundsException if the index is outside the half-open
 155          * range {[0, parameterCount)}
 156          */
 157         M changeParameterType(int index, F paramType);
 158 
 159         /**
 160          * Return a method descriptor that is identical to this one,
 161          * except that a range of parameter types have been removed.
 162          *
 163          * @param start the index of the first parameter to remove
 164          * @param end the index after the last parameter to remove
 165          * @return the new method descriptor
 166          *
 167          * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
 168          * range {@code [0, parameterCount)}, or {@code end} is outside the closed range
 169          * {@code [0, parameterCount]}, or if {@code start > end}
 170          */
 171         M dropParameterTypes(int start, int end);
 172 
 173         /**
 174          * Return a method descriptor that is identical to this one,
 175          * except that a range of additional parameter types have been inserted.
 176          *
 177          * @param pos the index at which to insert the first inserted parameter
 178          * @param paramTypes field descriptors describing the new parameter types
 179          *                   to insert
 180          * @return the new method descriptor
 181          * @throws NullPointerException if any argument is {@code null}
 182          * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
 183          * range {[0, parameterCount]}
 184          */
 185         @SuppressWarnings("unchecked")
 186         M insertParameterTypes(int pos, F... paramTypes);
 187     }
 188 }