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