Filtering for -keepattributes rules
Change-Id: I21ebaf47d3943bbf50d4191be653a5bc88f92691
diff --git a/src/main/java/com/android/tools/r8/processkeeprules/FilteredKeepRulesBuilder.java b/src/main/java/com/android/tools/r8/processkeeprules/FilteredKeepRulesBuilder.java
index 8e4e552..2831df5 100644
--- a/src/main/java/com/android/tools/r8/processkeeprules/FilteredKeepRulesBuilder.java
+++ b/src/main/java/com/android/tools/r8/processkeeprules/FilteredKeepRulesBuilder.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.shaking.ProguardConfigurationParser.ProguardConfigurationSourceParser;
import com.android.tools.r8.shaking.ProguardConfigurationParserConsumer;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
import com.android.tools.r8.shaking.ProguardPathList;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
import com.android.tools.r8.utils.Reporter;
@@ -180,8 +181,26 @@
ProguardConfigurationSourceParser parser,
Position position,
TextPosition positionStart) {
- ensureNewlineAfterComment();
- write(parser, positionStart);
+ ProguardKeepAttributes keepAttributes = ProguardKeepAttributes.fromPatterns(attributesPatterns);
+ if (keepAttributes.lineNumberTable
+ || keepAttributes.runtimeInvisibleAnnotations
+ || keepAttributes.runtimeInvisibleParameterAnnotations
+ || keepAttributes.runtimeInvisibleTypeAnnotations
+ || keepAttributes.sourceFile) {
+ // Comment out the -keepattributes rule.
+ writeComment(parser, positionStart);
+ // Unset the undesired attributes and expand the rule.
+ keepAttributes.lineNumberTable = false;
+ keepAttributes.runtimeInvisibleAnnotations = false;
+ keepAttributes.runtimeInvisibleParameterAnnotations = false;
+ keepAttributes.runtimeInvisibleTypeAnnotations = false;
+ keepAttributes.sourceFile = false;
+ ensureNewlineAfterComment();
+ write(keepAttributes.toString());
+ } else {
+ ensureNewlineAfterComment();
+ write(parser, positionStart);
+ }
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 8697204..0f36f87 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -1970,6 +1970,9 @@
if (isQuote(quote)) {
expectClosingQuote(quote);
}
+ int lastPatternEndLine = line;
+ int lastPatternEndLineStartPosition = lineStartPosition;
+ int lastPatternEndPosition = position;
while (pattern != null) {
patterns.add(pattern);
skipWhitespace();
@@ -1981,17 +1984,24 @@
if (isQuote(quote)) {
expectClosingQuote(quote);
}
+ lastPatternEndLine = line;
+ lastPatternEndLineStartPosition = lineStartPosition;
+ lastPatternEndPosition = position;
if (pattern == null) {
throw parseError("Expected list element", start);
}
} else {
- pattern = null;
+ break;
}
}
skipWhitespace();
if (!eof() && !hasNextChar('-') && !hasNextChar('@')) {
throw parseError("Unexpected attribute");
}
+ // Position the parser at the end of the rule before notifying the configuration consumer.
+ line = lastPatternEndLine;
+ lineStartPosition = lastPatternEndLineStartPosition;
+ position = lastPatternEndPosition;
return patterns;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepAttributes.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepAttributes.java
index cf407e6..e0848b0 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepAttributes.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepAttributes.java
@@ -224,60 +224,58 @@
public StringBuilder append(StringBuilder builder) {
List<String> attributes = new ArrayList<>();
- if (sourceFile) {
- attributes.add(SOURCE_FILE);
- }
- if (innerClasses) {
- attributes.add(INNER_CLASSES);
+ if (annotationDefault) {
+ attributes.add(ANNOTATION_DEFAULT);
}
if (enclosingMethod) {
attributes.add(ENCLOSING_METHOD);
}
- if (signature) {
- attributes.add(SIGNATURE);
- }
if (exceptions) {
attributes.add(EXCEPTIONS);
}
+ if (innerClasses) {
+ attributes.add(INNER_CLASSES);
+ }
if (methodParameters) {
attributes.add(METHOD_PARAMETERS);
}
- if (sourceDebugExtension) {
- attributes.add(SOURCE_DEBUG_EXTENSION);
- }
- if (runtimeVisibleAnnotations) {
- attributes.add(RUNTIME_VISIBLE_ANNOTATIONS);
+ if (permittedSubclasses) {
+ attributes.add(PERMITTED_SUBCLASSES);
}
if (runtimeInvisibleAnnotations) {
attributes.add(RUNTIME_INVISIBLE_ANNOTATIONS);
}
- if (runtimeVisibleParameterAnnotations) {
- attributes.add(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
- }
if (runtimeInvisibleParameterAnnotations) {
attributes.add(RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
}
- if (runtimeVisibleTypeAnnotations) {
- attributes.add(RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
- }
if (runtimeInvisibleTypeAnnotations) {
attributes.add(RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
}
- if (annotationDefault) {
- attributes.add(ANNOTATION_DEFAULT);
+ if (runtimeVisibleAnnotations) {
+ attributes.add(RUNTIME_VISIBLE_ANNOTATIONS);
+ }
+ if (runtimeVisibleParameterAnnotations) {
+ attributes.add(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
+ }
+ if (runtimeVisibleTypeAnnotations) {
+ attributes.add(RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+ }
+ if (signature) {
+ attributes.add(SIGNATURE);
+ }
+ if (sourceDebugExtension) {
+ attributes.add(SOURCE_DEBUG_EXTENSION);
+ }
+ if (sourceFile) {
+ attributes.add(SOURCE_FILE);
}
if (stackMapTable) {
attributes.add(STACK_MAP_TABLE);
}
- if (permittedSubclasses) {
- attributes.add(PERMITTED_SUBCLASSES);
- }
-
- if (attributes.size() > 0) {
+ if (!attributes.isEmpty()) {
builder.append("-keepattributes ");
builder.append(String.join(",", attributes));
}
-
return builder;
}
diff --git a/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesCommandTest.java b/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesCommandTest.java
index 92e2034..92fc96a 100644
--- a/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesCommandTest.java
+++ b/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesCommandTest.java
@@ -8,7 +8,6 @@
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.tools.r8.CompilationFailedException;
@@ -115,20 +114,7 @@
}
// Rerun validation after filtering. This should succeed without diagnostics.
- String filteredRules = filter(rules, origin);
- boolean hasKeepAttributes = rules.contains("-keepattributes");
- try {
- validate(
- filteredRules,
- origin,
- diagnostics -> {
- if (!hasKeepAttributes) {
- diagnostics.assertNoMessages();
- }
- });
- } catch (CompilationFailedException e) {
- assertTrue(hasKeepAttributes);
- }
+ validate(filter(rules, origin), origin, TestDiagnosticMessagesImpl::assertNoMessages);
}
private String filter(String rules, Origin origin) throws CompilationFailedException {
diff --git a/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesFilteringTest.java b/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesFilteringTest.java
index 9ce869b..bd1cde6 100644
--- a/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesFilteringTest.java
+++ b/src/test/java/com/android/tools/r8/processkeeprules/ProcessKeepRulesFilteringTest.java
@@ -36,8 +36,8 @@
String keepRules =
StringUtils.unixLines(
" -dontobfuscate -dontoptimize -dontshrink -keep class com.example.MainActivity # keep",
- "# Keep all attributes",
- "-keepattributes *",
+ "# Keep all annotations",
+ "-keepattributes AnnotationDefault,*Annotations*",
"# Keep all",
"-keep class **",
"# Multi line repackageclasses",
@@ -55,8 +55,10 @@
StringUtils.unixLines(
" #-dontobfuscate -dontoptimize -dontshrink ",
"-keep class com.example.MainActivity # keep",
- "# Keep all attributes",
- "-keepattributes *",
+ "# Keep all annotations",
+ "#-keepattributes AnnotationDefault,*Annotations*",
+ "-keepattributes"
+ + " AnnotationDefault,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeVisibleTypeAnnotations",
"# Keep all",
"-keep class **",
"# Multi line repackageclasses",
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 7c65203..5d1c257 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -857,7 +857,7 @@
verifyParserEndsCleanly();
ProguardConfiguration config = builder.build();
assertEquals(
- "-keepattributes RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations",
+ "-keepattributes RuntimeInvisibleAnnotations,RuntimeVisibleAnnotations",
config.getKeepAttributes().toString());
assertEquals(
StringUtils.joinLines("-keep class kotlin.Metadata {", " *;", "}"),