content: /*******************************************************************************
   * Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *    Marc R. Hoffmann - initial API and implementation
   *    
   *******************************************************************************/
  package org.jacoco.report;
  
  import org.objectweb.asm.Type;
  
  /**
   * Names for the Java language.
   */
  public class JavaNames implements ILanguageNames {
  
  	public String getPackageName(final String vmname) {
  		if (vmname.length() == 0) {
  			return "default";
  		}
  		return vmname.replace('/', '.');
  	}
  
  	private String getClassName(final String vmname) {
  		final int pos = vmname.lastIndexOf('/');
  		final String name = pos == -1 ? vmname : vmname.substring(pos + 1);
  		return name.replace('$', '.');
  	}
  
  	private boolean isAnonymous(final String vmname) {
  		final int dollarPosition = vmname.lastIndexOf('$');
  		if (dollarPosition == -1) {
  			return false;
  		}
  		final int internalPosition = dollarPosition + 1;
  		if (internalPosition == vmname.length()) {
  			// shouldn't happen for classes compiled from Java source
  			return false;
  		}
  		// assume non-identifier start character for anonymous classes
  		final char start = vmname.charAt(internalPosition);
  		return !Character.isJavaIdentifierStart(start);
  	}
  
  	public String getClassName(final String vmname, final String vmsignature,
  			final String vmsuperclass, final String[] vminterfaces) {
  		if (isAnonymous(vmname)) {
  			final String vmsupertype;
  			if (vminterfaces != null && vminterfaces.length > 0) {
  				vmsupertype = vminterfaces[0];
  			} else if (vmsuperclass != null) {
  				vmsupertype = vmsuperclass;
  			} else {
  				vmsupertype = null;
  			}
  			// append Eclipse style label, e.g. "Foo.new Bar() {...}"
  			if (vmsupertype != null) {
  				final StringBuilder builder = new StringBuilder();
  				final String vmenclosing = vmname.substring(0,
  						vmname.lastIndexOf('$'));
  				builder.append(getClassName(vmenclosing)).append(".new ")
  						.append(getClassName(vmsupertype)).append("() {...}");
  				return builder.toString();
  			}
  		}
  		return getClassName(vmname);
  	}
  
  	public String getQualifiedClassName(final String vmname) {
  		return vmname.replace('/', '.').replace('$', '.');
  	}
  
  	public String getMethodName(final String vmclassname,
  			final String vmmethodname, final String vmdesc,
  			final String vmsignature) {
  		return getMethodName(vmclassname, vmmethodname, vmdesc, false);
  	}
  
  	public String getQualifiedMethodName(final String vmclassname,
  			final String vmmethodname, final String vmdesc,
  			final String vmsignature) {
  		return getQualifiedClassName(vmclassname) + "."
  				+ getMethodName(vmclassname, vmmethodname, vmdesc, true);
  	}
  
  	private String getMethodName(final String vmclassname,
  			final String vmmethodname, final String vmdesc,
  			final boolean qualifiedParams) {
  		if ("<clinit>".equals(vmmethodname)) {
  			return "static {...}";
  		}
  		final StringBuilder result = new StringBuilder();
  		if ("<init>".equals(vmmethodname)) {
  			if (isAnonymous(vmclassname)) {
  				return "{...}";
  			} else {
  				result.append(getClassName(vmclassname));
  			}
  		} else {
  			result.append(vmmethodname);
  		}
  		result.append('(');
  		final Type[] arguments = Type.getArgumentTypes(vmdesc);
  		boolean comma = false;
  		for (final Type arg : arguments) {
  			if (comma) {
  				result.append(", ");
  			} else {
  				comma = true;
  			}
  			if (qualifiedParams) {
  				result.append(getQualifiedClassName(arg.getClassName()));
  			} else {
  				result.append(getShortTypeName(arg));
  			}
  		}
  		result.append(')');
  		return result.toString();
  	}
  
  	private String getShortTypeName(final Type type) {
  		final String name = type.getClassName();
  		final int pos = name.lastIndexOf('.');
  		final String shortName = pos == -1 ? name : name.substring(pos + 1);
  		return shortName.replace('$', '.');
  	}
  
  }
  