Skip to content

Commit

Permalink
Refactor some more anonymous inner classes to static inner classes fo…
Browse files Browse the repository at this point in the history
…r future GC safety

Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
  • Loading branch information
codecholeric committed Jul 29, 2019
1 parent c94512e commit 01f3379
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.common.base.Suppliers;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import com.tngtech.archunit.Internal;
import com.tngtech.archunit.base.Function;
Expand Down Expand Up @@ -190,62 +191,87 @@ void finish() {
}

private Supplier<Set<JavaFieldAccess>> getFieldAccessesTo(final JavaField field) {
return newAccessSupplier(field.getOwner(), fieldAccessTargetResolvesTo(field));
return Suppliers.memoize(new AccessSupplier<>(field.getOwner(), fieldAccessTargetResolvesTo(field)));
}

private Function<JavaClass, Set<JavaFieldAccess>> fieldAccessTargetResolvesTo(final JavaField field) {
return new Function<JavaClass, Set<JavaFieldAccess>>() {
@Override
public Set<JavaFieldAccess> apply(JavaClass input) {
Set<JavaFieldAccess> result = new HashSet<>();
for (JavaFieldAccess access : fieldAccessesByTarget.get(input)) {
if (access.getTarget().resolveField().asSet().contains(field)) {
result.add(access);
}
}
return result;
}
};
return new ClassToFieldAccessesToSelf(fieldAccessesByTarget, field);
}

private Supplier<Set<JavaMethodCall>> getMethodCallsOf(final JavaMethod method) {
return newAccessSupplier(method.getOwner(), methodCallTargetResolvesTo(method));
return Suppliers.memoize(new AccessSupplier<>(method.getOwner(), methodCallTargetResolvesTo(method)));
}

private Function<JavaClass, Set<JavaMethodCall>> methodCallTargetResolvesTo(final JavaMethod method) {
return new Function<JavaClass, Set<JavaMethodCall>>() {
@Override
public Set<JavaMethodCall> apply(JavaClass input) {
Set<JavaMethodCall> result = new HashSet<>();
for (JavaMethodCall call : methodCallsByTarget.get(input)) {
if (call.getTarget().resolve().contains(method)) {
result.add(call);
}
return new ClassToMethodCallsToSelf(methodCallsByTarget, method);
}

private static class ClassToFieldAccessesToSelf implements Function<JavaClass, Set<JavaFieldAccess>> {
private final Multimap<JavaClass, JavaFieldAccess> fieldAccessesByTarget;
private final JavaField field;

ClassToFieldAccessesToSelf(SetMultimap<JavaClass, JavaFieldAccess> fieldAccessesByTarget, JavaField field) {
this.fieldAccessesByTarget = fieldAccessesByTarget;
this.field = field;
}

@Override
public Set<JavaFieldAccess> apply(JavaClass input) {
Set<JavaFieldAccess> result = new HashSet<>();
for (JavaFieldAccess access : fieldAccessesByTarget.get(input)) {
if (access.getTarget().resolveField().asSet().contains(field)) {
result.add(access);
}
return result;
}
};
return result;
}
}

private <T> Supplier<Set<T>> newAccessSupplier(final JavaClass owner, final Function<JavaClass, Set<T>> doWithEachClass) {
private static class ClassToMethodCallsToSelf implements Function<JavaClass, Set<JavaMethodCall>> {
private final Multimap<JavaClass, JavaMethodCall> methodCallsByTarget;
private final JavaMethod method;

ClassToMethodCallsToSelf(SetMultimap<JavaClass, JavaMethodCall> methodCallsByTarget, JavaMethod method) {
this.methodCallsByTarget = methodCallsByTarget;
this.method = method;
}

return Suppliers.memoize(new Supplier<Set<T>>() {
@Override
public Set<T> get() {
ImmutableSet.Builder<T> result = ImmutableSet.builder();
for (final JavaClass javaClass : getPossibleTargetClassesForAccess()) {
result.addAll(doWithEachClass.apply(javaClass));
@Override
public Set<JavaMethodCall> apply(JavaClass input) {
Set<JavaMethodCall> result = new HashSet<>();
for (JavaMethodCall call : methodCallsByTarget.get(input)) {
if (call.getTarget().resolve().contains(method)) {
result.add(call);
}
return result.build();
}
return result;
}
}

private Set<JavaClass> getPossibleTargetClassesForAccess() {
return ImmutableSet.<JavaClass>builder()
.add(owner)
.addAll(owner.getAllSubClasses())
.build();
private static class AccessSupplier<T extends JavaAccess<?>> implements Supplier<Set<T>> {
private final JavaClass owner;
private final Function<JavaClass, Set<T>> mapToAccesses;

AccessSupplier(JavaClass owner, Function<JavaClass, Set<T>> mapToAccesses) {
this.owner = owner;
this.mapToAccesses = mapToAccesses;
}

@Override
public Set<T> get() {
ImmutableSet.Builder<T> result = ImmutableSet.builder();
for (final JavaClass javaClass : getPossibleTargetClassesForAccess()) {
result.addAll(mapToAccesses.apply(javaClass));
}
});
return result.build();
}

private Set<JavaClass> getPossibleTargetClassesForAccess() {
return ImmutableSet.<JavaClass>builder()
.add(owner)
.addAll(owner.getAllSubClasses())
.build();
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,7 @@ public String getName() {
}

public Supplier<Map<String, JavaAnnotation>> getAnnotations() {
return Suppliers.memoize(new Supplier<Map<String, JavaAnnotation>>() {
@Override
public Map<String, JavaAnnotation> get() {
return buildAnnotations(annotations, importedClasses);
}
});
return Suppliers.memoize(new AnnotationsSupplier(annotations, importedClasses));
}

public String getDescriptor() {
Expand All @@ -182,6 +177,21 @@ public final OUTPUT build(JavaClass owner, ClassesByTypeName importedClasses) {
this.importedClasses = importedClasses;
return construct(self(), importedClasses);
}

private static class AnnotationsSupplier implements Supplier<Map<String, JavaAnnotation>> {
private final Set<JavaAnnotationBuilder> annotations;
private final ClassesByTypeName importedClasses;

AnnotationsSupplier(Set<JavaAnnotationBuilder> annotations, ClassesByTypeName importedClasses) {
this.annotations = annotations;
this.importedClasses = importedClasses;
}

@Override
public Map<String, JavaAnnotation> get() {
return buildAnnotations(annotations, importedClasses);
}
}
}

@Internal
Expand Down

0 comments on commit 01f3379

Please sign in to comment.