[KeepAnno] Print keep-annotation meta-info to configuration consumers This adds the meta-info printing and the rest is just toString on the AST. The printing format should likely coincide with the distribution format for normalized edges once that format is chosen. Bug: b/323816623 Change-Id: I338662616ed607392ff891af7853a183293ebc92
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java index 05ee81c..9932654 100644 --- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java +++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
@@ -215,6 +215,12 @@ @Override public String toString() { - return "KeepEdge{" + "preconditions=" + preconditions + ", consequences=" + consequences + '}'; + return "KeepEdge{metainfo=" + + getMetaInfo() + + ", preconditions=" + + preconditions + + ", consequences=" + + consequences + + '}'; } }
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdgeMetaInfo.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdgeMetaInfo.java index 6d4705a..9cf3305 100644 --- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdgeMetaInfo.java +++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdgeMetaInfo.java
@@ -3,6 +3,9 @@ // BSD-style license that can be found in the LICENSE file. package com.android.tools.r8.keepanno.ast; +import com.android.tools.r8.keepanno.keeprules.RulePrintingUtils; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; public class KeepEdgeMetaInfo { @@ -62,6 +65,21 @@ return version; } + public String toString() { + List<String> props = new ArrayList<>(3); + if (hasVersion()) { + props.add("version=" + version); + } + if (hasContext()) { + props.add("context=" + context.getDescriptorString()); + } + if (hasDescription()) { + props.add( + "description=\"" + RulePrintingUtils.escapeLineBreaks(description.description) + "\""); + } + return "MetaInfo{" + String.join(", ", props) + "}"; + } + public static class Builder { private KeepEdgeContext context = KeepEdgeContext.none(); private KeepEdgeDescription description = KeepEdgeDescription.empty();
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java index fe43d5c..dbc94d4 100644 --- a/src/main/java/com/android/tools/r8/R8.java +++ b/src/main/java/com/android/tools/r8/R8.java
@@ -868,6 +868,7 @@ assert appView.dexItemFactory().verifyNoCachedTypeElements(); // Generate the resulting application resources. + writeKeepDeclarationsToConfigurationConsumer(keepDeclarations); writeApplication(appView, inputApp, executorService); if (options.androidResourceProvider != null && options.androidResourceConsumer != null) { @@ -888,6 +889,27 @@ } } + private void writeKeepDeclarationsToConfigurationConsumer( + List<KeepDeclaration> keepDeclarations) { + if (options.configurationConsumer == null) { + return; + } + if (keepDeclarations.isEmpty()) { + return; + } + for (KeepDeclaration declaration : keepDeclarations) { + List<String> lines = StringUtils.splitLines(declaration.toString()); + StringBuilder builder = new StringBuilder(); + builder.append("# Start of content from keep annotations\n"); + for (String line : lines) { + builder.append("# ").append(line).append("\n"); + } + builder.append("# End of content from keep annotations\n"); + ExceptionUtils.withConsumeResourceHandler( + options.reporter, options.configurationConsumer, builder.toString()); + } + } + private static ForwardingConsumer wrapConsumerStoreBytesInList( Map<String, byte[]> dexFileContent, DexIndexedConsumer programConsumer,
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepUsesReflectionOnFieldTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepUsesReflectionOnFieldTest.java index e1c5dd9..905cc81 100644 --- a/src/test/java/com/android/tools/r8/keepanno/KeepUsesReflectionOnFieldTest.java +++ b/src/test/java/com/android/tools/r8/keepanno/KeepUsesReflectionOnFieldTest.java
@@ -38,13 +38,22 @@ @Test public void test() throws Exception { testForKeepAnno(parameters) + .enableNativeInterpretation() .addProgramClasses(getInputClasses()) .addKeepMainRule(TestClass.class) .setExcludedOuterClass(getClass()) .inspectOutputConfig( rules -> { - assertThat(rules, containsString("context: " + descriptor(A.class) + "foo()V")); - assertThat(rules, containsString("description: Keep the\\nstring-valued fields")); + if (parameters.isNativeR8()) { + // TODO(b/323816623): Once a final distribution format is defined for normalized + // edges, that format should likely be the bases of the annotation printing too. + assertThat(rules, containsString("context=" + descriptor(A.class) + "foo()V")); + assertThat( + rules, containsString("description=\"Keep the\\nstring-valued fields\"")); + } else { + assertThat(rules, containsString("context: " + descriptor(A.class) + "foo()V")); + assertThat(rules, containsString("description: Keep the\\nstring-valued fields")); + } }) .run(TestClass.class) .assertSuccessWithOutput(EXPECTED)