src/jdk.compiler/share/classes/com/sun/tools/javah/TypeSignature.java
branchhttp-client-branch
changeset 55982 b6ff245c0db6
parent 55981 907bddce488c
parent 48332 651a95f30dfb
child 55983 e4a1f0c9d4c6
equal deleted inserted replaced
55981:907bddce488c 55982:b6ff245c0db6
     1 /*
       
     2  * Copyright (c) 2002, 2014, 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 
       
    26 package com.sun.tools.javah;
       
    27 
       
    28 import java.util.*;
       
    29 import javax.lang.model.element.Name;
       
    30 import javax.lang.model.element.TypeElement;
       
    31 import javax.lang.model.type.ArrayType;
       
    32 import javax.lang.model.type.DeclaredType;
       
    33 import javax.lang.model.type.NoType;
       
    34 import javax.lang.model.type.PrimitiveType;
       
    35 import javax.lang.model.type.TypeKind;
       
    36 import javax.lang.model.type.TypeMirror;
       
    37 import javax.lang.model.type.TypeVariable;
       
    38 import javax.lang.model.type.TypeVisitor;
       
    39 import javax.lang.model.util.Elements;
       
    40 import javax.lang.model.util.SimpleTypeVisitor9;
       
    41 
       
    42 import com.sun.tools.javac.util.DefinedBy;
       
    43 import com.sun.tools.javac.util.DefinedBy.Api;
       
    44 
       
    45 /**
       
    46  * Returns internal type signature.
       
    47  *
       
    48  * <p><b>This is NOT part of any supported API.
       
    49  * If you write code that depends on this, you do so at your own
       
    50  * risk.  This code and its internal interfaces are subject to change
       
    51  * or deletion without notice.</b></p>
       
    52  *
       
    53  * @author Sucheta Dambalkar
       
    54  */
       
    55 
       
    56 public class TypeSignature {
       
    57     static class SignatureException extends Exception {
       
    58         private static final long serialVersionUID = 1L;
       
    59         SignatureException(String reason) {
       
    60             super(reason);
       
    61         }
       
    62     }
       
    63 
       
    64     Elements elems;
       
    65 
       
    66     /* Signature Characters */
       
    67 
       
    68     private static final String SIG_VOID                   = "V";
       
    69     private static final String SIG_BOOLEAN                = "Z";
       
    70     private static final String SIG_BYTE                   = "B";
       
    71     private static final String SIG_CHAR                   = "C";
       
    72     private static final String SIG_SHORT                  = "S";
       
    73     private static final String SIG_INT                    = "I";
       
    74     private static final String SIG_LONG                   = "J";
       
    75     private static final String SIG_FLOAT                  = "F";
       
    76     private static final String SIG_DOUBLE                 = "D";
       
    77     private static final String SIG_ARRAY                  = "[";
       
    78     private static final String SIG_CLASS                  = "L";
       
    79 
       
    80 
       
    81 
       
    82     public TypeSignature(Elements elems){
       
    83         this.elems = elems;
       
    84     }
       
    85 
       
    86     /*
       
    87      * Returns the type signature of a field according to JVM specs
       
    88      */
       
    89     public String getTypeSignature(String javasignature) throws SignatureException {
       
    90         return getParamJVMSignature(javasignature);
       
    91     }
       
    92 
       
    93     /*
       
    94      * Returns the type signature of a method according to JVM specs
       
    95      */
       
    96     public String getTypeSignature(String javasignature, TypeMirror returnType)
       
    97             throws SignatureException {
       
    98         String signature = null; //Java type signature.
       
    99         String typeSignature = null; //Internal type signature.
       
   100         List<String> params = new ArrayList<>(); //List of parameters.
       
   101         String paramsig = null; //Java parameter signature.
       
   102         String paramJVMSig = null; //Internal parameter signature.
       
   103         String returnSig = null; //Java return type signature.
       
   104         String returnJVMType = null; //Internal return type signature.
       
   105         int dimensions = 0; //Array dimension.
       
   106 
       
   107         int startIndex = -1;
       
   108         int endIndex = -1;
       
   109         StringTokenizer st = null;
       
   110         int i = 0;
       
   111 
       
   112         // Gets the actual java signature without parentheses.
       
   113         if (javasignature != null) {
       
   114             startIndex = javasignature.indexOf("(");
       
   115             endIndex = javasignature.indexOf(")");
       
   116         }
       
   117 
       
   118         if (((startIndex != -1) && (endIndex != -1))
       
   119             &&(startIndex+1 < javasignature.length())
       
   120             &&(endIndex < javasignature.length())) {
       
   121             signature = javasignature.substring(startIndex+1, endIndex);
       
   122         }
       
   123 
       
   124         // Separates parameters.
       
   125         if (signature != null) {
       
   126             if (signature.contains(",")) {
       
   127                 st = new StringTokenizer(signature, ",");
       
   128                 if (st != null) {
       
   129                     while (st.hasMoreTokens()) {
       
   130                         params.add(st.nextToken());
       
   131                     }
       
   132                 }
       
   133             } else {
       
   134                 params.add(signature);
       
   135             }
       
   136         }
       
   137 
       
   138         /* JVM type signature. */
       
   139         typeSignature = "(";
       
   140 
       
   141         // Gets indivisual internal parameter signature.
       
   142         while (params.isEmpty() != true) {
       
   143             paramsig = params.remove(i).trim();
       
   144             paramJVMSig  = getParamJVMSignature(paramsig);
       
   145             if (paramJVMSig != null) {
       
   146                 typeSignature += paramJVMSig;
       
   147             }
       
   148         }
       
   149 
       
   150         typeSignature += ")";
       
   151 
       
   152         // Get internal return type signature.
       
   153 
       
   154         returnJVMType = "";
       
   155         if (returnType != null) {
       
   156             dimensions = dimensions(returnType);
       
   157         }
       
   158 
       
   159         //Gets array dimension of return type.
       
   160         while (dimensions-- > 0) {
       
   161             returnJVMType += "[";
       
   162         }
       
   163         if (returnType != null) {
       
   164             returnSig = qualifiedTypeName(returnType);
       
   165             returnJVMType += getComponentType(returnSig);
       
   166         } else {
       
   167             System.out.println("Invalid return type.");
       
   168         }
       
   169 
       
   170         typeSignature += returnJVMType;
       
   171 
       
   172         return typeSignature;
       
   173     }
       
   174 
       
   175     /*
       
   176      * Returns internal signature of a parameter.
       
   177      */
       
   178     private String getParamJVMSignature(String paramsig) throws SignatureException {
       
   179         String paramJVMSig = "";
       
   180         String componentType ="";
       
   181 
       
   182         if(paramsig != null){
       
   183 
       
   184             if(paramsig.contains("[]")) {
       
   185                 // Gets array dimension.
       
   186                 int endindex = paramsig.indexOf("[]");
       
   187                 componentType = paramsig.substring(0, endindex);
       
   188                 String dimensionString =  paramsig.substring(endindex);
       
   189                 if(dimensionString != null){
       
   190                     while(dimensionString.contains("[]")){
       
   191                         paramJVMSig += "[";
       
   192                         int beginindex = dimensionString.indexOf("]") + 1;
       
   193                         if(beginindex < dimensionString.length()){
       
   194                             dimensionString = dimensionString.substring(beginindex);
       
   195                         }else
       
   196                             dimensionString = "";
       
   197                     }
       
   198                 }
       
   199             } else componentType = paramsig;
       
   200 
       
   201             paramJVMSig += getComponentType(componentType);
       
   202         }
       
   203         return paramJVMSig;
       
   204     }
       
   205 
       
   206     /*
       
   207      * Returns internal signature of a component.
       
   208      */
       
   209     private String getComponentType(String componentType) throws SignatureException {
       
   210 
       
   211         String JVMSig = "";
       
   212 
       
   213         if(componentType != null){
       
   214             switch (componentType) {
       
   215                 case "void":    JVMSig += SIG_VOID;    break;
       
   216                 case "boolean": JVMSig += SIG_BOOLEAN; break;
       
   217                 case "byte":    JVMSig += SIG_BYTE;    break;
       
   218                 case "char":    JVMSig += SIG_CHAR;    break;
       
   219                 case "short":   JVMSig += SIG_SHORT;   break;
       
   220                 case "int":     JVMSig += SIG_INT;     break;
       
   221                 case "long":    JVMSig += SIG_LONG;    break;
       
   222                 case "float":   JVMSig += SIG_FLOAT;   break;
       
   223                 case "double":  JVMSig += SIG_DOUBLE;  break;
       
   224                 default:
       
   225                     if (!componentType.equals("")) {
       
   226                         TypeElement classNameDoc = elems.getTypeElement(componentType);
       
   227 
       
   228                         if (classNameDoc == null) {
       
   229                             throw new SignatureException(componentType);
       
   230                         }
       
   231                         else {
       
   232                             String classname = classNameDoc.getQualifiedName().toString();
       
   233                             String newclassname = classname.replace('.', '/');
       
   234                             JVMSig += "L";
       
   235                             JVMSig += newclassname;
       
   236                             JVMSig += ";";
       
   237                         }
       
   238                     }
       
   239                     break;
       
   240             }
       
   241         }
       
   242         return JVMSig;
       
   243     }
       
   244 
       
   245     int dimensions(TypeMirror t) {
       
   246         if (t.getKind() != TypeKind.ARRAY)
       
   247             return 0;
       
   248         return 1 + dimensions(((ArrayType) t).getComponentType());
       
   249     }
       
   250 
       
   251 
       
   252     String qualifiedTypeName(TypeMirror type) {
       
   253         TypeVisitor<Name, Void> v = new SimpleTypeVisitor9<Name, Void>() {
       
   254             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   255             public Name visitArray(ArrayType t, Void p) {
       
   256                 return t.getComponentType().accept(this, p);
       
   257             }
       
   258 
       
   259             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   260             public Name visitDeclared(DeclaredType t, Void p) {
       
   261                 return ((TypeElement) t.asElement()).getQualifiedName();
       
   262             }
       
   263 
       
   264             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   265             public Name visitPrimitive(PrimitiveType t, Void p) {
       
   266                 return elems.getName(t.toString());
       
   267             }
       
   268 
       
   269             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   270             public Name visitNoType(NoType t, Void p) {
       
   271                 if (t.getKind() == TypeKind.VOID)
       
   272                     return elems.getName("void");
       
   273                 return defaultAction(t, p);
       
   274             }
       
   275 
       
   276             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   277             public Name visitTypeVariable(TypeVariable t, Void p) {
       
   278                 return t.getUpperBound().accept(this, p);
       
   279             }
       
   280         };
       
   281         return v.visit(type).toString();
       
   282     }
       
   283 }