001/* 002 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.meta; 024 025/** 026 * Represents a method signature provided by the runtime. 027 * 028 * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">Method 029 * Descriptors</a> 030 */ 031public interface Signature { 032 033 /** 034 * Returns the number of parameters in this signature, adding 1 for a receiver if requested. 035 * 036 * @param receiver true if 1 is to be added to the result for a receiver 037 * @return the number of parameters; + 1 iff {@code receiver == true} 038 */ 039 int getParameterCount(boolean receiver); 040 041 /** 042 * Gets the parameter type at the specified position. 043 * 044 * @param index the index into the parameters, with {@code 0} indicating the first parameter 045 * @param accessingClass the context of the type lookup. If non-null, its class loader is used 046 * for resolving the type. If {@code null}, then the type returned is either 047 * unresolved or a resolved type whose resolution is context free (e.g., a primitive 048 * type or a type in a java.* package). 049 * @return the {@code index}'th parameter type 050 * @throws LinkageError if {@code accessingClass != null} and resolution fails 051 * 052 */ 053 JavaType getParameterType(int index, ResolvedJavaType accessingClass); 054 055 /** 056 * Gets the parameter kind at the specified position. This is the same as calling 057 * {@link #getParameterType}. {@link JavaType#getKind getKind}. 058 * 059 * @param index the index into the parameters, with {@code 0} indicating the first parameter 060 * @return the kind of the parameter at the specified position 061 */ 062 default Kind getParameterKind(int index) { 063 return getParameterType(index, null).getKind(); 064 } 065 066 /** 067 * Gets the return type of this signature. 068 * 069 * @param accessingClass the context of the type lookup. If non-null, its class loader is used 070 * for resolving the type. If {@code null}, then the type returned is either 071 * unresolved or a resolved type whose resolution is context free (e.g., a primitive 072 * type or a type in a java.* package). 073 * @return the return type 074 * @throws LinkageError if {@code accessingClass != null} and resolution fails 075 */ 076 JavaType getReturnType(ResolvedJavaType accessingClass); 077 078 /** 079 * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}. 080 * {@link JavaType#getKind getKind}. 081 */ 082 default Kind getReturnKind() { 083 return getReturnType(null).getKind(); 084 } 085 086 /** 087 * Gets the <a 088 * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method 089 * descriptor</a> corresponding to this signature. For example: 090 * 091 * <pre> 092 * (ILjava/lang/String;D)V 093 * </pre> 094 * 095 * @return the signature as a string 096 */ 097 default String toMethodDescriptor() { 098 StringBuilder sb = new StringBuilder("("); 099 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 Kind[] toParameterKinds(boolean receiver) { 124 int args = getParameterCount(false); 125 Kind[] result; 126 int i = 0; 127 if (receiver) { 128 result = new Kind[args + 1]; 129 result[0] = Kind.Object; 130 i = 1; 131 } else { 132 result = new Kind[args]; 133 } 134 for (int j = 0; j < args; j++) { 135 result[i + j] = getParameterKind(j); 136 } 137 return result; 138 } 139}