src/share/classes/com/sun/tools/javah/LLNI.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

     1 /*
     2  * Copyright (c) 2002, 2010, 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  */
    27 package com.sun.tools.javah;
    29 import java.io.OutputStream;
    30 import java.io.PrintWriter;
    31 import java.util.ArrayList;
    32 import java.util.HashSet;
    33 import java.util.List;
    35 import java.util.Set;
    36 import javax.lang.model.element.Element;
    37 import javax.lang.model.element.ExecutableElement;
    38 import javax.lang.model.element.Modifier;
    39 import javax.lang.model.element.Name;
    40 import javax.lang.model.element.TypeElement;
    41 import javax.lang.model.element.VariableElement;
    42 import javax.lang.model.type.ArrayType;
    43 import javax.lang.model.type.PrimitiveType;
    44 import javax.lang.model.type.TypeKind;
    45 import javax.lang.model.type.TypeMirror;
    46 import javax.lang.model.type.TypeVisitor;
    47 import javax.lang.model.util.ElementFilter;
    48 import javax.lang.model.util.SimpleTypeVisitor7;
    50 /*
    51  * <p><b>This is NOT part of any supported API.
    52  * If you write code that depends on this, you do so at your own
    53  * risk.  This code and its internal interfaces are subject to change
    54  * or deletion without notice.</b></p>
    55  *
    56  * @author  Sucheta Dambalkar(Revised)
    57  */
    58 public class LLNI extends Gen {
    60     protected final char  innerDelim = '$';     /* For inner classes */
    61     protected Set<String>  doneHandleTypes;
    62     List<VariableElement> fields;
    63     List<ExecutableElement> methods;
    64     private boolean       doubleAlign;
    65     private int           padFieldNum = 0;
    67     LLNI(boolean doubleAlign, Util util) {
    68         super(util);
    69         this.doubleAlign = doubleAlign;
    70     }
    72     protected String getIncludes() {
    73         return "";
    74     }
    76     protected void write(OutputStream o, TypeElement clazz) throws Util.Exit {
    77         try {
    78             String cname     = mangleClassName(clazz.getQualifiedName().toString());
    79             PrintWriter pw   = wrapWriter(o);
    80             fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
    81             methods = ElementFilter.methodsIn(clazz.getEnclosedElements());
    82             generateDeclsForClass(pw, clazz, cname);
    83             // FIXME check if errors occurred on the PrintWriter and throw exception if so
    84         } catch (TypeSignature.SignatureException e) {
    85             util.error("llni.sigerror", e.getMessage());
    86         }
    87     }
    89     protected void generateDeclsForClass(PrintWriter pw,
    90             TypeElement clazz, String cname)
    91             throws TypeSignature.SignatureException, Util.Exit {
    92         doneHandleTypes  = new HashSet<String>();
    93         /* The following handle types are predefined in "typedefs.h". Suppress
    94            inclusion in the output by generating them "into the blue" here. */
    95         genHandleType(null, "java.lang.Class");
    96         genHandleType(null, "java.lang.ClassLoader");
    97         genHandleType(null, "java.lang.Object");
    98         genHandleType(null, "java.lang.String");
    99         genHandleType(null, "java.lang.Thread");
   100         genHandleType(null, "java.lang.ThreadGroup");
   101         genHandleType(null, "java.lang.Throwable");
   103         pw.println("/* LLNI Header for class " + clazz.getQualifiedName() + " */" + lineSep);
   104         pw.println("#ifndef _Included_" + cname);
   105         pw.println("#define _Included_" + cname);
   106         pw.println("#include \"typedefs.h\"");
   107         pw.println("#include \"llni.h\"");
   108         pw.println("#include \"jni.h\"" + lineSep);
   110         forwardDecls(pw, clazz);
   111         structSectionForClass(pw, clazz, cname);
   112         methodSectionForClass(pw, clazz, cname);
   113         pw.println("#endif");
   114     }
   116     protected void genHandleType(PrintWriter pw, String clazzname) {
   117         String cname = mangleClassName(clazzname);
   118         if (!doneHandleTypes.contains(cname)) {
   119             doneHandleTypes.add(cname);
   120             if (pw != null) {
   121                 pw.println("#ifndef DEFINED_" + cname);
   122                 pw.println("    #define DEFINED_" + cname);
   123                 pw.println("    GEN_HANDLE_TYPES(" + cname + ");");
   124                 pw.println("#endif" + lineSep);
   125             }
   126         }
   127     }
   129     protected String mangleClassName(String s) {
   130         return s.replace('.', '_')
   131             .replace('/', '_')
   132             .replace(innerDelim, '_');
   133     }
   135     protected void forwardDecls(PrintWriter pw, TypeElement clazz)
   136             throws TypeSignature.SignatureException {
   137         TypeElement object = elems.getTypeElement("java.lang.Object");
   138         if (clazz.equals(object))
   139             return;
   141         genHandleType(pw, clazz.getQualifiedName().toString());
   142         TypeElement superClass = (TypeElement) (types.asElement(clazz.getSuperclass()));
   144         if (superClass != null) {
   145             String superClassName = superClass.getQualifiedName().toString();
   146             forwardDecls(pw, superClass);
   147         }
   149         for (VariableElement field: fields) {
   151             if (!field.getModifiers().contains(Modifier.STATIC)) {
   152                 TypeMirror t = types.erasure(field.asType());
   153                 TypeSignature newTypeSig = new TypeSignature(elems);
   154                 String tname = newTypeSig.qualifiedTypeName(t);
   155                 String sig = newTypeSig.getTypeSignature(tname);
   157                 if (sig.charAt(0) != '[')
   158                     forwardDeclsFromSig(pw, sig);
   159             }
   160         }
   162         for (ExecutableElement method: methods) {
   164             if (method.getModifiers().contains(Modifier.NATIVE)) {
   165                 TypeMirror retType = types.erasure(method.getReturnType());
   166                 String typesig = signature(method);
   167                 TypeSignature newTypeSig = new TypeSignature(elems);
   168                 String sig = newTypeSig.getTypeSignature(typesig, retType);
   170                 if (sig.charAt(0) != '[')
   171                     forwardDeclsFromSig(pw, sig);
   173             }
   174         }
   175     }
   177     protected void forwardDeclsFromSig(PrintWriter pw, String sig) {
   178         int    len = sig.length();
   179         int    i   = sig.charAt(0) == '(' ? 1 : 0;
   181         /* Skip the initial "(". */
   182         while (i < len) {
   183             if (sig.charAt(i) == 'L') {
   184                 int j = i + 1;
   185                 while (sig.charAt(j) != ';') j++;
   186                 genHandleType(pw, sig.substring(i + 1, j));
   187                 i = j + 1;
   188             } else {
   189                 i++;
   190             }
   191         }
   192     }
   194     protected void structSectionForClass(PrintWriter pw,
   195                                          TypeElement jclazz, String cname) {
   197         String jname = jclazz.getQualifiedName().toString();
   199         if (cname.equals("java_lang_Object")) {
   200             pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
   201             pw.println();
   202             return;
   203         }
   204         pw.println("#if !defined(__i386)");
   205         pw.println("#pragma pack(4)");
   206         pw.println("#endif");
   207         pw.println();
   208         pw.println("struct " + cname + " {");
   209         pw.println("    ObjHeader h;");
   210         pw.print(fieldDefs(jclazz, cname));
   212         if (jname.equals("java.lang.Class"))
   213             pw.println("    Class *LLNI_mask(cClass);" +
   214                        "  /* Fake field; don't access (see oobj.h) */");
   215         pw.println("};" + lineSep + lineSep + "#pragma pack()");
   216         pw.println();
   217         return;
   218     }
   220     private static class FieldDefsRes {
   221         public String className;        /* Name of the current class. */
   222         public FieldDefsRes parent;
   223         public String s;
   224         public int byteSize;
   225         public boolean bottomMost;
   226         public boolean printedOne = false;
   228         FieldDefsRes(TypeElement clazz, FieldDefsRes parent, boolean bottomMost) {
   229             this.className = clazz.getQualifiedName().toString();
   230             this.parent = parent;
   231             this.bottomMost = bottomMost;
   232             int byteSize = 0;
   233             if (parent == null) this.s = "";
   234             else this.s = parent.s;
   235         }
   236     }
   238     /* Returns "true" iff added a field. */
   239     private boolean doField(FieldDefsRes res, VariableElement field,
   240                             String cname, boolean padWord) {
   242         String fieldDef = addStructMember(field, cname, padWord);
   243         if (fieldDef != null) {
   244             if (!res.printedOne) { /* add separator */
   245                 if (res.bottomMost) {
   246                     if (res.s.length() != 0)
   247                         res.s = res.s + "    /* local members: */" + lineSep;
   248                 } else {
   249                     res.s = res.s + "    /* inherited members from " +
   250                         res.className + ": */" + lineSep;
   251                 }
   252                 res.printedOne = true;
   253             }
   254             res.s = res.s + fieldDef;
   255             return true;
   256         }
   258         // Otherwise.
   259         return false;
   260     }
   262     private int doTwoWordFields(FieldDefsRes res, TypeElement clazz,
   263                                 int offset, String cname, boolean padWord) {
   264         boolean first = true;
   265         List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
   267         for (VariableElement field: fields) {
   268             TypeKind tk = field.asType().getKind();
   269             boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
   270             if (twoWords && doField(res, field, cname, first && padWord)) {
   271                 offset += 8; first = false;
   272             }
   273         }
   274         return offset;
   275     }
   277     String fieldDefs(TypeElement clazz, String cname) {
   278         FieldDefsRes res = fieldDefs(clazz, cname, true);
   279         return res.s;
   280     }
   282     FieldDefsRes fieldDefs(TypeElement clazz, String cname,
   283                                      boolean bottomMost){
   284         FieldDefsRes res;
   285         int offset;
   286         boolean didTwoWordFields = false;
   288         TypeElement superclazz = (TypeElement) types.asElement(clazz.getSuperclass());
   290         if (superclazz != null) {
   291             String supername = superclazz.getQualifiedName().toString();
   292             res = new FieldDefsRes(clazz,
   293                                    fieldDefs(superclazz, cname, false),
   294                                    bottomMost);
   295             offset = res.parent.byteSize;
   296         } else {
   297             res = new FieldDefsRes(clazz, null, bottomMost);
   298             offset = 0;
   299         }
   301         List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
   303         for (VariableElement field: fields) {
   305             if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
   306                 offset = doTwoWordFields(res, clazz, offset, cname, false);
   307                 didTwoWordFields = true;
   308             }
   310             TypeKind tk = field.asType().getKind();
   311             boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
   313             if (!doubleAlign || !twoWords) {
   314                 if (doField(res, field, cname, false)) offset += 4;
   315             }
   317         }
   319         if (doubleAlign && !didTwoWordFields) {
   320             if ((offset % 8) != 0) offset += 4;
   321             offset = doTwoWordFields(res, clazz, offset, cname, true);
   322         }
   324         res.byteSize = offset;
   325         return res;
   326     }
   328     /* OVERRIDE: This method handles instance fields */
   329     protected String addStructMember(VariableElement member, String cname,
   330                                      boolean padWord) {
   331         String res = null;
   333         if (member.getModifiers().contains(Modifier.STATIC)) {
   334             res = addStaticStructMember(member, cname);
   335             //   if (res == null) /* JNI didn't handle it, print comment. */
   336             //  res = "    /* Inaccessible static: " + member + " */" + lineSep;
   337         } else {
   338             TypeMirror mt = types.erasure(member.asType());
   339             if (padWord) res = "    java_int padWord" + padFieldNum++ + ";" + lineSep;
   340             res = "    " + llniType(mt, false, false) + " " + llniFieldName(member);
   341             if (isLongOrDouble(mt)) res = res + "[2]";
   342             res = res + ";" + lineSep;
   343         }
   344         return res;
   345     }
   347     static private final boolean isWindows =
   348         System.getProperty("os.name").startsWith("Windows");
   350     /*
   351      * This method only handles static final fields.
   352      */
   353     protected String addStaticStructMember(VariableElement field, String cname) {
   354         String res = null;
   355         Object exp = null;
   357         if (!field.getModifiers().contains(Modifier.STATIC))
   358             return res;
   359         if (!field.getModifiers().contains(Modifier.FINAL))
   360             return res;
   362         exp = field.getConstantValue();
   364         if (exp != null) {
   365             /* Constant. */
   367             String     cn     = cname + "_" + field.getSimpleName();
   368             String     suffix = null;
   369             long           val = 0;
   370             /* Can only handle int, long, float, and double fields. */
   371             if (exp instanceof Byte
   372                 || exp instanceof Short
   373                 || exp instanceof Integer) {
   374                 suffix = "L";
   375                 val = ((Number)exp).intValue();
   376             }
   377             else if (exp instanceof Long) {
   378                 // Visual C++ supports the i64 suffix, not LL
   379                 suffix = isWindows ? "i64" : "LL";
   380                 val = ((Long)exp).longValue();
   381             }
   382             else if (exp instanceof Float)  suffix = "f";
   383             else if (exp instanceof Double) suffix = "";
   384             else if (exp instanceof Character) {
   385                 suffix = "L";
   386                 Character ch = (Character) exp;
   387                 val = ((int) ch) & 0xffff;
   388             }
   389             if (suffix != null) {
   390                 // Some compilers will generate a spurious warning
   391                 // for the integer constants for Integer.MIN_VALUE
   392                 // and Long.MIN_VALUE so we handle them specially.
   393                 if ((suffix.equals("L") && (val == Integer.MIN_VALUE)) ||
   394                     (suffix.equals("LL") && (val == Long.MIN_VALUE))) {
   395                     res = "    #undef  " + cn + lineSep
   396                         + "    #define " + cn
   397                         + " (" + (val + 1) + suffix + "-1)" + lineSep;
   398                 } else if (suffix.equals("L") || suffix.endsWith("LL")) {
   399                     res = "    #undef  " + cn + lineSep
   400                         + "    #define " + cn + " " + val + suffix + lineSep;
   401                 } else {
   402                     res = "    #undef  " + cn + lineSep
   403                         + "    #define " + cn + " " + exp + suffix + lineSep;
   404                 }
   405             }
   406         }
   407         return res;
   408     }
   410     protected void methodSectionForClass(PrintWriter pw,
   411             TypeElement clazz, String cname)
   412             throws TypeSignature.SignatureException, Util.Exit {
   413         String methods = methodDecls(clazz, cname);
   415         if (methods.length() != 0) {
   416             pw.println("/* Native method declarations: */" + lineSep);
   417             pw.println("#ifdef __cplusplus");
   418             pw.println("extern \"C\" {");
   419             pw.println("#endif" + lineSep);
   420             pw.println(methods);
   421             pw.println("#ifdef __cplusplus");
   422             pw.println("}");
   423             pw.println("#endif");
   424         }
   425     }
   427     protected String methodDecls(TypeElement clazz, String cname)
   428             throws TypeSignature.SignatureException, Util.Exit {
   430         String res = "";
   431         for (ExecutableElement method: methods) {
   432             if (method.getModifiers().contains(Modifier.NATIVE))
   433                 res = res + methodDecl(method, clazz, cname);
   434         }
   435         return res;
   436     }
   438     protected String methodDecl(ExecutableElement method,
   439                                 TypeElement clazz, String cname)
   440             throws TypeSignature.SignatureException, Util.Exit {
   441         String res = null;
   443         TypeMirror retType = types.erasure(method.getReturnType());
   444         String typesig = signature(method);
   445         TypeSignature newTypeSig = new TypeSignature(elems);
   446         String sig = newTypeSig.getTypeSignature(typesig, retType);
   447         boolean longName = needLongName(method, clazz);
   449         if (sig.charAt(0) != '(')
   450             util.error("invalid.method.signature", sig);
   453         res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
   454             + "(JNIEnv *, " + cRcvrDecl(method, cname);
   455         List<? extends VariableElement> params = method.getParameters();
   456         List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
   457         for (VariableElement p: params){
   458             argTypes.add(types.erasure(p.asType()));
   459         }
   461         /* It would have been nice to include the argument names in the
   462            declaration, but there seems to be a bug in the "BinaryField"
   463            class, causing the getArguments() method to return "null" for
   464            most (non-constructor) methods. */
   465         for (TypeMirror argType: argTypes)
   466             res = res + ", " + jniType(argType);
   467         res = res + ");" + lineSep;
   468         return res;
   469     }
   471     protected final boolean needLongName(ExecutableElement method,
   472                                          TypeElement clazz) {
   473         Name methodName = method.getSimpleName();
   474         for (ExecutableElement memberMethod: methods) {
   475             if ((memberMethod != method) &&
   476                 memberMethod.getModifiers().contains(Modifier.NATIVE) &&
   477                     (methodName.equals(memberMethod.getSimpleName())))
   478                 return true;
   479         }
   480         return false;
   481     }
   483     protected final String jniMethodName(ExecutableElement method, String cname,
   484                                          boolean longName)
   485                 throws TypeSignature.SignatureException {
   486         String res = "Java_" + cname + "_" + method.getSimpleName();
   488         if (longName) {
   489             TypeMirror mType =  types.erasure(method.getReturnType());
   490             List<? extends VariableElement> params = method.getParameters();
   491             List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
   492             for (VariableElement param: params) {
   493                 argTypes.add(types.erasure(param.asType()));
   494             }
   496             res = res + "__";
   497             for (TypeMirror t: argTypes) {
   498                 String tname = t.toString();
   499                 TypeSignature newTypeSig = new TypeSignature(elems);
   500                 String sig = newTypeSig.getTypeSignature(tname);
   501                 res = res + nameToIdentifier(sig);
   502             }
   503         }
   504         return res;
   505     }
   507     // copied from JNI.java
   508     protected final String jniType(TypeMirror t) throws Util.Exit {
   509         TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
   510         TypeElement jClass = elems.getTypeElement("java.lang.Class");
   511         TypeElement jString = elems.getTypeElement("java.lang.String");
   512         Element tclassDoc = types.asElement(t);
   514         switch (t.getKind()) {
   515             case ARRAY: {
   516                 TypeMirror ct = ((ArrayType) t).getComponentType();
   517                 switch (ct.getKind()) {
   518                     case BOOLEAN:  return "jbooleanArray";
   519                     case BYTE:     return "jbyteArray";
   520                     case CHAR:     return "jcharArray";
   521                     case SHORT:    return "jshortArray";
   522                     case INT:      return "jintArray";
   523                     case LONG:     return "jlongArray";
   524                     case FLOAT:    return "jfloatArray";
   525                     case DOUBLE:   return "jdoubleArray";
   526                     case ARRAY:
   527                     case DECLARED: return "jobjectArray";
   528                     default: throw new Error(ct.toString());
   529                 }
   530             }
   532             case VOID:     return "void";
   533             case BOOLEAN:  return "jboolean";
   534             case BYTE:     return "jbyte";
   535             case CHAR:     return "jchar";
   536             case SHORT:    return "jshort";
   537             case INT:      return "jint";
   538             case LONG:     return "jlong";
   539             case FLOAT:    return "jfloat";
   540             case DOUBLE:   return "jdouble";
   542             case DECLARED: {
   543                 if (tclassDoc.equals(jString))
   544                     return "jstring";
   545                 else if (types.isAssignable(t, throwable.asType()))
   546                     return "jthrowable";
   547                 else if (types.isAssignable(t, jClass.asType()))
   548                     return "jclass";
   549                 else
   550                     return "jobject";
   551             }
   552         }
   554         util.bug("jni.unknown.type");
   555         return null; /* dead code. */
   556     }
   558     protected String llniType(TypeMirror t, boolean handleize, boolean longDoubleOK) {
   559         String res = null;
   561         switch (t.getKind()) {
   562             case ARRAY: {
   563                 TypeMirror ct = ((ArrayType) t).getComponentType();
   564                 switch (ct.getKind()) {
   565                     case BOOLEAN:  res = "IArrayOfBoolean"; break;
   566                     case BYTE:     res = "IArrayOfByte";    break;
   567                     case CHAR:     res = "IArrayOfChar";    break;
   568                     case SHORT:    res = "IArrayOfShort";   break;
   569                     case INT:      res = "IArrayOfInt";     break;
   570                     case LONG:     res = "IArrayOfLong";    break;
   571                     case FLOAT:    res = "IArrayOfFloat";   break;
   572                     case DOUBLE:   res = "IArrayOfDouble";  break;
   573                     case ARRAY:
   574                     case DECLARED: res = "IArrayOfRef";     break;
   575                     default: throw new Error(ct.getKind() + " " + ct);
   576                 }
   577                 if (!handleize) res = "DEREFERENCED_" + res;
   578                 break;
   579             }
   581             case VOID:
   582                 res = "void";
   583                 break;
   585             case BOOLEAN:
   586             case BYTE:
   587             case CHAR:
   588             case SHORT:
   589             case INT:
   590                 res = "java_int" ;
   591                 break;
   593             case LONG:
   594                 res = longDoubleOK ? "java_long" : "val32 /* java_long */";
   595                 break;
   597             case FLOAT:
   598                 res =  "java_float";
   599                 break;
   601             case DOUBLE:
   602                 res = longDoubleOK ? "java_double" : "val32 /* java_double */";
   603                 break;
   605             case DECLARED:
   606                 TypeElement e  = (TypeElement) types.asElement(t);
   607                 res = "I" +  mangleClassName(e.getQualifiedName().toString());
   608                 if (!handleize) res = "DEREFERENCED_" + res;
   609                 break;
   611             default:
   612                 throw new Error(t.getKind() + " " + t); // FIXME
   613         }
   615         return res;
   616     }
   618     protected final String cRcvrDecl(Element field, String cname) {
   619         return (field.getModifiers().contains(Modifier.STATIC) ? "jclass" : "jobject");
   620     }
   622     protected String maskName(String s) {
   623         return "LLNI_mask(" + s + ")";
   624     }
   626     protected String llniFieldName(VariableElement field) {
   627         return maskName(field.getSimpleName().toString());
   628     }
   630     protected final boolean isLongOrDouble(TypeMirror t) {
   631         TypeVisitor<Boolean,Void> v = new SimpleTypeVisitor7<Boolean,Void>() {
   632             public Boolean defaultAction(TypeMirror t, Void p){
   633                 return false;
   634             }
   635             public Boolean visitArray(ArrayType t, Void p) {
   636                 return visit(t.getComponentType(), p);
   637             }
   638             public Boolean visitPrimitive(PrimitiveType t, Void p) {
   639                 TypeKind tk = t.getKind();
   640                 return (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
   641             }
   642         };
   643         return v.visit(t, null);
   644     }
   646     /* Do unicode to ansi C identifier conversion.
   647        %%% This may not be right, but should be called more often. */
   648     protected final String nameToIdentifier(String name) {
   649         int len = name.length();
   650         StringBuffer buf = new StringBuffer(len);
   651         for (int i = 0; i < len; i++) {
   652             char c = name.charAt(i);
   653             if (isASCIILetterOrDigit(c))
   654                 buf.append(c);
   655             else if (c == '/')
   656                 buf.append('_');
   657             else if (c == '.')
   658                 buf.append('_');
   659             else if (c == '_')
   660                 buf.append("_1");
   661             else if (c == ';')
   662                 buf.append("_2");
   663             else if (c == '[')
   664                 buf.append("_3");
   665             else
   666                 buf.append("_0" + ((int)c));
   667         }
   668         return new String(buf);
   669     }
   671     protected final boolean isASCIILetterOrDigit(char c) {
   672         if (((c >= 'A') && (c <= 'Z')) ||
   673             ((c >= 'a') && (c <= 'z')) ||
   674             ((c >= '0') && (c <= '9')))
   675             return true;
   676         else
   677             return false;
   678     }
   679 }

mercurial