1 /*
   2  * Copyright (c) 2009, 2015, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package jdk.vm.ci.meta;
  24 
  25 /**
  26  * Represents a method signature provided by the runtime.
  27  *
  28  * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">Method
  29  *      Descriptors</a>
  30  */
  31 public interface Signature {
  32 
  33     /**
  34      * Returns the number of parameters in this signature, adding 1 for a receiver if requested.
  35      *
  36      * @param receiver true if 1 is to be added to the result for a receiver
  37      * @return the number of parameters; + 1 iff {@code receiver == true}
  38      */
  39     int getParameterCount(boolean receiver);
  40 
  41     /**
  42      * Gets the parameter type at the specified position.
  43      *
  44      * @param index the index into the parameters, with {@code 0} indicating the first parameter
  45      * @param accessingClass the context of the type lookup. If non-null, its class loader is used
  46      *            for resolving the type. If {@code null}, then the type returned is either
  47      *            unresolved or a resolved type whose resolution is context free (e.g., a primitive
  48      *            type or a type in a java.* package).
  49      * @return the {@code index}'th parameter type
  50      * @throws LinkageError if {@code accessingClass != null} and resolution fails
  51      *
  52      */
  53     JavaType getParameterType(int index, ResolvedJavaType accessingClass);
  54 
  55     /**
  56      * Gets the parameter kind at the specified position. This is the same as calling
  57      * {@link #getParameterType}. {@link JavaType#getJavaKind getJavaKind}.
  58      *
  59      * @param index the index into the parameters, with {@code 0} indicating the first parameter
  60      * @return the kind of the parameter at the specified position
  61      */
  62     default JavaKind getParameterKind(int index) {
  63         return getParameterType(index, null).getJavaKind();
  64     }
  65 
  66     /**
  67      * Gets the return type of this signature.
  68      *
  69      * @param accessingClass the context of the type lookup. If non-null, its class loader is used
  70      *            for resolving the type. If {@code null}, then the type returned is either
  71      *            unresolved or a resolved type whose resolution is context free (e.g., a primitive
  72      *            type or a type in a java.* package).
  73      * @return the return type
  74      * @throws LinkageError if {@code accessingClass != null} and resolution fails
  75      */
  76     JavaType getReturnType(ResolvedJavaType accessingClass);
  77 
  78     /**
  79      * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}.
  80      * {@link JavaType#getJavaKind getJavaKind}.
  81      */
  82     default JavaKind getReturnKind() {
  83         return getReturnType(null).getJavaKind();
  84     }
  85 
  86     /**
  87      * Gets the
  88      * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
  89      * descriptor</a> corresponding to this signature. For example:
  90      *
  91      * <pre>
  92      * (ILjava/lang/String;D)V
  93      * </pre>
  94      *
  95      * @return the signature as a string
  96      */
  97     default String toMethodDescriptor() {
  98         StringBuilder sb = new StringBuilder("(");
  99         for (int i = 0; i < getParameterCount(false); ++i) {
 100             sb.append(getParameterType(i, null).getName());
 101         }
 102         sb.append(')').append(getReturnType(null).getName());
 103         return sb.toString();
 104     }
 105 
 106     default JavaType[] toParameterTypes(JavaType receiverType) {
 107         int args = getParameterCount(false);
 108         JavaType[] result;
 109         int i = 0;
 110         if (receiverType != null) {
 111             result = new JavaType[args + 1];
 112             result[0] = receiverType;
 113             i = 1;
 114         } else {
 115             result = new JavaType[args];
 116         }
 117         for (int j = 0; j < args; j++) {
 118             result[i + j] = getParameterType(j, null);
 119         }
 120         return result;
 121     }
 122 
 123     default JavaKind[] toParameterKinds(boolean receiver) {
 124         int args = getParameterCount(false);
 125         JavaKind[] result;
 126         int i = 0;
 127         if (receiver) {
 128             result = new JavaKind[args + 1];
 129             result[0] = JavaKind.Object;
 130             i = 1;
 131         } else {
 132             result = new JavaKind[args];
 133         }
 134         for (int j = 0; j < args; j++) {
 135             result[i + j] = getParameterKind(j);
 136         }
 137         return result;
 138     }
 139 }