src/share/classes/com/sun/tools/javah/TypeSignature.java

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 712
a1d31ab7b525
child 1054
111bbf1ad913
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

duke@1 1 /*
ohair@798 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26
duke@1 27 package com.sun.tools.javah;
duke@1 28
duke@1 29 import java.util.*;
jjg@416 30 import javax.lang.model.element.Name;
jjg@416 31 import javax.lang.model.element.TypeElement;
jjg@416 32 import javax.lang.model.type.ArrayType;
jjg@416 33 import javax.lang.model.type.DeclaredType;
jjg@416 34 import javax.lang.model.type.NoType;
jjg@416 35 import javax.lang.model.type.PrimitiveType;
jjg@416 36 import javax.lang.model.type.TypeKind;
jjg@416 37 import javax.lang.model.type.TypeMirror;
jjg@416 38 import javax.lang.model.type.TypeVariable;
jjg@416 39 import javax.lang.model.type.TypeVisitor;
jjg@416 40 import javax.lang.model.util.Elements;
darcy@575 41 import javax.lang.model.util.SimpleTypeVisitor7;
duke@1 42
duke@1 43 /**
duke@1 44 * Returns internal type signature.
duke@1 45 *
jjg@581 46 * <p><b>This is NOT part of any supported API.
jjg@416 47 * If you write code that depends on this, you do so at your own
jjg@416 48 * risk. This code and its internal interfaces are subject to change
jjg@416 49 * or deletion without notice.</b></p>
jjg@416 50 *
duke@1 51 * @author Sucheta Dambalkar
duke@1 52 */
duke@1 53
jjg@712 54 public class TypeSignature {
jjg@712 55 static class SignatureException extends Exception {
jjg@712 56 private static final long serialVersionUID = 1L;
jjg@712 57 SignatureException(String reason) {
jjg@712 58 super(reason);
jjg@712 59 }
jjg@712 60 }
duke@1 61
jjg@416 62 Elements elems;
duke@1 63
duke@1 64 /* Signature Characters */
duke@1 65
duke@1 66 private static final String SIG_VOID = "V";
duke@1 67 private static final String SIG_BOOLEAN = "Z";
duke@1 68 private static final String SIG_BYTE = "B";
duke@1 69 private static final String SIG_CHAR = "C";
duke@1 70 private static final String SIG_SHORT = "S";
duke@1 71 private static final String SIG_INT = "I";
duke@1 72 private static final String SIG_LONG = "J";
duke@1 73 private static final String SIG_FLOAT = "F";
duke@1 74 private static final String SIG_DOUBLE = "D";
duke@1 75 private static final String SIG_ARRAY = "[";
duke@1 76 private static final String SIG_CLASS = "L";
duke@1 77
duke@1 78
duke@1 79
jjg@416 80 public TypeSignature(Elements elems){
jjg@416 81 this.elems = elems;
duke@1 82 }
duke@1 83
duke@1 84 /*
duke@1 85 * Returns the type signature of a field according to JVM specs
duke@1 86 */
jjg@712 87 public String getTypeSignature(String javasignature) throws SignatureException {
duke@1 88 return getParamJVMSignature(javasignature);
duke@1 89 }
duke@1 90
duke@1 91 /*
duke@1 92 * Returns the type signature of a method according to JVM specs
duke@1 93 */
jjg@712 94 public String getTypeSignature(String javasignature, TypeMirror returnType)
jjg@712 95 throws SignatureException {
duke@1 96 String signature = null; //Java type signature.
duke@1 97 String typeSignature = null; //Internal type signature.
jjg@416 98 List<String> params = new ArrayList<String>(); //List of parameters.
duke@1 99 String paramsig = null; //Java parameter signature.
duke@1 100 String paramJVMSig = null; //Internal parameter signature.
duke@1 101 String returnSig = null; //Java return type signature.
duke@1 102 String returnJVMType = null; //Internal return type signature.
jjg@416 103 int dimensions = 0; //Array dimension.
duke@1 104
duke@1 105 int startIndex = -1;
duke@1 106 int endIndex = -1;
duke@1 107 StringTokenizer st = null;
duke@1 108 int i = 0;
duke@1 109
duke@1 110 // Gets the actual java signature without parentheses.
jjg@416 111 if (javasignature != null) {
duke@1 112 startIndex = javasignature.indexOf("(");
duke@1 113 endIndex = javasignature.indexOf(")");
duke@1 114 }
duke@1 115
jjg@416 116 if (((startIndex != -1) && (endIndex != -1))
jjg@416 117 &&(startIndex+1 < javasignature.length())
jjg@416 118 &&(endIndex < javasignature.length())) {
duke@1 119 signature = javasignature.substring(startIndex+1, endIndex);
duke@1 120 }
duke@1 121
duke@1 122 // Separates parameters.
jjg@416 123 if (signature != null) {
jjg@416 124 if (signature.indexOf(",") != -1) {
duke@1 125 st = new StringTokenizer(signature, ",");
jjg@416 126 if (st != null) {
duke@1 127 while (st.hasMoreTokens()) {
duke@1 128 params.add(st.nextToken());
duke@1 129 }
duke@1 130 }
jjg@416 131 } else {
duke@1 132 params.add(signature);
duke@1 133 }
duke@1 134 }
duke@1 135
duke@1 136 /* JVM type signature. */
duke@1 137 typeSignature = "(";
duke@1 138
duke@1 139 // Gets indivisual internal parameter signature.
jjg@416 140 while (params.isEmpty() != true) {
jjg@416 141 paramsig = params.remove(i).trim();
duke@1 142 paramJVMSig = getParamJVMSignature(paramsig);
jjg@416 143 if (paramJVMSig != null) {
duke@1 144 typeSignature += paramJVMSig;
duke@1 145 }
duke@1 146 }
duke@1 147
duke@1 148 typeSignature += ")";
duke@1 149
duke@1 150 // Get internal return type signature.
duke@1 151
duke@1 152 returnJVMType = "";
jjg@416 153 if (returnType != null) {
jjg@416 154 dimensions = dimensions(returnType);
duke@1 155 }
duke@1 156
jjg@416 157 //Gets array dimension of return type.
jjg@416 158 while (dimensions-- > 0) {
jjg@416 159 returnJVMType += "[";
duke@1 160 }
jjg@416 161 if (returnType != null) {
jjg@416 162 returnSig = qualifiedTypeName(returnType);
duke@1 163 returnJVMType += getComponentType(returnSig);
jjg@416 164 } else {
duke@1 165 System.out.println("Invalid return type.");
duke@1 166 }
duke@1 167
duke@1 168 typeSignature += returnJVMType;
jjg@416 169
duke@1 170 return typeSignature;
duke@1 171 }
duke@1 172
duke@1 173 /*
duke@1 174 * Returns internal signature of a parameter.
duke@1 175 */
jjg@712 176 private String getParamJVMSignature(String paramsig) throws SignatureException {
duke@1 177 String paramJVMSig = "";
duke@1 178 String componentType ="";
duke@1 179
duke@1 180 if(paramsig != null){
duke@1 181
duke@1 182 if(paramsig.indexOf("[]") != -1) {
duke@1 183 // Gets array dimension.
duke@1 184 int endindex = paramsig.indexOf("[]");
duke@1 185 componentType = paramsig.substring(0, endindex);
duke@1 186 String dimensionString = paramsig.substring(endindex);
duke@1 187 if(dimensionString != null){
duke@1 188 while(dimensionString.indexOf("[]") != -1){
duke@1 189 paramJVMSig += "[";
duke@1 190 int beginindex = dimensionString.indexOf("]") + 1;
duke@1 191 if(beginindex < dimensionString.length()){
duke@1 192 dimensionString = dimensionString.substring(beginindex);
duke@1 193 }else
duke@1 194 dimensionString = "";
duke@1 195 }
duke@1 196 }
duke@1 197 } else componentType = paramsig;
duke@1 198
duke@1 199 paramJVMSig += getComponentType(componentType);
duke@1 200 }
duke@1 201 return paramJVMSig;
duke@1 202 }
duke@1 203
duke@1 204 /*
duke@1 205 * Returns internal signature of a component.
duke@1 206 */
jjg@712 207 private String getComponentType(String componentType) throws SignatureException {
duke@1 208
duke@1 209 String JVMSig = "";
duke@1 210
duke@1 211 if(componentType != null){
duke@1 212 if(componentType.equals("void")) JVMSig += SIG_VOID ;
duke@1 213 else if(componentType.equals("boolean")) JVMSig += SIG_BOOLEAN ;
duke@1 214 else if(componentType.equals("byte")) JVMSig += SIG_BYTE ;
duke@1 215 else if(componentType.equals("char")) JVMSig += SIG_CHAR ;
duke@1 216 else if(componentType.equals("short")) JVMSig += SIG_SHORT ;
duke@1 217 else if(componentType.equals("int")) JVMSig += SIG_INT ;
duke@1 218 else if(componentType.equals("long")) JVMSig += SIG_LONG ;
duke@1 219 else if(componentType.equals("float")) JVMSig += SIG_FLOAT ;
duke@1 220 else if(componentType.equals("double")) JVMSig += SIG_DOUBLE ;
duke@1 221 else {
duke@1 222 if(!componentType.equals("")){
jjg@416 223 TypeElement classNameDoc = elems.getTypeElement(componentType);
duke@1 224
duke@1 225 if(classNameDoc == null){
jjg@712 226 throw new SignatureException(componentType);
duke@1 227 }else {
jjg@416 228 String classname = classNameDoc.getQualifiedName().toString();
duke@1 229 String newclassname = classname.replace('.', '/');
duke@1 230 JVMSig += "L";
duke@1 231 JVMSig += newclassname;
duke@1 232 JVMSig += ";";
duke@1 233 }
duke@1 234 }
duke@1 235 }
duke@1 236 }
duke@1 237 return JVMSig;
duke@1 238 }
jjg@416 239
jjg@416 240 int dimensions(TypeMirror t) {
jjg@416 241 if (t.getKind() != TypeKind.ARRAY)
jjg@416 242 return 0;
jjg@416 243 return 1 + dimensions(((ArrayType) t).getComponentType());
jjg@416 244 }
jjg@416 245
jjg@416 246
jjg@416 247 String qualifiedTypeName(TypeMirror type) {
darcy@575 248 TypeVisitor<Name, Void> v = new SimpleTypeVisitor7<Name, Void>() {
jjg@416 249 @Override
jjg@416 250 public Name visitArray(ArrayType t, Void p) {
jjg@416 251 return t.getComponentType().accept(this, p);
jjg@416 252 }
jjg@416 253
jjg@416 254 @Override
jjg@416 255 public Name visitDeclared(DeclaredType t, Void p) {
jjg@416 256 return ((TypeElement) t.asElement()).getQualifiedName();
jjg@416 257 }
jjg@416 258
jjg@416 259 @Override
jjg@416 260 public Name visitPrimitive(PrimitiveType t, Void p) {
jjg@416 261 return elems.getName(t.toString());
jjg@416 262 }
jjg@416 263
jjg@416 264 @Override
jjg@416 265 public Name visitNoType(NoType t, Void p) {
jjg@416 266 if (t.getKind() == TypeKind.VOID)
jjg@416 267 return elems.getName("void");
jjg@416 268 return defaultAction(t, p);
jjg@416 269 }
jjg@416 270
jjg@416 271 @Override
jjg@416 272 public Name visitTypeVariable(TypeVariable t, Void p) {
jjg@416 273 return t.getUpperBound().accept(this, p);
jjg@416 274 }
jjg@416 275 };
jjg@416 276 return v.visit(type).toString();
jjg@416 277 }
duke@1 278 }

mercurial