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