Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aff3d507 authored by Winson Chiu's avatar Winson Chiu
Browse files

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
parent afd1ca4a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -323,8 +323,15 @@ class ImmutabilityProcessor : AbstractProcessor() {
        parentPolicyExceptions: Set<Immutable.Policy.Exception>,
        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(
+36 −0
Original line number Diff line number Diff line
@@ -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<String, IgnoredClass> getInnerClassThree();
                Map<String, NotIgnoredClass> 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<CompilationError>,