diff --git a/src/main/java/com/squareup/javapoet/ClassName.java b/src/main/java/com/squareup/javapoet/ClassName.java index 6d1abd8c7..3617c51a4 100644 --- a/src/main/java/com/squareup/javapoet/ClassName.java +++ b/src/main/java/com/squareup/javapoet/ClassName.java @@ -51,7 +51,7 @@ private ClassName(List names, List annotations) { this.names = Util.immutableList(names); this.canonicalName = (names.get(0).isEmpty() ? Util.join(".", names.subList(1, names.size())) - : Util.join(".", names)).replace(".$", "$"); + : Util.join(".", names)); } @Override public ClassName annotated(List annotations) { @@ -141,16 +141,13 @@ public static ClassName get(Class clazz) { checkArgument(!clazz.isArray(), "array types cannot be represented as a ClassName"); List names = new ArrayList<>(); while (true) { - if (clazz.isAnonymousClass()) { - int lastDot = clazz.getName().lastIndexOf('.'); - if (lastDot != -1) { - String anonClassName = clazz.getName().substring(lastDot + 1); - int lastDollar = anonClassName.lastIndexOf('$'); - names.add(anonClassName.substring(lastDollar)); - } - } else { - names.add(clazz.getSimpleName()); + String anonymousSuffix = ""; + while (clazz.isAnonymousClass()) { + int lastDollar = clazz.getName().lastIndexOf('$'); + anonymousSuffix = clazz.getName().substring(lastDollar) + anonymousSuffix; + clazz = clazz.getEnclosingClass(); } + names.add(clazz.getSimpleName() + anonymousSuffix); Class enclosing = clazz.getEnclosingClass(); if (enclosing == null) break; clazz = enclosing; diff --git a/src/test/java/com/squareup/javapoet/ClassNameTest.java b/src/test/java/com/squareup/javapoet/ClassNameTest.java index 1544814f8..0488213d8 100644 --- a/src/test/java/com/squareup/javapoet/ClassNameTest.java +++ b/src/test/java/com/squareup/javapoet/ClassNameTest.java @@ -96,10 +96,18 @@ private void assertBestGuessThrows(String s) { assertThat(baz).isEqualTo(ClassName.get("com.example", "Foo", "Bar", "Baz")); } + static class $Outer { + static class $Inner {} + } + @Test public void classNameFromTypeElement() { Elements elements = compilationRule.getElements(); - TypeElement element = elements.getTypeElement(Object.class.getCanonicalName()); - assertThat(ClassName.get(element).toString()).isEqualTo("java.lang.Object"); + TypeElement object = elements.getTypeElement(Object.class.getCanonicalName()); + assertThat(ClassName.get(object).toString()).isEqualTo("java.lang.Object"); + TypeElement outer = elements.getTypeElement($Outer.class.getCanonicalName()); + assertThat(ClassName.get(outer).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer"); + TypeElement inner = elements.getTypeElement($Outer.$Inner.class.getCanonicalName()); + assertThat(ClassName.get(inner).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner"); } @Test public void classNameFromClass() { @@ -109,6 +117,12 @@ private void assertBestGuessThrows(String s) { .isEqualTo("com.squareup.javapoet.ClassNameTest.OuterClass.InnerClass"); assertThat((ClassName.get(new Object() {}.getClass())).toString()) .isEqualTo("com.squareup.javapoet.ClassNameTest$1"); + assertThat((ClassName.get(new Object() { Object inner = new Object() {}; }.inner.getClass())).toString()) + .isEqualTo("com.squareup.javapoet.ClassNameTest$2$1"); + assertThat((ClassName.get($Outer.class)).toString()) + .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer"); + assertThat((ClassName.get($Outer.$Inner.class)).toString()) + .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner"); } @Test public void peerClass() {