Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ public static void completeClassHierarchy(JavaClass javaClass, ImportContext imp
javaClass.completeClassHierarchyFrom(importContext);
}

public static void completePackage(JavaClass javaClass, ImportContext importContext) {
javaClass.completePackageInfoFrom(importContext);
}

public static void completeEnclosingDeclaration(JavaClass javaClass, ImportContext importContext) {
javaClass.completeEnclosingDeclarationFrom(importContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.tngtech.archunit.core.domain;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -1429,6 +1430,13 @@ void completeClassHierarchyFrom(ImportContext context) {
completionProcess.markClassHierarchyComplete();
}

void completePackageInfoFrom(ImportContext context) {
this.javaPackage = JavaPackage.from(Arrays.asList(
this,
context.resolveClass(this.getPackageName() + ".package-info")));
completionProcess.markPackageComplete();
}

private void completeSuperclassFrom(ImportContext context) {
Optional<JavaClass> rawSuperclass = context.createSuperclass(this);
if (rawSuperclass.isPresent()) {
Expand Down Expand Up @@ -1663,6 +1671,10 @@ public void markAnnotationsComplete() {
@Override
public void markDependenciesComplete() {
}

@Override
public void markPackageComplete() {
}
};

abstract boolean hasFinished();
Expand All @@ -1683,6 +1695,8 @@ public void markDependenciesComplete() {

public abstract void markDependenciesComplete();

public abstract void markPackageComplete();

static CompletionProcess start() {
return new FullCompletionProcess();
}
Expand All @@ -1701,6 +1715,7 @@ private static class FullCompletionProcess extends CompletionProcess {
private boolean membersComplete = false;
private boolean annotationsComplete = false;
private boolean dependenciesComplete = false;
private boolean packageComplete = false;

@Override
boolean hasFinished() {
Expand All @@ -1711,7 +1726,8 @@ boolean hasFinished() {
&& genericInterfacesComplete
&& membersComplete
&& annotationsComplete
&& dependenciesComplete;
&& dependenciesComplete
&& packageComplete;
}

@Override
Expand Down Expand Up @@ -1753,6 +1769,11 @@ public void markAnnotationsComplete() {
public void markDependenciesComplete() {
this.dependenciesComplete = true;
}

@Override
public void markPackageComplete() {
this.packageComplete = true;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ public void onNewClass(String className, Optional<String> superclassName, List<S
}
importRecord.addInterfaces(ownerName, interfaceNames);
dependencyResolutionProcess.registerSupertypes(interfaceNames);
}
if(!className.endsWith(".package-info")) {
String packageName = className.substring(0, className.lastIndexOf("."));
dependencyResolutionProcess.registerPackageInfo(packageName + ".package-info");
}
}

@Override
public void onDeclaredTypeParameters(JavaClassTypeParametersBuilder typeParametersBuilder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.completeGenericInterfaces;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.completeGenericSuperclass;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.completeMembers;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.completePackage;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.completeTypeParameters;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.createInstanceofCheck;
import static com.tngtech.archunit.core.domain.DomainObjectCreationContext.createJavaClasses;
Expand Down Expand Up @@ -119,6 +120,7 @@ private void completeClasses() {
completeGenericInterfaces(javaClass, this);
completeMembers(javaClass, this);
completeAnnotations(javaClass, this);
completePackage(javaClass, this);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ class DependencyResolutionProcess {
private final int maxRunsForGenericSignatureTypes = getConfiguredIterations(
MAX_ITERATIONS_FOR_GENERIC_SIGNATURE_TYPES_PROPERTY_NAME, MAX_ITERATIONS_FOR_GENERIC_SIGNATURE_TYPES_DEFAULT_VALUE);

static final String MAX_ITERATIONS_FOR_PACKAGE_INFO_PROPERTY_NAME = "maxIterationsForPackageInfo";
static final int MAX_ITERATIONS_FOR_PACKAGE_INFO_DEFAULT_VALUE = -1;
private final int maxRunsForPackageInfo = getConfiguredIterations(
MAX_ITERATIONS_FOR_PACKAGE_INFO_PROPERTY_NAME, MAX_ITERATIONS_FOR_PACKAGE_INFO_DEFAULT_VALUE);

private Set<String> currentTypeNames = new HashSet<>();
private int runNumber = 1;
private boolean shouldContinue;
Expand Down Expand Up @@ -116,6 +121,12 @@ void registerGenericSignatureType(String typeName) {
}
}

void registerPackageInfo(String typeName) {
if (runNumberHasNotExceeded(maxRunsForPackageInfo)) {
currentTypeNames.add(typeName);
}
}

void resolve(ImportedClasses classes) {
logConfiguration();
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
Expand Down Expand Up @@ -121,7 +122,12 @@ public static <T> MetricsComponents<T> from(Collection<T> elements, Function<? s
public static MetricsComponents<JavaClass> fromPackages(Collection<JavaPackage> packages) {
ImmutableSet.Builder<MetricsComponent<JavaClass>> components = ImmutableSet.builder();
for (JavaPackage javaPackage : packages) {
components.add(MetricsComponent.of(javaPackage.getName(), javaPackage.getClassesInPackageTree()));
components.add(MetricsComponent.of(
javaPackage.getName(),
javaPackage.getClassesInPackageTree().stream()
.filter(jc -> !jc.getSimpleName().equals("package-info"))
.collect(Collectors.toList())
));
}
return MetricsComponents.of(components.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.tngtech.archunit.base.ArchUnitException.InvalidSyntaxUsageException;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.base.HasDescription;
import com.tngtech.archunit.core.domain.packageexamples.annotated.PackageLevelAnnotation;
import com.tngtech.archunit.core.domain.packageexamples.annotated.WithinAnnotatedPackage;
import com.tngtech.archunit.core.domain.testobjects.AAccessingB;
import com.tngtech.archunit.core.domain.testobjects.AExtendingSuperAImplementingInterfaceForA;
import com.tngtech.archunit.core.domain.testobjects.AReferencingB;
Expand Down Expand Up @@ -1595,6 +1597,15 @@ public void function_getPackage() {
.isEqualTo(javaClass.getPackageName());
}

@Test
public void function_getPackageInfo() {
JavaClass javaClass = importClassWithContext(WithinAnnotatedPackage.class);

assertThat(javaClass.getPackage().isAnnotatedWith(PackageLevelAnnotation.class))
.as("package info is available")
.isTrue();
}

@Test
public void functions_get_members() {
JavaClass javaClass = importClassWithContext(ClassWithSeveralConstructorsFieldsAndMethods.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.tngtech.archunit.core.domain.packageexamples.annotated;

public class WithinAnnotatedPackage {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.function.Supplier;

Expand All @@ -22,17 +23,20 @@
import com.tngtech.archunit.core.domain.JavaConstructorCall;
import com.tngtech.archunit.core.domain.JavaConstructorReference;
import com.tngtech.archunit.core.domain.JavaEnumConstant;
import com.tngtech.archunit.core.domain.JavaField;
import com.tngtech.archunit.core.domain.JavaFieldAccess;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaMethodCall;
import com.tngtech.archunit.core.domain.JavaMethodReference;
import com.tngtech.archunit.core.domain.JavaPackage;
import com.tngtech.archunit.core.domain.JavaParameterizedType;
import com.tngtech.archunit.core.domain.JavaType;
import com.tngtech.archunit.core.domain.JavaWildcardType;
import com.tngtech.archunit.core.domain.ReferencedClassObject;
import com.tngtech.archunit.core.domain.ThrowsDeclaration;
import com.tngtech.archunit.core.domain.properties.HasAnnotations;
import com.tngtech.archunit.core.importer.DependencyResolutionProcessTestUtils.ImporterWithAdjustedResolutionRuns;
import com.tngtech.archunit.core.importer.testexamples.OtherClass;
import com.tngtech.archunit.core.importer.testexamples.SomeAnnotation;
import com.tngtech.archunit.core.importer.testexamples.annotatedclassimport.ClassWithUnimportedAnnotation;
import com.tngtech.archunit.core.importer.testexamples.annotatedparameters.ClassWithMethodWithAnnotatedParameters;
Expand All @@ -44,9 +48,11 @@
import com.tngtech.archunit.core.importer.testexamples.annotationresolution.SomeAnnotationWithAnnotationParameter;
import com.tngtech.archunit.core.importer.testexamples.annotationresolution.SomeAnnotationWithClassParameter;
import com.tngtech.archunit.core.importer.testexamples.classhierarchyresolution.Child;
import com.tngtech.archunit.core.importer.testexamples.packageinforesolution.ClassThatReferencesOtherClass;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -59,6 +65,7 @@
import static com.tngtech.archunit.core.importer.DependencyResolutionProcess.MAX_ITERATIONS_FOR_GENERIC_SIGNATURE_TYPES_PROPERTY_NAME;
import static com.tngtech.archunit.core.importer.DependencyResolutionProcess.MAX_ITERATIONS_FOR_MEMBER_TYPES_PROPERTY_NAME;
import static com.tngtech.archunit.core.importer.DependencyResolutionProcess.MAX_ITERATIONS_FOR_SUPERTYPES_PROPERTY_NAME;
import static com.tngtech.archunit.core.importer.DependencyResolutionProcess.MAX_ITERATIONS_FOR_PACKAGE_INFO_PROPERTY_NAME;
import static com.tngtech.archunit.core.importer.testexamples.SomeEnum.OTHER_VALUE;
import static com.tngtech.archunit.core.importer.testexamples.SomeEnum.SOME_VALUE;
import static com.tngtech.archunit.core.importer.testexamples.annotatedparameters.ClassWithMethodWithAnnotatedParameters.methodWithOneAnnotatedParameterWithTwoAnnotations;
Expand Down Expand Up @@ -620,6 +627,33 @@ class Innermost {
assertThatType(outermost).matches(Outermost.class);
}

@Test
public void automatically_resolves_packages() {
JavaClass otherClass = new ClassFileImporter()
.importClass(OtherClass.class);

JavaPackage checkedClassPackageInfo = otherClass.getPackage();
assertThat(checkedClassPackageInfo.getAnnotations()).hasSize(1);
assertThat(checkedClassPackageInfo.isAnnotatedWith(SomeAnnotation.class)).isTrue();
}

@Test
public void automatically_resolves_dependency_packages() {
JavaClass checkedClass = ImporterWithAdjustedResolutionRuns
.disableAllIterationsExcept(MAX_ITERATIONS_FOR_PACKAGE_INFO_PROPERTY_NAME, MAX_ITERATIONS_FOR_MEMBER_TYPES_PROPERTY_NAME)
.importClass(ClassThatReferencesOtherClass.class);

Optional<JavaField> firstField = checkedClass.getAllFields().stream().findFirst();
assertThat(firstField).isPresent();
JavaClass otherClass = firstField.get().getRawType();
assertThat(otherClass).isFullyImported(true);

JavaPackage otherClassPackageInfo = otherClass.getPackage();

Assertions.assertThat(otherClassPackageInfo.getAnnotations()).hasSize(1);
Assertions.assertThat(otherClassPackageInfo.isAnnotatedWith(SomeAnnotation.class)).isTrue();
}

@DataProvider
public static Object[][] data_automatically_resolves_generic_type_parameter_bounds() {
@SuppressWarnings("unused")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.tngtech.archunit.core.importer.testexamples.packageinforesolution;

import com.tngtech.archunit.core.importer.testexamples.OtherClass;

public class ClassThatReferencesOtherClass {
OtherClass otherClass;
}