private CharSequence toName(boolean internal, @Nullable StringBuilder out) { if (DEFAULT_PACKAGE.equals(this)) { return ""; } // We build in reverse so that we don't have to recurse to parent. StringBuilder sb = out; if (sb == null) { sb = new StringBuilder(); } int startPosition = sb.length(); switch (type) { case PACKAGE: // Treat package names as directories to disambiguate those namespaces. if (internal) { sb.append('/'); } break; case METHOD: case CONSTRUCTOR: // Disambiguate callables and fields. // Constructors are disambiguated from methods by the presence of // angle brackets in the name: <init> and <clinit>. sb.append(")("); break; case FIELD: case CLASS: break; } ApiElement el = this; while (true) { ApiElement parentEl = el.parent.get(); appendInReverse(el.name, sb); if (DEFAULT_PACKAGE.equals(parentEl)) { break; } switch (el.type) { case CLASS: sb.append(internal ? (parentEl.type == ApiElementType.CLASS ? '$' : '/') : '.'); break; case PACKAGE: sb.append(internal ? '/' : '.'); break; case CONSTRUCTOR: case METHOD: case FIELD: sb.append(internal ? '#' : '.'); break; } el = parentEl; } reverse(sb, startPosition, sb.length()); return sb; }
/** * @param name a JVM internal class name. * @return An API element such that name equals {@link #toInternalName}. */ public static ApiElement fromInternalClassName(String name) { try { ApiElement apiElement = ApiElement.DEFAULT_PACKAGE; String[] nameParts = name.split("/"); for (int i = 0, n = nameParts.length; i < n - 1; ++i) { apiElement = apiElement.child(nameParts[i], ApiElementType.PACKAGE); } String className = nameParts[nameParts.length - 1]; for (String classNamePart : splitClassName(className)) { apiElement = apiElement.child(classNamePart, ApiElementType.CLASS); } return apiElement; } catch (RuntimeException ex) { // Make sure the trace includes the whole input. throw new IllegalArgumentException("Bad internal class name `" + name + "`", ex); } }
static ApiElement method(String name, ApiElement parent) { return parent.child(name, ApiElementType.METHOD); }
static ApiElement field(String name, ApiElement parent) { return parent.child(name, ApiElementType.FIELD); }
static ApiElement clazz(String name, ApiElement parent) { return parent.child(name, ApiElementType.CLASS); }
static ApiElement pkg(String name, ApiElement parent) { return parent.child(name, ApiElementType.PACKAGE); }