aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Broyer <t.broyer@ltgt.net>2017-05-13 14:52:51 +0200
committerJesse Wilson <jesse@swank.ca>2017-05-13 08:52:51 -0400
commit4cd975b9649ec87f9a71ce48916fba8d9d460e4e (patch)
tree171a12cbbec17a17c2505588e2a088f343e6e37a /src
parent40dfa0cf36d844ca733bef0d4a61e87c9339af2c (diff)
downloadjavapoet-4cd975b9649ec87f9a71ce48916fba8d9d460e4e.tar.gz
Fix conflicts with types with same name as type being declared (#559)
* Add failing tests for types conflicting with type being declared Also removes previous (flawed) test, which should have been in JavaFileTest anyway, and add a separate test for the "superclass references self" case (already handled in TypeSpecTest#interfaceExtends btw, but this makes it clearer what is tested and expected). And add a separate test for classes in the same package conflicting with a superclass, for completeness. Reproduces #470 * Fix conflicts with types with same name as type being declared Those types (annotations, or referenced in annotation values, in type variable bounds, superclass, or superinterfaces) were erroneously imported rather than being emitted with their qualified name. Fixes #470
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/squareup/javapoet/TypeSpec.java29
-rw-r--r--src/test/java/com/squareup/javapoet/JavaFileTest.java94
-rw-r--r--src/test/java/com/squareup/javapoet/TypeSpecTest.java19
3 files changed, 123 insertions, 19 deletions
diff --git a/src/main/java/com/squareup/javapoet/TypeSpec.java b/src/main/java/com/squareup/javapoet/TypeSpec.java
index 85fa250..b493d0c 100644
--- a/src/main/java/com/squareup/javapoet/TypeSpec.java
+++ b/src/main/java/com/squareup/javapoet/TypeSpec.java
@@ -82,6 +82,30 @@ public final class TypeSpec {
this.originatingElements = Util.immutableList(originatingElementsMutable);
}
+ /**
+ * Creates a dummy type spec for type-resolution only (in CodeWriter)
+ * while emitting the type declaration but before entering the type body.
+ */
+ private TypeSpec(TypeSpec type) {
+ assert type.anonymousTypeArguments == null;
+ this.kind = type.kind;
+ this.name = type.name;
+ this.anonymousTypeArguments = null;
+ this.javadoc = type.javadoc;
+ this.annotations = Collections.emptyList();
+ this.modifiers = Collections.emptySet();
+ this.typeVariables = Collections.emptyList();
+ this.superclass = null;
+ this.superinterfaces = Collections.emptyList();
+ this.enumConstants = Collections.emptyMap();
+ this.fieldSpecs = Collections.emptyList();
+ this.staticBlock = type.staticBlock;
+ this.initializerBlock = type.initializerBlock;
+ this.methodSpecs = Collections.emptyList();
+ this.typeSpecs = Collections.emptyList();
+ this.originatingElements = Collections.emptyList();
+ }
+
public boolean hasModifier(Modifier modifier) {
return modifiers.contains(modifier);
}
@@ -172,6 +196,9 @@ public final class TypeSpec {
codeWriter.emit(anonymousTypeArguments);
codeWriter.emit(") {\n");
} else {
+ // Push an empty type (specifically without nested types) for type-resolution.
+ codeWriter.pushType(new TypeSpec(this));
+
codeWriter.emitJavadoc(javadoc);
codeWriter.emitAnnotations(annotations, false);
codeWriter.emitModifiers(modifiers, Util.union(implicitModifiers, kind.asMemberModifiers));
@@ -214,6 +241,8 @@ public final class TypeSpec {
}
}
+ codeWriter.popType();
+
codeWriter.emit(" {\n");
}
diff --git a/src/test/java/com/squareup/javapoet/JavaFileTest.java b/src/test/java/com/squareup/javapoet/JavaFileTest.java
index a7662a2..ee7fca8 100644
--- a/src/test/java/com/squareup/javapoet/JavaFileTest.java
+++ b/src/test/java/com/squareup/javapoet/JavaFileTest.java
@@ -465,6 +465,84 @@ public final class JavaFileTest {
+ "}\n");
}
+ @Test public void classAndSuperclassShareName() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .superclass(ClassName.get("com.taco.bell", "Taco"))
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "class Taco extends com.taco.bell.Taco {\n"
+ + "}\n");
+ }
+
+ @Test public void conflictingAnnotation() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .addAnnotation(ClassName.get("com.taco.bell", "Taco"))
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "@com.taco.bell.Taco\n"
+ + "class Taco {\n"
+ + "}\n");
+ }
+
+ @Test public void conflictingAnnotationReferencedClass() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("com.squareup.tacos", "MyAnno"))
+ .addMember("value", "$T.class", ClassName.get("com.taco.bell", "Taco"))
+ .build())
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "@MyAnno(com.taco.bell.Taco.class)\n"
+ + "class Taco {\n"
+ + "}\n");
+ }
+
+ @Test public void conflictingTypeVariableBound() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .addTypeVariable(
+ TypeVariableName.get("T", ClassName.get("com.taco.bell", "Taco")))
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "class Taco<T extends com.taco.bell.Taco> {\n"
+ + "}\n");
+ }
+
+ @Test public void superclassReferencesSelf() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .superclass(ParameterizedTypeName.get(
+ ClassName.get(Comparable.class), ClassName.get("com.squareup.tacos", "Taco")))
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "import java.lang.Comparable;\n"
+ + "\n"
+ + "class Taco extends Comparable<Taco> {\n"
+ + "}\n");
+ }
+
/** https://github.com/square/javapoet/issues/366 */
@Test public void annotationIsNestedClass() throws Exception {
String source = JavaFile.builder("com.squareup.tacos",
@@ -573,4 +651,20 @@ public final class JavaFileTest {
+ " }\n"
+ "}\n");
}
+
+ @Test public void packageClassConflictsWithSuperlass() throws Exception {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .superclass(ClassName.get("com.taco.bell", "A"))
+ .addField(ClassName.get("com.squareup.tacos", "A"), "a")
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "class Taco extends com.taco.bell.A {\n"
+ + " A a;\n"
+ + "}\n");
+ }
}
diff --git a/src/test/java/com/squareup/javapoet/TypeSpecTest.java b/src/test/java/com/squareup/javapoet/TypeSpecTest.java
index fa27f17..4044955 100644
--- a/src/test/java/com/squareup/javapoet/TypeSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/TypeSpecTest.java
@@ -625,25 +625,6 @@ public final class TypeSpecTest {
+ "}\n");
}
- @Test public void classImplementsExtendsSameName() throws Exception {
- ClassName javapoetTaco = ClassName.get(tacosPackage, "Taco");
- ClassName tacoBellTaco = ClassName.get("com.taco.bell", "Taco");
- ClassName fishTaco = ClassName.get("org.fish.taco", "Taco");
- TypeSpec typeSpec = TypeSpec.classBuilder("Taco")
- .superclass(fishTaco)
- .addSuperinterface(ParameterizedTypeName.get(ClassName.get(Comparable.class), javapoetTaco))
- .addSuperinterface(tacoBellTaco)
- .build();
- assertThat(toString(typeSpec)).isEqualTo(""
- + "package com.squareup.tacos;\n"
- + "\n"
- + "import java.lang.Comparable;\n"
- + "\n"
- + "class Taco extends org.fish.taco.Taco "
- + "implements Comparable<Taco>, com.taco.bell.Taco {\n"
- + "}\n");
- }
-
@Test public void classImplementsNestedClass() throws Exception {
ClassName outer = ClassName.get(tacosPackage, "Outer");
ClassName inner = outer.nestedClass("Inner");