Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ResolvedType.getAllTypes() returns parent, this, and interfaces #56

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/main/java/com/fasterxml/classmate/ResolvedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ public final boolean canCreateSubtype(Class<?> subtype) {
*/
public abstract List<ResolvedType> getImplementedInterfaces();

/**
* Returns Ordered list of parent, current and interfaces of this type.
*
* @return List of parent, current and interfaces of this type containing at least current type
*/
public List<ResolvedType> getAllTypes() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to resolve super types recursively, as methods called will only include immediate super class, interfaces implemented; but not super types of those types.

I think name should be getAllSuperTypes(); I also think that list should NOT include type itself (so that name makes sense in that context).
It might make sense to refactor this so that were two variants:

  1. getAllSuperTypes() to work as described
  2. addAllSuperTypes(Collection<ResolvedType>) that would add types into given set

... and come to think of this, I realized that List does not quite make sense here, for two reasons:

  1. There is no well-defined ordering for inclusion; for this reason, we could just use Collection. But further,
  2. Since it will be necessary to avoid duplicate interfaces (there are cases where things like java.io.Serializable are implemented via multiple super-interfaces).

So most likely return type really should be Set. This does open up some further questions (should differently parameterized super-types -- say, Comparable<X> vs Comparable<Y>; or, some cases, "raw" variant -- be included once or multiple times), but for now simple equality could work (which would lead to double inclusion for varying type parameters).

Finally, there may be a problem with recusive types (most common being Enum...), so a test for that might be needed. But I can take care of that.

List<ResolvedType> allTypes = new ArrayList<ResolvedType>();
ResolvedType parentClass = getParentClass();
if (parentClass != null) {
allTypes.add(parentClass);
}
allTypes.add(this);
List<ResolvedType> implementedInterfaces = getImplementedInterfaces();
if (implementedInterfaces != null) {
allTypes.addAll(implementedInterfaces);
}

return allTypes;
};

/**
* Returns list of generic type declarations for this type, in order they
* are declared in class description.
Expand Down
23 changes: 22 additions & 1 deletion src/test/java/com/fasterxml/classmate/ResolvedTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ private static class Foo16 extends Bar16 { }
private static class Bar16 extends Zen16<Bar16, Foo16> { }

private static class Zen16<A, B extends A> { }


private static class ClassWithInterfaces implements FirstInterface, SecondInterface { }

interface FirstInterface {}

interface SecondInterface {}

@Test
public void testCanCreateSubtype() {
ResolvedObjectType stringType = ResolvedObjectType.create(String.class, null, null, null);
Expand Down Expand Up @@ -140,4 +146,19 @@ public void testIssue16()
assertEquals(Bar16.class, params.get(0).getErasedType());
assertEquals(Foo16.class, params.get(1).getErasedType());
}

@Test
public void testFindAllClasses() {
TypeResolver resolver = new TypeResolver();
ResolvedType type = resolver.resolve(ClassWithInterfaces.class);

List<ResolvedType> allTypes = type.getAllTypes();

assertNotNull(allTypes);
assertEquals(4, allTypes.size());
assertEquals(Object.class, allTypes.get(0).getErasedType());
assertEquals(ClassWithInterfaces.class, allTypes.get(1).getErasedType());
assertEquals(FirstInterface.class, allTypes.get(2).getErasedType());
assertEquals(SecondInterface.class, allTypes.get(3).getErasedType());
}
}