Skip to content

Commit 7507180

Browse files
alexfedorenchikcodecholeric
authored andcommitted
Offer a way to retrieve the component type of a JavaClass that is an array.
Issue: #187 Signed-off-by: Alexander Fedorenchik <alexander.fedorenchik@gmail.com>
1 parent 989918f commit 7507180

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

archunit/src/main/java/com/tngtech/archunit/core/domain/ImportContext.java

+2
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,6 @@ public interface ImportContext {
5656
Set<JavaConstructor> getConstructorsWithParameterOfType(JavaClass javaClass);
5757

5858
Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsOfType(JavaClass javaClass);
59+
60+
Optional<JavaClass> resolveComponentType(JavaType type);
5961
}

archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java

+7
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public class JavaClass implements HasName.AndFullName, HasAnnotations, HasModifi
8181
private final Set<JavaClass> interfaces = new HashSet<>();
8282
private final Set<JavaClass> subClasses = new HashSet<>();
8383
private Optional<JavaClass> enclosingClass = Optional.absent();
84+
private Optional<JavaClass> componentType = Optional.absent();
8485
private Supplier<Map<String, JavaAnnotation>> annotations =
8586
Suppliers.ofInstance(Collections.<String, JavaAnnotation>emptyMap());
8687
private Supplier<Set<JavaMethod>> allMethods;
@@ -186,6 +187,11 @@ public boolean isArray() {
186187
return javaType.isArray();
187188
}
188189

190+
@PublicAPI(usage = ACCESS)
191+
Optional<JavaClass> tryGetComponentType() {
192+
return componentType;
193+
}
194+
189195
/**
190196
* @return Returns true if this class is declared within another class.
191197
* Returns false for top-level classes.
@@ -841,6 +847,7 @@ public Map<String, JavaAnnotation> get() {
841847
}
842848

843849
CompletionProcess completeFrom(ImportContext context) {
850+
componentType = context.resolveComponentType(javaType);
844851
enclosingClass = context.createEnclosingClass(this);
845852
memberDependenciesOnClass = new MemberDependenciesOnClass(
846853
context.getFieldsOfType(this),

archunit/src/main/java/com/tngtech/archunit/core/importer/ClassGraphCreator.java

+11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.tngtech.archunit.core.domain.JavaMethod;
4141
import com.tngtech.archunit.core.domain.JavaMethodCall;
4242
import com.tngtech.archunit.core.domain.JavaStaticInitializer;
43+
import com.tngtech.archunit.core.domain.JavaType;
4344
import com.tngtech.archunit.core.domain.ThrowsDeclaration;
4445
import com.tngtech.archunit.core.importer.AccessRecord.FieldAccessRecord;
4546
import com.tngtech.archunit.core.importer.DomainBuilders.JavaConstructorCallBuilder;
@@ -275,6 +276,16 @@ public Optional<JavaClass> createEnclosingClass(JavaClass owner) {
275276
Optional.<JavaClass>absent();
276277
}
277278

279+
@Override
280+
public Optional<JavaClass> resolveComponentType(JavaType array) {
281+
return array.tryGetComponentType().transform(new Function<JavaType, JavaClass>() {
282+
@Override
283+
public JavaClass apply(JavaType input) {
284+
return classes.getOrResolve(input.getName());
285+
}
286+
});
287+
}
288+
278289
private static class MemberDependenciesByTarget {
279290
private final SetMultimap<JavaClass, JavaField> fieldTypeDependencies = HashMultimap.create();
280291
private final SetMultimap<JavaClass, JavaMethod> methodParameterTypeDependencies = HashMultimap.create();

archunit/src/test/java/com/tngtech/archunit/core/domain/JavaClassTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import com.tngtech.archunit.core.domain.testobjects.IsArrayTestClass;
2424
import com.tngtech.archunit.core.domain.testobjects.SuperA;
2525
import com.tngtech.archunit.core.importer.ClassFileImporter;
26+
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassAccessingOneDimensionalArray;
27+
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassAccessingTwoDimensionalArray;
28+
import com.tngtech.archunit.core.importer.testexamples.arrays.ClassUsedInArray;
2629
import com.tngtech.java.junit.dataprovider.DataProvider;
2730
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
2831
import com.tngtech.java.junit.dataprovider.UseDataProvider;
@@ -80,13 +83,28 @@ public void finds_array_type() {
8083
JavaMethod method = importClassWithContext(IsArrayTestClass.class).getMethod("anArray");
8184

8285
assertThat(method.getRawReturnType().isArray()).isTrue();
86+
assertThat(method.getRawReturnType().tryGetComponentType().get().getName()).isEqualTo("java.lang.Object");
8387
}
8488

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

8993
assertThat(method.getRawReturnType().isArray()).isFalse();
94+
assertThat(method.getRawReturnType().tryGetComponentType().isPresent()).isFalse();
95+
}
96+
97+
@Test
98+
public void finds_multidimensional_array_type() {
99+
JavaClasses classes = importClassesWithContext(ClassUsedInArray.class, ClassAccessingOneDimensionalArray.class, ClassAccessingTwoDimensionalArray.class);
100+
JavaClass type = classes.get(ClassUsedInArray.class);
101+
JavaClass oneDimArray = classes.get(ClassAccessingOneDimensionalArray.class).getField("array").getRawType();
102+
JavaClass twoDimArray = classes.get(ClassAccessingTwoDimensionalArray.class).getField("array").getRawType();
103+
104+
assertThat(oneDimArray.isArray()).isTrue();
105+
assertThat(oneDimArray.tryGetComponentType().get()).isEqualTo(type);
106+
assertThat(twoDimArray.isArray()).isTrue();
107+
assertThat(twoDimArray.tryGetComponentType().get()).isEqualTo(oneDimArray);
90108
}
91109

92110
@Test

archunit/src/test/java/com/tngtech/archunit/core/importer/ImportTestUtils.java

+5
Original file line numberDiff line numberDiff line change
@@ -428,5 +428,10 @@ public Set<JavaConstructor> getConstructorsWithParameterOfType(JavaClass javaCla
428428
public Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsOfType(JavaClass javaClass) {
429429
return Collections.emptySet();
430430
}
431+
432+
@Override
433+
public Optional<JavaClass> resolveComponentType(JavaType type) {
434+
return Optional.absent();
435+
}
431436
}
432437
}

0 commit comments

Comments
 (0)