Mon, 21 Jan 2013 20:15:16 +0000
8005851: Remove support for synchronized interface methods
Summary: Synchronized default methods are no longer supported
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1999, 2012, 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 */
26 package com.sun.tools.javac.jvm;
28 import java.io.IOException;
29 import java.io.Writer;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Stack;
33 import java.util.StringTokenizer;
35 import javax.lang.model.element.Element;
36 import javax.lang.model.element.ExecutableElement;
37 import javax.lang.model.element.Modifier;
38 import javax.lang.model.element.Name;
39 import javax.lang.model.element.TypeElement;
40 import javax.lang.model.element.VariableElement;
41 import javax.lang.model.type.ArrayType;
42 import javax.lang.model.type.DeclaredType;
43 import javax.lang.model.type.NoType;
44 import javax.lang.model.type.PrimitiveType;
45 import javax.lang.model.type.TypeKind;
46 import javax.lang.model.type.TypeMirror;
47 import javax.lang.model.type.TypeVariable;
48 import javax.lang.model.type.TypeVisitor;
49 import javax.lang.model.util.ElementFilter;
50 import javax.lang.model.util.Elements;
51 import javax.lang.model.util.SimpleTypeVisitor8;
52 import javax.lang.model.util.Types;
54 import javax.tools.FileObject;
55 import javax.tools.JavaFileManager;
56 import javax.tools.StandardLocation;
58 import com.sun.tools.javac.code.Attribute;
59 import com.sun.tools.javac.code.Flags;
60 import com.sun.tools.javac.code.Kinds;
61 import com.sun.tools.javac.code.Scope;
62 import com.sun.tools.javac.code.Symbol.ClassSymbol;
63 import com.sun.tools.javac.code.Symtab;
64 import com.sun.tools.javac.model.JavacElements;
65 import com.sun.tools.javac.model.JavacTypes;
66 import com.sun.tools.javac.util.Assert;
67 import com.sun.tools.javac.util.Context;
68 import com.sun.tools.javac.util.Log;
69 import com.sun.tools.javac.util.Options;
71 import static com.sun.tools.javac.main.Option.*;
73 /** This class provides operations to write native header files for classes.
74 *
75 * <p><b>This is NOT part of any supported API.
76 * If you write code that depends on this, you do so at your own risk.
77 * This code and its internal interfaces are subject to change or
78 * deletion without notice.</b>
79 */
80 public class JNIWriter {
81 protected static final Context.Key<JNIWriter> jniWriterKey =
82 new Context.Key<JNIWriter>();
84 /** Access to files. */
85 private final JavaFileManager fileManager;
87 JavacElements elements;
88 JavacTypes types;
90 /** The log to use for verbose output.
91 */
92 private final Log log;
94 /** Switch: verbose output.
95 */
96 private boolean verbose;
98 /** Switch: check all nested classes of top level class
99 */
100 private boolean checkAll;
102 private Mangle mangler;
104 private Context context;
106 private Symtab syms;
108 private String lineSep;
110 private final boolean isWindows =
111 System.getProperty("os.name").startsWith("Windows");
113 /** Get the ClassWriter instance for this context. */
114 public static JNIWriter instance(Context context) {
115 JNIWriter instance = context.get(jniWriterKey);
116 if (instance == null)
117 instance = new JNIWriter(context);
118 return instance;
119 }
121 /** Construct a class writer, given an options table.
122 */
123 private JNIWriter(Context context) {
124 context.put(jniWriterKey, this);
125 fileManager = context.get(JavaFileManager.class);
126 log = Log.instance(context);
128 Options options = Options.instance(context);
129 verbose = options.isSet(VERBOSE);
130 checkAll = options.isSet("javah:full");
132 this.context = context; // for lazyInit()
133 syms = Symtab.instance(context);
135 lineSep = System.getProperty("line.separator");
136 }
138 private void lazyInit() {
139 if (mangler == null) {
140 elements = JavacElements.instance(context);
141 types = JavacTypes.instance(context);
142 mangler = new Mangle(elements, types);
143 }
144 }
146 public boolean needsHeader(ClassSymbol c) {
147 if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
148 return false;
150 if (checkAll)
151 return needsHeader(c.outermostClass(), true);
152 else
153 return needsHeader(c, false);
154 }
156 private boolean needsHeader(ClassSymbol c, boolean checkNestedClasses) {
157 if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
158 return false;
160 /* temporary code for backwards compatibility */
161 for (Attribute.Compound a: c.annotations.getAttributes()) {
162 if (a.type.tsym == syms.nativeHeaderType_old.tsym)
163 return true;
164 }
165 /* end of temporary code for backwards compatibility */
167 for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
168 if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
169 return true;
170 for (Attribute.Compound a: i.sym.annotations.getAttributes()) {
171 if (a.type.tsym == syms.nativeHeaderType.tsym)
172 return true;
173 }
174 }
175 if (checkNestedClasses) {
176 for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
177 if ((i.sym.kind == Kinds.TYP) && needsHeader(((ClassSymbol) i.sym), true))
178 return true;
179 }
180 }
181 return false;
182 }
184 /** Emit a class file for a given class.
185 * @param c The class from which a class file is generated.
186 */
187 public FileObject write(ClassSymbol c)
188 throws IOException
189 {
190 String className = c.flatName().toString();
191 FileObject outFile
192 = fileManager.getFileForOutput(StandardLocation.NATIVE_HEADER_OUTPUT,
193 "", className.replaceAll("[.$]", "_") + ".h", null);
194 Writer out = outFile.openWriter();
195 try {
196 write(out, c);
197 if (verbose)
198 log.printVerbose("wrote.file", outFile);
199 out.close();
200 out = null;
201 } finally {
202 if (out != null) {
203 // if we are propogating an exception, delete the file
204 out.close();
205 outFile.delete();
206 outFile = null;
207 }
208 }
209 return outFile; // may be null if write failed
210 }
212 public void write(Writer out, ClassSymbol sym)
213 throws IOException {
214 lazyInit();
215 try {
216 String cname = mangler.mangle(sym.fullname, Mangle.Type.CLASS);
217 println(out, fileTop());
218 println(out, includes());
219 println(out, guardBegin(cname));
220 println(out, cppGuardBegin());
222 writeStatics(out, sym);
223 writeMethods(out, sym, cname);
225 println(out, cppGuardEnd());
226 println(out, guardEnd(cname));
227 } catch (TypeSignature.SignatureException e) {
228 throw new IOException(e);
229 }
230 }
232 protected void writeStatics(Writer out, ClassSymbol sym) throws IOException {
233 List<VariableElement> classfields = getAllFields(sym);
235 for (VariableElement v: classfields) {
236 if (!v.getModifiers().contains(Modifier.STATIC))
237 continue;
238 String s = null;
239 s = defineForStatic(sym, v);
240 if (s != null) {
241 println(out, s);
242 }
243 }
244 }
246 /**
247 * Including super class fields.
248 */
249 List<VariableElement> getAllFields(TypeElement subclazz) {
250 List<VariableElement> fields = new ArrayList<VariableElement>();
251 TypeElement cd = null;
252 Stack<TypeElement> s = new Stack<TypeElement>();
254 cd = subclazz;
255 while (true) {
256 s.push(cd);
257 TypeElement c = (TypeElement) (types.asElement(cd.getSuperclass()));
258 if (c == null)
259 break;
260 cd = c;
261 }
263 while (!s.empty()) {
264 cd = s.pop();
265 fields.addAll(ElementFilter.fieldsIn(cd.getEnclosedElements()));
266 }
268 return fields;
269 }
271 protected String defineForStatic(TypeElement c, VariableElement f) {
272 CharSequence cnamedoc = c.getQualifiedName();
273 CharSequence fnamedoc = f.getSimpleName();
275 String cname = mangler.mangle(cnamedoc, Mangle.Type.CLASS);
276 String fname = mangler.mangle(fnamedoc, Mangle.Type.FIELDSTUB);
278 Assert.check(f.getModifiers().contains(Modifier.STATIC));
280 if (f.getModifiers().contains(Modifier.FINAL)) {
281 Object value = null;
283 value = f.getConstantValue();
285 if (value != null) { /* so it is a ConstantExpression */
286 String constString = null;
287 if ((value instanceof Integer)
288 || (value instanceof Byte)
289 || (value instanceof Short)) {
290 /* covers byte, short, int */
291 constString = value.toString() + "L";
292 } else if (value instanceof Boolean) {
293 constString = ((Boolean) value) ? "1L" : "0L";
294 } else if (value instanceof Character) {
295 Character ch = (Character) value;
296 constString = String.valueOf(((int) ch) & 0xffff) + "L";
297 } else if (value instanceof Long) {
298 // Visual C++ supports the i64 suffix, not LL.
299 if (isWindows)
300 constString = value.toString() + "i64";
301 else
302 constString = value.toString() + "LL";
303 } else if (value instanceof Float) {
304 /* bug for bug */
305 float fv = ((Float)value).floatValue();
306 if (Float.isInfinite(fv))
307 constString = ((fv < 0) ? "-" : "") + "Inff";
308 else
309 constString = value.toString() + "f";
310 } else if (value instanceof Double) {
311 /* bug for bug */
312 double d = ((Double)value).doubleValue();
313 if (Double.isInfinite(d))
314 constString = ((d < 0) ? "-" : "") + "InfD";
315 else
316 constString = value.toString();
317 }
319 if (constString != null) {
320 StringBuilder s = new StringBuilder("#undef ");
321 s.append(cname); s.append("_"); s.append(fname); s.append(lineSep);
322 s.append("#define "); s.append(cname); s.append("_");
323 s.append(fname); s.append(" "); s.append(constString);
324 return s.toString();
325 }
327 }
328 }
330 return null;
331 }
334 protected void writeMethods(Writer out, ClassSymbol sym, String cname)
335 throws IOException, TypeSignature.SignatureException {
336 List<ExecutableElement> classmethods = ElementFilter.methodsIn(sym.getEnclosedElements());
337 for (ExecutableElement md: classmethods) {
338 if(md.getModifiers().contains(Modifier.NATIVE)){
339 TypeMirror mtr = types.erasure(md.getReturnType());
340 String sig = signature(md);
341 TypeSignature newtypesig = new TypeSignature(elements);
342 CharSequence methodName = md.getSimpleName();
343 boolean longName = false;
344 for (ExecutableElement md2: classmethods) {
345 if ((md2 != md)
346 && (methodName.equals(md2.getSimpleName()))
347 && (md2.getModifiers().contains(Modifier.NATIVE)))
348 longName = true;
350 }
351 println(out, "/*");
352 println(out, " * Class: " + cname);
353 println(out, " * Method: " +
354 mangler.mangle(methodName, Mangle.Type.FIELDSTUB));
355 println(out, " * Signature: " + newtypesig.getTypeSignature(sig, mtr));
356 println(out, " */");
357 println(out, "JNIEXPORT " + jniType(mtr) +
358 " JNICALL " +
359 mangler.mangleMethod(md, sym,
360 (longName) ?
361 Mangle.Type.METHOD_JNI_LONG :
362 Mangle.Type.METHOD_JNI_SHORT));
363 print(out, " (JNIEnv *, ");
364 List<? extends VariableElement> paramargs = md.getParameters();
365 List<TypeMirror> args = new ArrayList<TypeMirror>();
366 for (VariableElement p: paramargs) {
367 args.add(types.erasure(p.asType()));
368 }
369 if (md.getModifiers().contains(Modifier.STATIC))
370 print(out, "jclass");
371 else
372 print(out, "jobject");
374 for (TypeMirror arg: args) {
375 print(out, ", ");
376 print(out, jniType(arg));
377 }
378 println(out, ");"
379 + lineSep);
380 }
381 }
382 }
384 // c.f. MethodDoc.signature
385 String signature(ExecutableElement e) {
386 StringBuilder sb = new StringBuilder("(");
387 String sep = "";
388 for (VariableElement p: e.getParameters()) {
389 sb.append(sep);
390 sb.append(types.erasure(p.asType()).toString());
391 sep = ",";
392 }
393 sb.append(")");
394 return sb.toString();
395 }
397 protected final String jniType(TypeMirror t) {
398 TypeElement throwable = elements.getTypeElement("java.lang.Throwable");
399 TypeElement jClass = elements.getTypeElement("java.lang.Class");
400 TypeElement jString = elements.getTypeElement("java.lang.String");
401 Element tclassDoc = types.asElement(t);
404 switch (t.getKind()) {
405 case ARRAY: {
406 TypeMirror ct = ((ArrayType) t).getComponentType();
407 switch (ct.getKind()) {
408 case BOOLEAN: return "jbooleanArray";
409 case BYTE: return "jbyteArray";
410 case CHAR: return "jcharArray";
411 case SHORT: return "jshortArray";
412 case INT: return "jintArray";
413 case LONG: return "jlongArray";
414 case FLOAT: return "jfloatArray";
415 case DOUBLE: return "jdoubleArray";
416 case ARRAY:
417 case DECLARED: return "jobjectArray";
418 default: throw new Error(ct.toString());
419 }
420 }
422 case VOID: return "void";
423 case BOOLEAN: return "jboolean";
424 case BYTE: return "jbyte";
425 case CHAR: return "jchar";
426 case SHORT: return "jshort";
427 case INT: return "jint";
428 case LONG: return "jlong";
429 case FLOAT: return "jfloat";
430 case DOUBLE: return "jdouble";
432 case DECLARED: {
433 if (tclassDoc.equals(jString))
434 return "jstring";
435 else if (types.isAssignable(t, throwable.asType()))
436 return "jthrowable";
437 else if (types.isAssignable(t, jClass.asType()))
438 return "jclass";
439 else
440 return "jobject";
441 }
442 }
444 Assert.check(false, "jni unknown type");
445 return null; /* dead code. */
446 }
448 protected String fileTop() {
449 return "/* DO NOT EDIT THIS FILE - it is machine generated */";
450 }
452 protected String includes() {
453 return "#include <jni.h>";
454 }
456 /*
457 * Deal with the C pre-processor.
458 */
459 protected String cppGuardBegin() {
460 return "#ifdef __cplusplus" + lineSep
461 + "extern \"C\" {" + lineSep
462 + "#endif";
463 }
465 protected String cppGuardEnd() {
466 return "#ifdef __cplusplus" + lineSep
467 + "}" + lineSep
468 + "#endif";
469 }
471 protected String guardBegin(String cname) {
472 return "/* Header for class " + cname + " */" + lineSep
473 + lineSep
474 + "#ifndef _Included_" + cname + lineSep
475 + "#define _Included_" + cname;
476 }
478 protected String guardEnd(String cname) {
479 return "#endif";
480 }
482 protected void print(Writer out, String text) throws IOException {
483 out.write(text);
484 }
486 protected void println(Writer out, String text) throws IOException {
487 out.write(text);
488 out.write(lineSep);
489 }
492 private static class Mangle {
494 public static class Type {
495 public static final int CLASS = 1;
496 public static final int FIELDSTUB = 2;
497 public static final int FIELD = 3;
498 public static final int JNI = 4;
499 public static final int SIGNATURE = 5;
500 public static final int METHOD_JDK_1 = 6;
501 public static final int METHOD_JNI_SHORT = 7;
502 public static final int METHOD_JNI_LONG = 8;
503 };
505 private Elements elems;
506 private Types types;
508 Mangle(Elements elems, Types types) {
509 this.elems = elems;
510 this.types = types;
511 }
513 public final String mangle(CharSequence name, int mtype) {
514 StringBuilder result = new StringBuilder(100);
515 int length = name.length();
517 for (int i = 0; i < length; i++) {
518 char ch = name.charAt(i);
519 if (isalnum(ch)) {
520 result.append(ch);
521 } else if ((ch == '.') &&
522 mtype == Mangle.Type.CLASS) {
523 result.append('_');
524 } else if (( ch == '$') &&
525 mtype == Mangle.Type.CLASS) {
526 result.append('_');
527 result.append('_');
528 } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
529 result.append('_');
530 } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
531 result.append('_');
532 } else if (mtype == Mangle.Type.JNI) {
533 String esc = null;
534 if (ch == '_')
535 esc = "_1";
536 else if (ch == '.')
537 esc = "_";
538 else if (ch == ';')
539 esc = "_2";
540 else if (ch == '[')
541 esc = "_3";
542 if (esc != null) {
543 result.append(esc);
544 } else {
545 result.append(mangleChar(ch));
546 }
547 } else if (mtype == Mangle.Type.SIGNATURE) {
548 if (isprint(ch)) {
549 result.append(ch);
550 } else {
551 result.append(mangleChar(ch));
552 }
553 } else {
554 result.append(mangleChar(ch));
555 }
556 }
558 return result.toString();
559 }
561 public String mangleMethod(ExecutableElement method, TypeElement clazz,
562 int mtype) throws TypeSignature.SignatureException {
563 StringBuilder result = new StringBuilder(100);
564 result.append("Java_");
566 if (mtype == Mangle.Type.METHOD_JDK_1) {
567 result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
568 result.append('_');
569 result.append(mangle(method.getSimpleName(),
570 Mangle.Type.FIELD));
571 result.append("_stub");
572 return result.toString();
573 }
575 /* JNI */
576 result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
577 result.append('_');
578 result.append(mangle(method.getSimpleName(),
579 Mangle.Type.JNI));
580 if (mtype == Mangle.Type.METHOD_JNI_LONG) {
581 result.append("__");
582 String typesig = signature(method);
583 TypeSignature newTypeSig = new TypeSignature(elems);
584 String sig = newTypeSig.getTypeSignature(typesig, method.getReturnType());
585 sig = sig.substring(1);
586 sig = sig.substring(0, sig.lastIndexOf(')'));
587 sig = sig.replace('/', '.');
588 result.append(mangle(sig, Mangle.Type.JNI));
589 }
591 return result.toString();
592 }
593 //where
594 private String getInnerQualifiedName(TypeElement clazz) {
595 return elems.getBinaryName(clazz).toString();
596 }
598 public final String mangleChar(char ch) {
599 String s = Integer.toHexString(ch);
600 int nzeros = 5 - s.length();
601 char[] result = new char[6];
602 result[0] = '_';
603 for (int i = 1; i <= nzeros; i++)
604 result[i] = '0';
605 for (int i = nzeros+1, j = 0; i < 6; i++, j++)
606 result[i] = s.charAt(j);
607 return new String(result);
608 }
610 // Warning: duplicated in Gen
611 private String signature(ExecutableElement e) {
612 StringBuilder sb = new StringBuilder();
613 String sep = "(";
614 for (VariableElement p: e.getParameters()) {
615 sb.append(sep);
616 sb.append(types.erasure(p.asType()).toString());
617 sep = ",";
618 }
619 sb.append(")");
620 return sb.toString();
621 }
623 /* Warning: Intentional ASCII operation. */
624 private static boolean isalnum(char ch) {
625 return ch <= 0x7f && /* quick test */
626 ((ch >= 'A' && ch <= 'Z') ||
627 (ch >= 'a' && ch <= 'z') ||
628 (ch >= '0' && ch <= '9'));
629 }
631 /* Warning: Intentional ASCII operation. */
632 private static boolean isprint(char ch) {
633 return ch >= 32 && ch <= 126;
634 }
635 }
637 private static class TypeSignature {
638 static class SignatureException extends Exception {
639 private static final long serialVersionUID = 1L;
640 SignatureException(String reason) {
641 super(reason);
642 }
643 }
645 Elements elems;
647 /* Signature Characters */
649 private static final String SIG_VOID = "V";
650 private static final String SIG_BOOLEAN = "Z";
651 private static final String SIG_BYTE = "B";
652 private static final String SIG_CHAR = "C";
653 private static final String SIG_SHORT = "S";
654 private static final String SIG_INT = "I";
655 private static final String SIG_LONG = "J";
656 private static final String SIG_FLOAT = "F";
657 private static final String SIG_DOUBLE = "D";
658 private static final String SIG_ARRAY = "[";
659 private static final String SIG_CLASS = "L";
663 public TypeSignature(Elements elems){
664 this.elems = elems;
665 }
667 /*
668 * Returns the type signature of a field according to JVM specs
669 */
670 public String getTypeSignature(String javasignature) throws SignatureException {
671 return getParamJVMSignature(javasignature);
672 }
674 /*
675 * Returns the type signature of a method according to JVM specs
676 */
677 public String getTypeSignature(String javasignature, TypeMirror returnType)
678 throws SignatureException {
679 String signature = null; //Java type signature.
680 String typeSignature = null; //Internal type signature.
681 List<String> params = new ArrayList<String>(); //List of parameters.
682 String paramsig = null; //Java parameter signature.
683 String paramJVMSig = null; //Internal parameter signature.
684 String returnSig = null; //Java return type signature.
685 String returnJVMType = null; //Internal return type signature.
686 int dimensions = 0; //Array dimension.
688 int startIndex = -1;
689 int endIndex = -1;
690 StringTokenizer st = null;
691 int i = 0;
693 // Gets the actual java signature without parentheses.
694 if (javasignature != null) {
695 startIndex = javasignature.indexOf("(");
696 endIndex = javasignature.indexOf(")");
697 }
699 if (((startIndex != -1) && (endIndex != -1))
700 &&(startIndex+1 < javasignature.length())
701 &&(endIndex < javasignature.length())) {
702 signature = javasignature.substring(startIndex+1, endIndex);
703 }
705 // Separates parameters.
706 if (signature != null) {
707 if (signature.indexOf(",") != -1) {
708 st = new StringTokenizer(signature, ",");
709 if (st != null) {
710 while (st.hasMoreTokens()) {
711 params.add(st.nextToken());
712 }
713 }
714 } else {
715 params.add(signature);
716 }
717 }
719 /* JVM type signature. */
720 typeSignature = "(";
722 // Gets indivisual internal parameter signature.
723 while (params.isEmpty() != true) {
724 paramsig = params.remove(i).trim();
725 paramJVMSig = getParamJVMSignature(paramsig);
726 if (paramJVMSig != null) {
727 typeSignature += paramJVMSig;
728 }
729 }
731 typeSignature += ")";
733 // Get internal return type signature.
735 returnJVMType = "";
736 if (returnType != null) {
737 dimensions = dimensions(returnType);
738 }
740 //Gets array dimension of return type.
741 while (dimensions-- > 0) {
742 returnJVMType += "[";
743 }
744 if (returnType != null) {
745 returnSig = qualifiedTypeName(returnType);
746 returnJVMType += getComponentType(returnSig);
747 } else {
748 System.out.println("Invalid return type.");
749 }
751 typeSignature += returnJVMType;
753 return typeSignature;
754 }
756 /*
757 * Returns internal signature of a parameter.
758 */
759 private String getParamJVMSignature(String paramsig) throws SignatureException {
760 String paramJVMSig = "";
761 String componentType ="";
763 if(paramsig != null){
765 if(paramsig.indexOf("[]") != -1) {
766 // Gets array dimension.
767 int endindex = paramsig.indexOf("[]");
768 componentType = paramsig.substring(0, endindex);
769 String dimensionString = paramsig.substring(endindex);
770 if(dimensionString != null){
771 while(dimensionString.indexOf("[]") != -1){
772 paramJVMSig += "[";
773 int beginindex = dimensionString.indexOf("]") + 1;
774 if(beginindex < dimensionString.length()){
775 dimensionString = dimensionString.substring(beginindex);
776 }else
777 dimensionString = "";
778 }
779 }
780 } else componentType = paramsig;
782 paramJVMSig += getComponentType(componentType);
783 }
784 return paramJVMSig;
785 }
787 /*
788 * Returns internal signature of a component.
789 */
790 private String getComponentType(String componentType) throws SignatureException {
792 String JVMSig = "";
794 if(componentType != null){
795 if(componentType.equals("void")) JVMSig += SIG_VOID ;
796 else if(componentType.equals("boolean")) JVMSig += SIG_BOOLEAN ;
797 else if(componentType.equals("byte")) JVMSig += SIG_BYTE ;
798 else if(componentType.equals("char")) JVMSig += SIG_CHAR ;
799 else if(componentType.equals("short")) JVMSig += SIG_SHORT ;
800 else if(componentType.equals("int")) JVMSig += SIG_INT ;
801 else if(componentType.equals("long")) JVMSig += SIG_LONG ;
802 else if(componentType.equals("float")) JVMSig += SIG_FLOAT ;
803 else if(componentType.equals("double")) JVMSig += SIG_DOUBLE ;
804 else {
805 if(!componentType.equals("")){
806 TypeElement classNameDoc = elems.getTypeElement(componentType);
808 if(classNameDoc == null){
809 throw new SignatureException(componentType);
810 }else {
811 String classname = classNameDoc.getQualifiedName().toString();
812 String newclassname = classname.replace('.', '/');
813 JVMSig += "L";
814 JVMSig += newclassname;
815 JVMSig += ";";
816 }
817 }
818 }
819 }
820 return JVMSig;
821 }
823 int dimensions(TypeMirror t) {
824 if (t.getKind() != TypeKind.ARRAY)
825 return 0;
826 return 1 + dimensions(((ArrayType) t).getComponentType());
827 }
830 String qualifiedTypeName(TypeMirror type) {
831 TypeVisitor<Name, Void> v = new SimpleTypeVisitor8<Name, Void>() {
832 @Override
833 public Name visitArray(ArrayType t, Void p) {
834 return t.getComponentType().accept(this, p);
835 }
837 @Override
838 public Name visitDeclared(DeclaredType t, Void p) {
839 return ((TypeElement) t.asElement()).getQualifiedName();
840 }
842 @Override
843 public Name visitPrimitive(PrimitiveType t, Void p) {
844 return elems.getName(t.toString());
845 }
847 @Override
848 public Name visitNoType(NoType t, Void p) {
849 if (t.getKind() == TypeKind.VOID)
850 return elems.getName("void");
851 return defaultAction(t, p);
852 }
854 @Override
855 public Name visitTypeVariable(TypeVariable t, Void p) {
856 return t.getUpperBound().accept(this, p);
857 }
858 };
859 return v.visit(type).toString();
860 }
861 }
863 }