Skip to content

Commit

Permalink
Offer a way to retrieve the component type of a JavaClass that is a…
Browse files Browse the repository at this point in the history
…n array.

Issue: #187

Signed-off-by: Alexander Fedorenchik <alexander.fedorenchik@gmail.com>
  • Loading branch information
alexfedorenchik authored and codecholeric committed Nov 3, 2019
1 parent 989918f commit 7507180
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ public interface ImportContext {
Set<JavaConstructor> getConstructorsWithParameterOfType(JavaClass javaClass);

Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsOfType(JavaClass javaClass);

Optional<JavaClass> resolveComponentType(JavaType type);
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class JavaClass implements HasName.AndFullName, HasAnnotations, HasModifi
private final Set<JavaClass> interfaces = new HashSet<>();
private final Set<JavaClass> subClasses = new HashSet<>();
private Optional<JavaClass> enclosingClass = Optional.absent();
private Optional<JavaClass> componentType = Optional.absent();
private Supplier<Map<String, JavaAnnotation>> annotations =
Suppliers.ofInstance(Collections.<String, JavaAnnotation>emptyMap());
private Supplier<Set<JavaMethod>> allMethods;
Expand Down Expand Up @@ -186,6 +187,11 @@ public boolean isArray() {
return javaType.isArray();
}

@PublicAPI(usage = ACCESS)
Optional<JavaClass> tryGetComponentType() {
return componentType;
}

/**
* @return Returns true if this class is declared within another class.
* Returns false for top-level classes.
Expand Down Expand Up @@ -841,6 +847,7 @@ public Map<String, JavaAnnotation> get() {
}

CompletionProcess completeFrom(ImportContext context) {
componentType = context.resolveComponentType(javaType);
enclosingClass = context.createEnclosingClass(this);
memberDependenciesOnClass = new MemberDependenciesOnClass(
context.getFieldsOfType(this),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaMethodCall;
import com.tngtech.archunit.core.domain.JavaStaticInitializer;
import com.tngtech.archunit.core.domain.JavaType;
import com.tngtech.archunit.core.domain.ThrowsDeclaration;
import com.tngtech.archunit.core.importer.AccessRecord.FieldAccessRecord;
import com.tngtech.archunit.core.importer.DomainBuilders.JavaConstructorCallBuilder;
Expand Down Expand Up @@ -275,6 +276,16 @@ public Optional<JavaClass> createEnclosingClass(JavaClass owner) {
Optional.<JavaClass>absent();
}

@Override
public Optional<JavaClass> resolveComponentType(JavaType array) {
return array.tryGetComponentType().transform(new Function<JavaType, JavaClass>() {
@Override
public JavaClass apply(JavaType input) {
return classes.getOrResolve(input.getName());
}
});
}

private static class MemberDependenciesByTarget {
private final SetMultimap<JavaClass, JavaField> fieldTypeDependencies = HashMultimap.create();
private final SetMultimap<JavaClass, JavaMethod> methodParameterTypeDependencies = HashMultimap.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import com.tngtech.archunit.core.domain.testobjects.IsArrayTestClass;
import com.tngtech.archunit.core.domain.testobjects.SuperA;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassAccessingOneDimensionalArray;
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassAccessingTwoDimensionalArray;
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassUsedInArray;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
Expand Down Expand Up @@ -80,13 +83,28 @@ public void finds_array_type() {
JavaMethod method = importClassWithContext(IsArrayTestClass.class).getMethod("anArray");

assertThat(method.getRawReturnType().isArray()).isTrue();
assertThat(method.getRawReturnType().tryGetComponentType().get().getName()).isEqualTo("java.lang.Object");
}

@Test
public void finds_non_array_type() {
JavaMethod method = importClassWithContext(IsArrayTestClass.class).getMethod("notAnArray");

assertThat(method.getRawReturnType().isArray()).isFalse();
assertThat(method.getRawReturnType().tryGetComponentType().isPresent()).isFalse();
}

@Test
public void finds_multidimensional_array_type() {
JavaClasses classes = importClassesWithContext(ClassUsedInArray.class, ClassAccessingOneDimensionalArray.class, ClassAccessingTwoDimensionalArray.class);
JavaClass type = classes.get(ClassUsedInArray.class);
JavaClass oneDimArray = classes.get(ClassAccessingOneDimensionalArray.class).getField("array").getRawType();
JavaClass twoDimArray = classes.get(ClassAccessingTwoDimensionalArray.class).getField("array").getRawType();

assertThat(oneDimArray.isArray()).isTrue();
assertThat(oneDimArray.tryGetComponentType().get()).isEqualTo(type);
assertThat(twoDimArray.isArray()).isTrue();
assertThat(twoDimArray.tryGetComponentType().get()).isEqualTo(oneDimArray);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,5 +428,10 @@ public Set<JavaConstructor> getConstructorsWithParameterOfType(JavaClass javaCla
public Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsOfType(JavaClass javaClass) {
return Collections.emptySet();
}

@Override
public Optional<JavaClass> resolveComponentType(JavaType type) {
return Optional.absent();
}
}
}

0 comments on commit 7507180

Please sign in to comment.