From aff3d507d357f87cda7cfeb4b148faccfcb3ef8b Mon Sep 17 00:00:00 2001 From: Winson Chiu Date: Wed, 5 Oct 2022 16:14:29 +0000 Subject: [PATCH] Propagate class @Immutable.Ignore to references If a class is marked at its header with @Immutable.Ignore, the processor should ignore all usages and references to the class, regardless of it's used as a return type or type arg. Without this change, it was required to mark @Ignore on all of usages of the class. Test: atest android.processor.ImmutabilityProcessorTest#ignoredClass Change-Id: I5cd470d86c6eb8c3358656a6d8f6e2588bdb6c66 --- .../immutability/ImmutabilityProcessor.kt | 9 +++++ .../processor/ImmutabilityProcessorTest.kt | 36 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt b/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt index dfebdccf1d637..f29d9b2a6e81a 100644 --- a/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt +++ b/tools/processors/immutability/src/android/processor/immutability/ImmutabilityProcessor.kt @@ -323,8 +323,15 @@ class ImmutabilityProcessor : AbstractProcessor() { parentPolicyExceptions: Set, nonInterfaceClassFailure: () -> String = { MessageUtils.nonInterfaceReturnFailure() }, ): Boolean { + // Skip if the symbol being considered is itself ignored if (isIgnored(symbol)) return false + + // Skip if the type being checked, like for a typeArg or return type, is ignored if (isIgnored(type)) return false + + // Skip if that typeArg is itself ignored when inspected at the class header level + if (isIgnored(type.asElement())) return false + if (type.isPrimitive) return false if (type.isPrimitiveOrVoid) { printError(parentChain, symbol, MessageUtils.voidReturnFailure()) @@ -355,6 +362,8 @@ class ImmutabilityProcessor : AbstractProcessor() { var anyError = false type.typeArguments.forEachIndexed { index, typeArg -> + if (isIgnored(typeArg.asElement())) return@forEachIndexed + val argError = visitType(parentChain, seenTypesByPolicy, symbol, typeArg, newPolicyExceptions) { MessageUtils.nonInterfaceReturnFailure( diff --git a/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt b/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt index 2f7d59a7f0e58..43caa456a0931 100644 --- a/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt +++ b/tools/processors/immutability/test/android/processor/ImmutabilityProcessorTest.kt @@ -287,6 +287,42 @@ class ImmutabilityProcessorTest { ) } + @Test + fun ignoredClass() = test( + JavaFileObjects.forSourceString( + "$PACKAGE_PREFIX.$DATA_CLASS_NAME", + /* language=JAVA */ """ + package $PACKAGE_PREFIX; + + import java.util.List; + import java.util.Map; + + @Immutable + public interface $DATA_CLASS_NAME { + IgnoredClass getInnerClassOne(); + NotIgnoredClass getInnerClassTwo(); + Map getInnerClassThree(); + Map getInnerClassFour(); + + @Immutable.Ignore + final class IgnoredClass { + public String innerField; + } + + final class NotIgnoredClass { + public String innerField; + } + } + """.trimIndent() + ), errors = listOf( + nonInterfaceReturnFailure(line = 9), + nonInterfaceReturnFailure(line = 11, prefix = "Value NotIgnoredClass"), + classNotImmutableFailure(line = 18, className = "NotIgnoredClass"), + nonInterfaceClassFailure(line = 18), + memberNotMethodFailure(line = 19), + ) + ) + private fun test( source: JavaFileObject, errors: List,