Skip to content

Commit b10dde6

Browse files
committed
Review: We have to always ensure the whole component type chain is present. Background is, that if those component types are not referenced in another place (e.g. the two-dim component type is not also a field type somewhere, etc.), we will otherwise create a "simple" class stub here on the fly, and that simple stub will not get processed anymore and thus will not get any component type. In other words, the component type chain would then be broken.
Issue: #187 Signed-off-by: Peter Gafert <[email protected]>
1 parent ac545fb commit b10dde6

File tree

5 files changed

+38
-14
lines changed

5 files changed

+38
-14
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,5 @@ public interface ImportContext {
5757

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

60-
Optional<JavaClass> resolveComponentType(JavaType type);
60+
JavaClass resolveClass(String fullyQualifiedClassName);
6161
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ public Map<String, JavaAnnotation> get() {
847847
}
848848

849849
CompletionProcess completeFrom(ImportContext context) {
850-
componentType = context.resolveComponentType(javaType);
850+
completeComponentType(context);
851851
enclosingClass = context.createEnclosingClass(this);
852852
memberDependenciesOnClass = new MemberDependenciesOnClass(
853853
context.getFieldsOfType(this),
@@ -859,6 +859,15 @@ CompletionProcess completeFrom(ImportContext context) {
859859
return new CompletionProcess();
860860
}
861861

862+
private void completeComponentType(ImportContext context) {
863+
JavaClass current = this;
864+
while (current.isArray() && !current.componentType.isPresent()) {
865+
JavaClass componentType = context.resolveClass(current.javaType.tryGetComponentType().get().getName());
866+
current.componentType = Optional.of(componentType);
867+
current = componentType;
868+
}
869+
}
870+
862871
@Override
863872
public String toString() {
864873
return "JavaClass{name='" + javaType.getName() + "\'}";

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
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;
4443
import com.tngtech.archunit.core.domain.ThrowsDeclaration;
4544
import com.tngtech.archunit.core.importer.AccessRecord.FieldAccessRecord;
4645
import com.tngtech.archunit.core.importer.DomainBuilders.JavaConstructorCallBuilder;
@@ -277,13 +276,8 @@ public Optional<JavaClass> createEnclosingClass(JavaClass owner) {
277276
}
278277

279278
@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-
});
279+
public JavaClass resolveClass(String fullyQualifiedClassName) {
280+
return classes.getOrResolve(fullyQualifiedClassName);
287281
}
288282

289283
private static class MemberDependenciesByTarget {
@@ -347,4 +341,4 @@ Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsOfType(J
347341
return constructorThrowsDeclarationDependencies.get(javaClass);
348342
}
349343
}
350-
}
344+
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,27 @@ public void finds_multidimensional_array_type() {
105105
assertThat(oneDimArray.tryGetComponentType().get()).isEqualTo(type);
106106
assertThat(twoDimArray.isArray()).isTrue();
107107
assertThat(twoDimArray.tryGetComponentType().get()).isEqualTo(oneDimArray);
108+
assertThat(twoDimArray.tryGetComponentType().get().tryGetComponentType().get()).isEqualTo(type);
109+
}
110+
111+
@Test
112+
public void finds_component_type_chain_of_otherwise_unreferenced_component_type() {
113+
class OnlyReferencingMultiDimArray {
114+
OnlyReferencingMultiDimArray[][][] field;
115+
}
116+
117+
JavaClass javaClass = importClassesWithContext(OnlyReferencingMultiDimArray.class)
118+
.get(OnlyReferencingMultiDimArray.class);
119+
120+
JavaClass arrayType = javaClass.getField("field").getRawType();
121+
JavaClass twoDim = arrayType.tryGetComponentType().get();
122+
assertThat(twoDim.getName()).isEqualTo(OnlyReferencingMultiDimArray[][].class.getName());
123+
124+
JavaClass oneDim = twoDim.tryGetComponentType().get();
125+
assertThat(oneDim.getName()).isEqualTo(OnlyReferencingMultiDimArray[].class.getName());
126+
127+
JavaClass original = oneDim.tryGetComponentType().get();
128+
assertThat(original).isEqualTo(javaClass);
108129
}
109130

110131
@Test

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ public Set<ThrowsDeclaration<JavaConstructor>> getConstructorThrowsDeclarationsO
430430
}
431431

432432
@Override
433-
public Optional<JavaClass> resolveComponentType(JavaType type) {
434-
return Optional.absent();
433+
public JavaClass resolveClass(String fullyQualifiedClassName) {
434+
throw new UnsupportedOperationException("Override me where necessary");
435435
}
436436
}
437-
}
437+
}

0 commit comments

Comments
 (0)