diff --git a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java index c95823fc13..7d37a02417 100644 --- a/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/ConcreteReference.java @@ -84,6 +84,9 @@ public String pakkage() { return clazz().getPackage().getName(); } + @Override + public abstract boolean useFullName(); + @Override public String enclosingClassName() { if (!hasEnclosingClass()) { @@ -129,9 +132,22 @@ public boolean isSupertypeOrEquals(Reference other) { @Override public boolean isAssignableFrom(Reference other) { + if (other instanceof VaporReference && ((VaporReference) other).supertypeReference() != null) { + return isAssignableFrom(((VaporReference) other).supertypeReference()); + } + if (!(other instanceof ConcreteReference)) { return false; } + + if (generics().size() == other.generics().size()) { + for (int i = 0; i < generics().size(); i++) { + if (!generics().get(i).isSupertypeOrEquals(other.generics().get(i))) { + return false; + } + } + } + return clazz().isAssignableFrom(((ConcreteReference) other).clazz()); } @@ -178,6 +194,7 @@ public static ConcreteReference wildcardWithUpperBound(Reference upperBoundRefer public static Builder builder() { return new AutoValue_ConcreteReference.Builder() + .setUseFullName(false) .setGenerics(ImmutableList.of()) .setIsStaticImport(false); } @@ -189,6 +206,8 @@ public static Builder builder() { public abstract static class Builder { public abstract Builder setClazz(Class clazz); + public abstract Builder setUseFullName(boolean useFullName); + public abstract Builder setWildcardUpperBound(Reference reference); public abstract Builder setGenerics(List clazzes); diff --git a/src/main/java/com/google/api/generator/engine/ast/Reference.java b/src/main/java/com/google/api/generator/engine/ast/Reference.java index 6fd856c78f..ed26731f0f 100644 --- a/src/main/java/com/google/api/generator/engine/ast/Reference.java +++ b/src/main/java/com/google/api/generator/engine/ast/Reference.java @@ -27,6 +27,8 @@ public interface Reference { String pakkage(); + boolean useFullName(); + @Nullable String enclosingClassName(); diff --git a/src/main/java/com/google/api/generator/engine/ast/VaporReference.java b/src/main/java/com/google/api/generator/engine/ast/VaporReference.java index 4ba17aa356..fbd75afc2e 100644 --- a/src/main/java/com/google/api/generator/engine/ast/VaporReference.java +++ b/src/main/java/com/google/api/generator/engine/ast/VaporReference.java @@ -37,10 +37,16 @@ public abstract class VaporReference implements Reference { @Override public abstract String pakkage(); + @Override + public abstract boolean useFullName(); + @Nullable @Override public abstract String enclosingClassName(); + @Nullable + public abstract Reference supertypeReference(); + @Nullable @Override public Reference wildcardUpperBound() { @@ -77,7 +83,7 @@ public boolean isSupertypeOrEquals(Reference other) { @Override public boolean isAssignableFrom(Reference other) { - // Not handling this for VaporReference. + // Not handling this yet for VaporReference. return false; } @@ -117,6 +123,7 @@ public Reference copyAndSetGenerics(List generics) { public static Builder builder() { return new AutoValue_VaporReference.Builder() + .setUseFullName(false) .setGenerics(ImmutableList.of()) .setIsStaticImport(false); } @@ -130,12 +137,16 @@ public abstract static class Builder { public abstract Builder setPakkage(String pakkage); + public abstract Builder setUseFullName(boolean useFullName); + public abstract Builder setGenerics(List clazzes); public abstract Builder setEnclosingClassName(String enclosingClassName); public abstract Builder setIsStaticImport(boolean isStaticImport); + public abstract Builder setSupertypeReference(Reference supertypeReference); + // Private. abstract Builder setPlainName(String plainName); diff --git a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java index 94af63747e..fa2648a545 100644 --- a/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/ImportWriterVisitor.java @@ -109,7 +109,9 @@ public void visit(TypeNode type) { } List refs = new ArrayList<>(type.reference().generics()); - refs.add(type.reference()); + if (!type.reference().useFullName()) { + refs.add(type.reference()); + } references(refs); } @@ -384,6 +386,9 @@ private void variableExpressions(List expressions) { private void references(List refs) { for (Reference ref : refs) { // Don't need to import this. + if (ref.useFullName()) { + continue; + } if (!ref.isStaticImport() && (ref.isFromPackage(PKG_JAVA_LANG) || ref.isFromPackage(currentPackage))) { continue; diff --git a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java index 6112275b3c..7a1e4d3b6d 100644 --- a/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java +++ b/src/main/java/com/google/api/generator/engine/writer/JavaWriterVisitor.java @@ -145,6 +145,10 @@ public void visit(TypeNode type) { if (type.isPrimitiveType()) { generatedCodeBuilder.append(typeKind.toString().toLowerCase()); } else { + if (type.reference().useFullName()) { + generatedCodeBuilder.append(type.reference().pakkage()); + generatedCodeBuilder.append(DOT); + } // A null pointer exception will be thrown if reference is null, which is WAI. generatedCodeBuilder.append(type.reference().name()); } diff --git a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java index b284b1bb3a..7083cc280b 100644 --- a/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java +++ b/src/test/java/com/google/api/generator/engine/ast/ConcreteReferenceTest.java @@ -148,4 +148,89 @@ public void wildcards() { "? extends String", ConcreteReference.wildcardWithUpperBound(TypeNode.STRING.reference()).name()); } + + @Test + public void isAssignableFrom_concreteRef() { + assertFalse( + ConcreteReference.withClazz(List.class) + .isAssignableFrom(ConcreteReference.withClazz(Map.class))); + + assertTrue( + ConcreteReference.withClazz(List.class) + .isAssignableFrom(ConcreteReference.withClazz(ArrayList.class))); + assertFalse( + ConcreteReference.withClazz(ArrayList.class) + .isAssignableFrom(ConcreteReference.withClazz(List.class))); + assertTrue( + ConcreteReference.withClazz(ArrayList.class) + .isAssignableFrom(ConcreteReference.withClazz(ArrayList.class))); + + assertTrue( + ConcreteReference.withClazz(List.class) + .isAssignableFrom( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) + .build())); + assertTrue( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) + .build() + .isAssignableFrom( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) + .build())); + assertFalse( + ConcreteReference.builder() + .setClazz(List.class) + .setGenerics(Arrays.asList(ConcreteReference.withClazz(Integer.class))) + .build() + .isAssignableFrom( + ConcreteReference.builder() + .setClazz(ArrayList.class) + .setGenerics(Arrays.asList(ConcreteReference.withClazz(String.class))) + .build())); + } + + @Test + public void isAssignableFrom_vaporRef() { + assertFalse( + ConcreteReference.withClazz(List.class) + .isAssignableFrom( + VaporReference.builder().setName("ArrayList").setPakkage("java.util").build())); + assertFalse( + ConcreteReference.withClazz(ArrayList.class) + .isAssignableFrom( + VaporReference.builder().setName("ArrayList").setPakkage("java.util").build())); + } + + @Test + public void isAssignableFrom_vaporRefWithConcreteRefSupertype() { + assertTrue( + ConcreteReference.withClazz(List.class) + .isAssignableFrom( + VaporReference.builder() + .setName("ArrayList") + .setPakkage("java.util") + .setSupertypeReference(ConcreteReference.withClazz(List.class)) + .build())); + assertTrue( + ConcreteReference.withClazz(List.class) + .isAssignableFrom( + VaporReference.builder() + .setName("SpecialArrayList") + .setPakkage("com.foo.bar") + .setSupertypeReference(ConcreteReference.withClazz(ArrayList.class)) + .build())); + assertFalse( + ConcreteReference.withClazz(List.class) + .isAssignableFrom( + VaporReference.builder() + .setName("HashMap") + .setPakkage("java.util") + .setSupertypeReference(ConcreteReference.withClazz(Map.class)) + .build())); + } } diff --git a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java index 352b52379e..5a936b61b3 100644 --- a/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/ImportWriterVisitorTest.java @@ -76,6 +76,36 @@ public void setUp() { writerVisitor.initialize(CURRENT_PACKAGE, CURRENT_CLASS); } + @Test + public void writeReferenceTypeImports_basic() { + TypeNode.withReference(ConcreteReference.withClazz(List.class)).accept(writerVisitor); + assertEquals("import java.util.List;\n\n", writerVisitor.write()); + + writerVisitor.clear(); + TypeNode.withReference( + VaporReference.builder().setName("FooBar").setPakkage("com.foo.bar").build()) + .accept(writerVisitor); + assertEquals("import com.foo.bar.FooBar;\n\n", writerVisitor.write()); + } + + @Test + public void writeReferenceTypeImports_useFullName() { + TypeNode.withReference( + ConcreteReference.builder().setClazz(List.class).setUseFullName(true).build()) + .accept(writerVisitor); + assertEquals("", writerVisitor.write()); + + writerVisitor.clear(); + TypeNode.withReference( + VaporReference.builder() + .setName("FooBar") + .setPakkage("com.foo.bar") + .setUseFullName(true) + .build()) + .accept(writerVisitor); + assertEquals("", writerVisitor.write()); + } + @Test public void writeNewObjectExprImports_basic() { // [Constructing] `new ArrayList<>()` diff --git a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java index 5745b8e01f..bfa090c228 100644 --- a/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java +++ b/src/test/java/com/google/api/generator/engine/writer/JavaWriterVisitorTest.java @@ -107,6 +107,36 @@ public void writePrimitiveArrayType() { assertEquals(writerVisitor.write(), "byte[]"); } + @Test + public void writeReferenceType_basic() { + TypeNode.withReference(ConcreteReference.withClazz(List.class)).accept(writerVisitor); + assertEquals("List", writerVisitor.write()); + + writerVisitor.clear(); + TypeNode.withReference( + VaporReference.builder().setName("FooBar").setPakkage("com.foo.bar").build()) + .accept(writerVisitor); + assertEquals("FooBar", writerVisitor.write()); + } + + @Test + public void writeReferenceType_useFullName() { + TypeNode.withReference( + ConcreteReference.builder().setClazz(List.class).setUseFullName(true).build()) + .accept(writerVisitor); + assertEquals("java.util.List", writerVisitor.write()); + + writerVisitor.clear(); + TypeNode.withReference( + VaporReference.builder() + .setName("FooBar") + .setPakkage("com.foo.bar") + .setUseFullName(true) + .build()) + .accept(writerVisitor); + assertEquals("com.foo.bar.FooBar", writerVisitor.write()); + } + @Test public void writeAnnotation_simple() { AnnotationNode annotation = AnnotationNode.OVERRIDE;