Skip to content

Commit

Permalink
add support to detect references of fields in methods
Browse files Browse the repository at this point in the history
This adds a method to the public API of FieldsShould.java to check if a field has been accessed by methods matching a given predicate.

Issue: #857
Signed-off-by: Leonard Husmann <[email protected]>
  • Loading branch information
leonardhusmann authored and codecholeric committed Oct 8, 2023
1 parent 874c0a1 commit f77932e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,18 @@ public static ArchCondition<JavaCodeUnit> onlyBeCalledByConstructorsThat(Describ
origin.is(matching(JavaConstructor.class, predicate)), GET_CALLS_OF_SELF);
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaField> notBeAccessedByMethodsThat(DescribedPredicate<? super JavaMethod> predicate) {
return new ArchCondition<JavaField>("not be accessed by methods that " + predicate.getDescription()) {
@Override
public void check(JavaField field, ConditionEvents events) {
field.getAccessesToSelf().stream()
.filter(access -> access.getOrigin() instanceof JavaMethod && predicate.test((JavaMethod) access.getOrigin()))
.forEach(violation -> events.add(SimpleConditionEvent.violated(field, violation.getDescription())));
}
};
}

/**
* Derives an {@link ArchCondition} from a {@link DescribedPredicate}. Similar to {@link ArchCondition#from(DescribedPredicate)},
* but more conveniently creates a message to be used within a 'have'-sentence.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaField;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ClassesTransformer;
import com.tngtech.archunit.lang.Priority;
Expand Down Expand Up @@ -93,4 +94,9 @@ public FieldsShouldInternal haveRawType(DescribedPredicate<? super JavaClass> pr
public FieldsShouldInternal notHaveRawType(DescribedPredicate<? super JavaClass> predicate) {
return addCondition(not(ArchConditions.haveRawType(predicate)));
}

@Override
public FieldsShouldInternal notBeAccessedByMethodsThat(DescribedPredicate<? super JavaMethod> predicate) {
return addCondition(ArchConditions.notBeAccessedByMethodsThat(predicate));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.tngtech.archunit.PublicAPI;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.properties.HasName;
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;

Expand Down Expand Up @@ -156,6 +157,15 @@ public interface FieldsShould<CONJUNCTION extends FieldsShouldConjunction> exten
@PublicAPI(usage = ACCESS)
CONJUNCTION notHaveRawType(DescribedPredicate<? super JavaClass> predicate);

/**
* Asserts that fields are not accessed by methods matching the given predicate.
*
* @param predicate A predicate determining the methods this field should not be accessed by
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION notBeAccessedByMethodsThat(DescribedPredicate<? super JavaMethod> predicate);

/**
* Asserts that fields are static.
*
Expand Down

0 comments on commit f77932e

Please sign in to comment.