diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/AccessRecord.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/AccessRecord.java index 9ef25c6b3b..c1063f8a7d 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/AccessRecord.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/AccessRecord.java @@ -245,9 +245,9 @@ private static class RawAccessRecordProcessed imple RawAccessRecordProcessed(RawAccessRecord record, ImportedClasses classes, AccessTargetFactory accessTargetFactory) { this.record = record; this.classes = classes; - targetOwner = this.classes.getOrResolve(record.target.owner.getFullyQualifiedClassName()); + targetOwner = this.classes.getOrResolve(record.getTarget().owner.getFullyQualifiedClassName()); this.accessTargetFactory = accessTargetFactory; - originSupplier = createOriginSupplier(record.caller, classes); + originSupplier = createOriginSupplier(record.getOrigin(), classes); } @Override @@ -257,17 +257,17 @@ public JavaCodeUnit getOrigin() { @Override public TARGET getTarget() { - return accessTargetFactory.create(targetOwner, record.target, classes); + return accessTargetFactory.create(targetOwner, record.getTarget(), classes); } @Override public int getLineNumber() { - return record.lineNumber; + return record.getLineNumber(); } @Override public boolean isDeclaredInLambda() { - return record.declaredInLambda; + return record.isDeclaredInLambda(); } @Override diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileImportRecord.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileImportRecord.java index 857ca2d69e..68487abfc9 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileImportRecord.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileImportRecord.java @@ -217,13 +217,13 @@ Set getTryCatchBlockBuildersFor(JavaCodeUnit codeUnit) { } void registerFieldAccess(RawAccessRecord.ForField record) { - if (!isSyntheticEnumSwitchMapFieldName(record.target.name)) { + if (!isSyntheticEnumSwitchMapFieldName(record.getTarget().name)) { rawFieldAccessRecords.add(record); } } void registerMethodCall(RawAccessRecord record) { - if (isSyntheticAccessMethodName(record.target.name)) { + if (isSyntheticAccessMethodName(record.getTarget().name)) { syntheticPrivateAccessRecorder.registerSyntheticMethodInvocation(record); } else { rawMethodCallRecords.add(record); @@ -281,9 +281,9 @@ void forEachRawConstructorReferenceRecord(Consumer doWithRecord ).forEach(doWithRecord); } - private Stream fixSyntheticOrigins( + private > Stream fixSyntheticOrigins( Set rawAccessRecordsIncludingSyntheticAccesses, - Function> createAccessWithNewOrigin, + Function> createAccessWithNewOrigin, SyntheticAccessRecorder... syntheticAccessRecorders ) { @@ -303,25 +303,26 @@ Map getClasses() { } private static final Function COPY_RAW_ACCESS_RECORD = - access -> new RawAccessRecord.Builder() - .withCaller(access.caller) - .withTarget(access.target) - .withLineNumber(access.lineNumber) - .withDeclaredInLambda(access.declaredInLambda); + access -> copyInto(new RawAccessRecord.Builder(), access); private static final Function COPY_RAW_FIELD_ACCESS_RECORD = - access -> new RawAccessRecord.ForField.Builder() - .withCaller(access.caller) - .withAccessType(access.accessType) - .withTarget(access.target) - .withLineNumber(access.lineNumber) - .withDeclaredInLambda(access.declaredInLambda); + access -> copyInto(new RawAccessRecord.ForField.Builder(), access) + .withAccessType(access.accessType); + + private static > BUILDER copyInto(BUILDER builder, RawCodeUnitDependency referencedClassObject) { + builder + .withOrigin(referencedClassObject.getOrigin()) + .withTarget(referencedClassObject.getTarget()) + .withLineNumber(referencedClassObject.getLineNumber()) + .withDeclaredInLambda(referencedClassObject.isDeclaredInLambda()); + return builder; + } private static SyntheticAccessRecorder createSyntheticLambdaAccessRecorder() { return new SyntheticAccessRecorder( codeUnit -> isLambdaMethodName(codeUnit.getName()), (accessBuilder, newOrigin) -> accessBuilder - .withCaller(newOrigin) + .withOrigin(newOrigin) .withDeclaredInLambda(true) ); } @@ -329,7 +330,7 @@ private static SyntheticAccessRecorder createSyntheticLambdaAccessRecorder() { private static SyntheticAccessRecorder createSyntheticPrivateAccessRecorder() { return new SyntheticAccessRecorder( codeUnit -> isSyntheticAccessMethodName(codeUnit.getName()), - RawAccessRecord.BaseBuilder::withCaller + RawCodeUnitDependencyBuilder::withOrigin ); } @@ -377,54 +378,51 @@ Optional getEnclosingCodeUnit(String ownerName) { private static class SyntheticAccessRecorder { private final SetMultimap rawSyntheticMethodInvocationRecordsByTarget = HashMultimap.create(); private final Predicate isSyntheticOrigin; - private final BiConsumer, CodeUnit> fixOrigin; + private final BiConsumer, CodeUnit> fixOrigin; SyntheticAccessRecorder( Predicate isSyntheticOrigin, - BiConsumer, CodeUnit> fixOrigin + BiConsumer, CodeUnit> fixOrigin ) { this.isSyntheticOrigin = isSyntheticOrigin; this.fixOrigin = fixOrigin; } void registerSyntheticMethodInvocation(RawAccessRecord record) { - rawSyntheticMethodInvocationRecordsByTarget.put(getMemberKey(record.target), record); + rawSyntheticMethodInvocationRecordsByTarget.put(getMemberKey(record.getTarget()), record); } - Set fixSyntheticAccess( + > Set fixSyntheticAccess( ACCESS access, - Function> copyAccess + Function> copyAccess ) { - return isSyntheticOrigin.test(access.caller) + return isSyntheticOrigin.test(access.getOrigin()) ? replaceOriginByFixedOrigin(access, copyAccess) : singleton(access); } - private Set replaceOriginByFixedOrigin( + private > Set replaceOriginByFixedOrigin( ACCESS accessFromSyntheticMethod, - Function> copyAccess + Function> copyAccess ) { Set result = findNonSyntheticOriginOf(accessFromSyntheticMethod) .map(accessWithCorrectOrigin -> { - RawAccessRecord.BaseBuilder copiedBuilder = copyAccess.apply(accessFromSyntheticMethod); - fixOrigin.accept(copiedBuilder, accessWithCorrectOrigin.caller); + RawCodeUnitDependencyBuilder copiedBuilder = copyAccess.apply(accessFromSyntheticMethod); + fixOrigin.accept(copiedBuilder, accessWithCorrectOrigin.getOrigin()); return copiedBuilder.build(); }) .collect(toSet()); if (result.isEmpty()) { - log.warn("Could not find matching origin for synthetic method {}.{}|{}", - accessFromSyntheticMethod.target.getDeclaringClassName(), - accessFromSyntheticMethod.target.name, - accessFromSyntheticMethod.target.getDescriptor()); + log.warn("Could not find matching origin for synthetic method {}", accessFromSyntheticMethod); } return result; } - private Stream findNonSyntheticOriginOf(ACCESS access) { - return isSyntheticOrigin.test(access.caller) - ? rawSyntheticMethodInvocationRecordsByTarget.get(getMemberKey(access.caller)).stream().flatMap(this::findNonSyntheticOriginOf) + private > Stream> findNonSyntheticOriginOf(ACCESS access) { + return isSyntheticOrigin.test(access.getOrigin()) + ? rawSyntheticMethodInvocationRecordsByTarget.get(getMemberKey(access.getOrigin())).stream().flatMap(this::findNonSyntheticOriginOf) : Stream.of(access); } } diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileProcessor.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileProcessor.java index a43b67d441..f092c4b935 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileProcessor.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileProcessor.java @@ -301,7 +301,7 @@ public void onTryCatchBlocksFinished(Set tryCatchBlocks) { private > BUILDER filled(BUILDER builder, TargetInfo target) { return builder - .withCaller(codeUnit) + .withOrigin(codeUnit) .withTarget(target) .withLineNumber(lineNumber); } diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/RawAccessRecord.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawAccessRecord.java index f41fde4fee..a9bcc5ce41 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/RawAccessRecord.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawAccessRecord.java @@ -25,26 +25,46 @@ import static com.google.common.base.Preconditions.checkNotNull; -class RawAccessRecord { - final CodeUnit caller; - final TargetInfo target; - final int lineNumber; - final boolean declaredInLambda; - - RawAccessRecord(CodeUnit caller, TargetInfo target, int lineNumber, boolean declaredInLambda) { - this.caller = checkNotNull(caller); +class RawAccessRecord implements RawCodeUnitDependency { + private final CodeUnit origin; + private final TargetInfo target; + private final int lineNumber; + private final boolean declaredInLambda; + + RawAccessRecord(CodeUnit origin, TargetInfo target, int lineNumber, boolean declaredInLambda) { + this.origin = checkNotNull(origin); this.target = checkNotNull(target); this.lineNumber = lineNumber; this.declaredInLambda = declaredInLambda; } + @Override + public CodeUnit getOrigin() { + return origin; + } + + @Override + public TargetInfo getTarget() { + return target; + } + + @Override + public int getLineNumber() { + return lineNumber; + } + + @Override + public boolean isDeclaredInLambda() { + return declaredInLambda; + } + @Override public String toString() { return getClass().getSimpleName() + "{" + fieldsAsString() + '}'; } private String fieldsAsString() { - return "caller=" + caller + ", target=" + target + ", lineNumber=" + lineNumber; + return "origin=" + origin + ", target=" + target + ", lineNumber=" + lineNumber + ", declaredInLambda=" + declaredInLambda; } interface MemberSignature { @@ -195,33 +215,37 @@ public String toString() { static class Builder extends BaseBuilder { @Override - RawAccessRecord build() { - return new RawAccessRecord(caller, target, lineNumber, declaredInLambda); + public RawAccessRecord build() { + return new RawAccessRecord(origin, target, lineNumber, declaredInLambda); } } - abstract static class BaseBuilder> { - CodeUnit caller; + abstract static class BaseBuilder> implements RawCodeUnitDependencyBuilder { + CodeUnit origin; TargetInfo target; int lineNumber = -1; boolean declaredInLambda = false; - SELF withCaller(CodeUnit caller) { - this.caller = caller; + @Override + public SELF withOrigin(CodeUnit origin) { + this.origin = origin; return self(); } - SELF withTarget(TargetInfo target) { + @Override + public SELF withTarget(TargetInfo target) { this.target = target; return self(); } - SELF withLineNumber(int lineNumber) { + @Override + public SELF withLineNumber(int lineNumber) { this.lineNumber = lineNumber; return self(); } - SELF withDeclaredInLambda(boolean declaredInLambda) { + @Override + public SELF withDeclaredInLambda(boolean declaredInLambda) { this.declaredInLambda = declaredInLambda; return self(); } @@ -230,15 +254,13 @@ SELF withDeclaredInLambda(boolean declaredInLambda) { SELF self() { return (SELF) this; } - - abstract ACCESS build(); } static class ForField extends RawAccessRecord { final AccessType accessType; - private ForField(CodeUnit caller, TargetInfo target, int lineNumber, AccessType accessType, boolean declaredInLambda) { - super(caller, target, lineNumber, declaredInLambda); + private ForField(CodeUnit origin, TargetInfo target, int lineNumber, AccessType accessType, boolean declaredInLambda) { + super(origin, target, lineNumber, declaredInLambda); this.accessType = accessType; } @@ -251,8 +273,8 @@ Builder withAccessType(AccessType accessType) { } @Override - ForField build() { - return new ForField(super.caller, super.target, super.lineNumber, accessType, declaredInLambda); + public ForField build() { + return new ForField(super.origin, super.target, super.lineNumber, accessType, declaredInLambda); } } } diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependency.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependency.java new file mode 100644 index 0000000000..85aea8ae54 --- /dev/null +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependency.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014-2022 TNG Technology Consulting GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.tngtech.archunit.core.importer; + +interface RawCodeUnitDependency { + RawAccessRecord.CodeUnit getOrigin(); + + TARGET getTarget(); + + int getLineNumber(); + + boolean isDeclaredInLambda(); +} diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependencyBuilder.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependencyBuilder.java new file mode 100644 index 0000000000..90f26259df --- /dev/null +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/RawCodeUnitDependencyBuilder.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014-2022 TNG Technology Consulting GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.tngtech.archunit.core.importer; + +import com.tngtech.archunit.core.importer.RawAccessRecord.CodeUnit; + +interface RawCodeUnitDependencyBuilder, TARGET> { + RawCodeUnitDependencyBuilder withOrigin(CodeUnit origin); + + RawCodeUnitDependencyBuilder withTarget(TARGET target); + + RawCodeUnitDependencyBuilder withLineNumber(int lineNumber); + + RawCodeUnitDependencyBuilder withDeclaredInLambda(boolean declaredInLambda); + + CODE_UNIT_DEPENDENCY build(); +}