1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Marc R. Hoffmann - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.report; 14 15 import org.objectweb.asm.Type; 16 17 /** 18 * Names for the Java language. 19 */ 20 public class JavaNames implements ILanguageNames { 21 getPackageName(final String vmname)22 public String getPackageName(final String vmname) { 23 if (vmname.length() == 0) { 24 return "default"; 25 } 26 return vmname.replace('/', '.'); 27 } 28 getClassName(final String vmname)29 private String getClassName(final String vmname) { 30 final int pos = vmname.lastIndexOf('/'); 31 final String name = pos == -1 ? vmname : vmname.substring(pos + 1); 32 return name.replace('$', '.'); 33 } 34 isAnonymous(final String vmname)35 private boolean isAnonymous(final String vmname) { 36 final int dollarPosition = vmname.lastIndexOf('$'); 37 if (dollarPosition == -1) { 38 return false; 39 } 40 final int internalPosition = dollarPosition + 1; 41 if (internalPosition == vmname.length()) { 42 // shouldn't happen for classes compiled from Java source 43 return false; 44 } 45 // assume non-identifier start character for anonymous classes 46 final char start = vmname.charAt(internalPosition); 47 return !Character.isJavaIdentifierStart(start); 48 } 49 getClassName(final String vmname, final String vmsignature, final String vmsuperclass, final String[] vminterfaces)50 public String getClassName(final String vmname, final String vmsignature, 51 final String vmsuperclass, final String[] vminterfaces) { 52 if (isAnonymous(vmname)) { 53 final String vmsupertype; 54 if (vminterfaces != null && vminterfaces.length > 0) { 55 vmsupertype = vminterfaces[0]; 56 } else if (vmsuperclass != null) { 57 vmsupertype = vmsuperclass; 58 } else { 59 vmsupertype = null; 60 } 61 // append Eclipse style label, e.g. "Foo.new Bar() {...}" 62 if (vmsupertype != null) { 63 final StringBuilder builder = new StringBuilder(); 64 final String vmenclosing = vmname.substring(0, 65 vmname.lastIndexOf('$')); 66 builder.append(getClassName(vmenclosing)).append(".new ") 67 .append(getClassName(vmsupertype)).append("() {...}"); 68 return builder.toString(); 69 } 70 } 71 return getClassName(vmname); 72 } 73 getQualifiedClassName(final String vmname)74 public String getQualifiedClassName(final String vmname) { 75 return vmname.replace('/', '.').replace('$', '.'); 76 } 77 getMethodName(final String vmclassname, final String vmmethodname, final String vmdesc, final String vmsignature)78 public String getMethodName(final String vmclassname, 79 final String vmmethodname, final String vmdesc, 80 final String vmsignature) { 81 return getMethodName(vmclassname, vmmethodname, vmdesc, false); 82 } 83 getQualifiedMethodName(final String vmclassname, final String vmmethodname, final String vmdesc, final String vmsignature)84 public String getQualifiedMethodName(final String vmclassname, 85 final String vmmethodname, final String vmdesc, 86 final String vmsignature) { 87 return getQualifiedClassName(vmclassname) + "." 88 + getMethodName(vmclassname, vmmethodname, vmdesc, true); 89 } 90 getMethodName(final String vmclassname, final String vmmethodname, final String vmdesc, final boolean qualifiedParams)91 private String getMethodName(final String vmclassname, 92 final String vmmethodname, final String vmdesc, 93 final boolean qualifiedParams) { 94 if ("<clinit>".equals(vmmethodname)) { 95 return "static {...}"; 96 } 97 final StringBuilder result = new StringBuilder(); 98 if ("<init>".equals(vmmethodname)) { 99 if (isAnonymous(vmclassname)) { 100 return "{...}"; 101 } else { 102 result.append(getClassName(vmclassname)); 103 } 104 } else { 105 result.append(vmmethodname); 106 } 107 result.append('('); 108 final Type[] arguments = Type.getArgumentTypes(vmdesc); 109 boolean comma = false; 110 for (final Type arg : arguments) { 111 if (comma) { 112 result.append(", "); 113 } else { 114 comma = true; 115 } 116 if (qualifiedParams) { 117 result.append(getQualifiedClassName(arg.getClassName())); 118 } else { 119 result.append(getShortTypeName(arg)); 120 } 121 } 122 result.append(')'); 123 return result.toString(); 124 } 125 getShortTypeName(final Type type)126 private String getShortTypeName(final Type type) { 127 final String name = type.getClassName(); 128 final int pos = name.lastIndexOf('.'); 129 final String shortName = pos == -1 ? name : name.substring(pos + 1); 130 return shortName.replace('$', '.'); 131 } 132 133 } 134