Add commandline options for assertion configuration
This also enables assertion configuration for L8.
Bug: 139898386
Change-Id: Icbdd0f5f289eb3d121464a283e9bfbb25c13f095
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommandParser.java b/src/main/java/com/android/tools/r8/BaseCompilerCommandParser.java
index 2915114..7dd1027 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommandParser.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommandParser.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.StringDiagnostic;
@@ -10,10 +11,28 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Arrays;
-public class BaseCompilerCommandParser {
+public class BaseCompilerCommandParser<
+ C extends BaseCompilerCommand, B extends BaseCompilerCommand.Builder<C, B>> {
- static void parseMinApi(BaseCompilerCommand.Builder builder, String minApiString, Origin origin) {
+ static final Iterable<String> ASSERTIONS_USAGE_MESSAGE =
+ Arrays.asList(
+ " --force-enable-assertions[:[<class name>|<package name>...]]",
+ " --force-ea[:[<class name>|<package name>...]]",
+ " # Forcefully enable javac generated assertion code.",
+ " --force-disable-assertions[:[<class name>|<package name>...]]",
+ " --force-da[:[<class name>|<package name>...]]",
+ " # Forcefully disable javac generated assertion code. This",
+ " # is the default handling of javac assertion code when",
+ " # generating DEX file format.",
+ " --force-passthrough-assertions[:[<class name>|<package name>...]]",
+ " --force-pa[:[<class name>|<package name>...]]",
+ " # Don't change javac generated assertion code. This",
+ " # is the default handling of javac assertion code when",
+ " # generating class file format.");
+
+ void parseMinApi(B builder, String minApiString, Origin origin) {
int minApi;
try {
minApi = Integer.parseInt(minApiString);
@@ -28,6 +47,81 @@
builder.setMinApiLevel(minApi);
}
+ private static String PACAKGE_ASSERTION_POSTFIX = "...";
+
+ private void addAssertionTransformation(
+ B builder, AssertionTransformation transformation, String scope) {
+ if (scope == null) {
+ builder.addAssertionsConfiguration(
+ b -> b.setTransformation(transformation).setScopeAll().build());
+ } else {
+ assert scope.length() > 0;
+ if (scope.endsWith(PACAKGE_ASSERTION_POSTFIX)) {
+ builder.addAssertionsConfiguration(
+ b ->
+ b.setTransformation(transformation)
+ .setScopePackage(
+ scope.substring(0, scope.length() - PACAKGE_ASSERTION_POSTFIX.length()))
+ .build());
+ } else {
+ builder.addAssertionsConfiguration(
+ b -> b.setTransformation(transformation).setScopeClass(scope).build());
+ }
+ }
+ }
+
+ boolean tryParseAssertionArgument(B builder, String arg, Origin origin) {
+ String FORCE_ENABLE_ASSERTIONS = "--force-enable-assertions";
+ String FORCE_EA = "--force-ea";
+ String FORCE_DISABLE_ASSERTIONS = "--force-disable-assertions";
+ String FORCE_DA = "--force-da";
+ String FORCE_PASSTHROUGH_ASSERTIONS = "--force-passthrough-assertions";
+ String FORCE_PA = "--force-pa";
+
+ AssertionTransformation transformation = null;
+ String remaining = null;
+ if (arg.startsWith(FORCE_ENABLE_ASSERTIONS)) {
+ transformation = AssertionTransformation.ENABLE;
+ remaining = arg.substring(FORCE_ENABLE_ASSERTIONS.length());
+ } else if (arg.startsWith(FORCE_EA)) {
+ transformation = AssertionTransformation.ENABLE;
+ remaining = arg.substring(FORCE_EA.length());
+ } else if (arg.startsWith(FORCE_DISABLE_ASSERTIONS)) {
+ transformation = AssertionTransformation.DISABLE;
+ remaining = arg.substring(FORCE_DISABLE_ASSERTIONS.length());
+ } else if (arg.startsWith(FORCE_DA)) {
+ transformation = AssertionTransformation.DISABLE;
+ remaining = arg.substring(FORCE_DA.length());
+ } else if (arg.startsWith(FORCE_PASSTHROUGH_ASSERTIONS)) {
+ transformation = AssertionTransformation.PASSTHROUGH;
+ remaining = arg.substring(FORCE_PASSTHROUGH_ASSERTIONS.length());
+ } else if (arg.startsWith(FORCE_PA)) {
+ transformation = AssertionTransformation.PASSTHROUGH;
+ remaining = arg.substring(FORCE_PA.length());
+ }
+ if (transformation != null) {
+ if (remaining.length() == 0) {
+ addAssertionTransformation(builder, transformation, null);
+ return true;
+ } else {
+ if (remaining.length() == 1 || remaining.charAt(0) != ':') {
+ return false;
+ }
+ String classOrPackageScope = remaining.substring(1);
+ if (classOrPackageScope.contains(";")
+ || classOrPackageScope.contains("[")
+ || classOrPackageScope.contains("/")) {
+ builder.error(
+ new StringDiagnostic("Illegal assertion scope: " + classOrPackageScope, origin));
+ }
+ addAssertionTransformation(builder, transformation, remaining.substring(1));
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
/**
* This method must match the lookup in
* {@link com.android.tools.r8.JdkClassFileProvider#fromJdkHome}.
diff --git a/src/main/java/com/android/tools/r8/D8CommandParser.java b/src/main/java/com/android/tools/r8/D8CommandParser.java
index 1099cf9..fda08a6 100644
--- a/src/main/java/com/android/tools/r8/D8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/D8CommandParser.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.nio.file.Files;
@@ -21,7 +22,7 @@
import java.util.List;
import java.util.Set;
-public class D8CommandParser extends BaseCompilerCommandParser {
+public class D8CommandParser extends BaseCompilerCommandParser<D8Command, D8Command.Builder> {
private static final Set<String> OPTIONS_WITH_PARAMETER =
ImmutableSet.of(
@@ -108,31 +109,33 @@
static final String USAGE_MESSAGE =
String.join(
"\n",
- Arrays.asList(
- "Usage: d8 [options] <input-files>",
- " where <input-files> are any combination of dex, class, zip, jar, or apk files",
- " and options are:",
- " --debug # Compile with debugging information (default).",
- " --release # Compile without debugging information.",
- " --output <file> # Output result in <outfile>.",
- " # <file> must be an existing directory or a zip file.",
- " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
- " --classpath <file> # Add <file> as a classpath resource.",
- " --min-api <number> # Minimum Android API level compatibility, default: "
- + AndroidApiLevel.getDefault().getLevel()
- + ".",
- " --intermediate # Compile an intermediate result intended for later",
- " # merging.",
- " --file-per-class # Produce a separate dex file per input class",
- " --no-desugaring # Force disable desugaring.",
- " --desugared-lib <file> # Specify desugared library configuration.",
- " # <file> is a desugared library configuration (json).",
- " --main-dex-list <file> # List of classes to place in the primary dex file.",
- " --main-dex-list-output <file>",
- " # Output resulting main dex list in <file>.",
- " --version # Print the version of d8.",
- " --help # Print this message."));
-
+ Iterables.concat(
+ Arrays.asList(
+ "Usage: d8 [options] <input-files>",
+ " where <input-files> are any combination of dex, class, zip, jar, or apk files",
+ " and options are:",
+ " --debug # Compile with debugging information (default).",
+ " --release # Compile without debugging information.",
+ " --output <file> # Output result in <outfile>.",
+ " # <file> must be an existing directory or a zip file.",
+ " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
+ " --classpath <file> # Add <file> as a classpath resource.",
+ " --min-api <number> # Minimum Android API level compatibility, default: "
+ + AndroidApiLevel.getDefault().getLevel()
+ + ".",
+ " --intermediate # Compile an intermediate result intended for later",
+ " # merging.",
+ " --file-per-class # Produce a separate dex file per input class",
+ " --no-desugaring # Force disable desugaring.",
+ " --desugared-lib <file> # Specify desugared library configuration.",
+ " # <file> is a desugared library configuration (json).",
+ " --main-dex-list <file> # List of classes to place in the primary dex file.",
+ " --main-dex-list-output <file>",
+ " # Output resulting main dex list in <file>."),
+ ASSERTIONS_USAGE_MESSAGE,
+ Arrays.asList(
+ " --version # Print the version of d8.",
+ " --help # Print this message.")));
/**
* Parse the D8 command-line.
*
@@ -143,7 +146,7 @@
* @return D8 command builder with state set up according to parsed command line.
*/
public static D8Command.Builder parse(String[] args, Origin origin) {
- return parse(args, origin, D8Command.builder());
+ return new D8CommandParser().parse(args, origin, D8Command.builder());
}
/**
@@ -157,10 +160,10 @@
* @return D8 command builder with state set up according to parsed command line.
*/
public static D8Command.Builder parse(String[] args, Origin origin, DiagnosticsHandler handler) {
- return parse(args, origin, D8Command.builder(handler));
+ return new D8CommandParser().parse(args, origin, D8Command.builder(handler));
}
- private static D8Command.Builder parse(String[] args, Origin origin, D8Command.Builder builder) {
+ private D8Command.Builder parse(String[] args, Origin origin, D8Command.Builder builder) {
CompilationMode compilationMode = null;
Path outputPath = null;
OutputMode outputMode = null;
@@ -250,11 +253,12 @@
builder.setDisableDesugaring(true);
} else if (arg.equals("--desugared-lib")) {
builder.addDesugaredLibraryConfiguration(StringResource.fromFile(Paths.get(nextArg)));
- } else {
- if (arg.startsWith("--")) {
+ } else if (arg.startsWith("--")) {
+ if (!tryParseAssertionArgument(builder, arg, origin)) {
builder.error(new StringDiagnostic("Unknown option: " + arg, origin));
continue;
}
+ } else {
builder.addProgramFiles(Paths.get(arg));
}
}
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 1ddd338..d190d6c 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -15,7 +15,6 @@
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
-import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
@@ -82,6 +81,7 @@
int minApiLevel,
Reporter diagnosticsHandler,
DesugaredLibraryConfiguration libraryConfiguration,
+ List<AssertionsConfiguration> assertionsConfiguration,
DexItemFactory factory) {
super(
inputApp,
@@ -94,7 +94,7 @@
false,
false,
(name, checksum) -> true,
- ImmutableList.of());
+ assertionsConfiguration);
this.d8Command = d8Command;
this.r8Command = r8Command;
this.libraryConfiguration = libraryConfiguration;
@@ -315,6 +315,7 @@
getMinApiLevel(),
getReporter(),
libraryConfiguration,
+ getAssertionsConfiguration(),
factory);
}
}
diff --git a/src/main/java/com/android/tools/r8/L8CommandParser.java b/src/main/java/com/android/tools/r8/L8CommandParser.java
index 1dc83c1..bf35b67 100644
--- a/src/main/java/com/android/tools/r8/L8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/L8CommandParser.java
@@ -10,12 +10,13 @@
import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Set;
-public class L8CommandParser extends BaseCompilerCommandParser {
+public class L8CommandParser extends BaseCompilerCommandParser<L8Command, L8Command.Builder> {
private static final Set<String> OPTIONS_WITH_PARAMETER =
ImmutableSet.of("--output", "--lib", "--min-api", "--desugared-lib");
@@ -32,23 +33,27 @@
static final String USAGE_MESSAGE =
String.join(
"\n",
- Arrays.asList(
- "Usage: l8 [options] <input-files>",
- " where <input-files> are any combination of dex, class, zip, jar, or apk files",
- " and options are:",
- " --debug # Compile with debugging information (default).",
- " --release # Compile without debugging information.",
- " --output <file> # Output result in <outfile>.",
- " # <file> must be an existing directory or a zip file.",
- " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
- " --min-api <number> # Minimum Android API level compatibility, default: "
- + AndroidApiLevel.getDefault().getLevel()
- + ".",
- " --pg-conf <file> # Proguard configuration <file>.",
- " --desugared-lib <file> # Specify desugared library configuration.",
- " # <file> is a desugared library configuration (json).",
- " --version # Print the version of l8.",
- " --help # Print this message."));
+ Iterables.concat(
+ Arrays.asList(
+ "Usage: l8 [options] <input-files>",
+ " where <input-files> are any combination of dex, class, zip, jar, or apk files",
+ " and options are:",
+ " --debug # Compile with debugging information (default).",
+ " --release # Compile without debugging information.",
+ " --output <file> # Output result in <outfile>.",
+ " # <file> must be an existing directory or a zip file.",
+ " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
+ " --min-api <number> # Minimum Android API level compatibility, default: "
+ + AndroidApiLevel.getDefault().getLevel()
+ + ".",
+ " --pg-conf <file> # Proguard configuration <file>.",
+ " --desugared-lib <file> # Specify desugared library configuration.",
+ " # <file> is a desugared library configuration"
+ + " (json)."),
+ ASSERTIONS_USAGE_MESSAGE,
+ Arrays.asList(
+ " --version # Print the version of l8.",
+ " --help # Print this message.")));
/**
* Parse the D8 command-line.
@@ -60,7 +65,7 @@
* @return D8 command builder with state set up according to parsed command line.
*/
public static L8Command.Builder parse(String[] args, Origin origin) {
- return parse(args, origin, L8Command.builder());
+ return new L8CommandParser().parse(args, origin, L8Command.builder());
}
/**
@@ -74,10 +79,10 @@
* @return D8 command builder with state set up according to parsed command line.
*/
public static L8Command.Builder parse(String[] args, Origin origin, DiagnosticsHandler handler) {
- return parse(args, origin, L8Command.builder(handler));
+ return new L8CommandParser().parse(args, origin, L8Command.builder(handler));
}
- private static L8Command.Builder parse(String[] args, Origin origin, L8Command.Builder builder) {
+ private L8Command.Builder parse(String[] args, Origin origin, L8Command.Builder builder) {
CompilationMode compilationMode = null;
Path outputPath = null;
OutputMode outputMode = null;
@@ -139,11 +144,12 @@
builder.addProguardConfigurationFiles(Paths.get(nextArg));
} else if (arg.equals("--desugared-lib")) {
builder.addDesugaredLibraryConfiguration(StringResource.fromFile(Paths.get(nextArg)));
- } else {
- if (arg.startsWith("--")) {
+ } else if (arg.startsWith("--")) {
+ if (!tryParseAssertionArgument(builder, arg, origin)) {
builder.error(new StringDiagnostic("Unknown option: " + arg, origin));
continue;
}
+ } else {
builder.addProgramFiles(Paths.get(arg));
}
}
diff --git a/src/main/java/com/android/tools/r8/R8CommandParser.java b/src/main/java/com/android/tools/r8/R8CommandParser.java
index dd9ab8e..f1541bd 100644
--- a/src/main/java/com/android/tools/r8/R8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/R8CommandParser.java
@@ -8,12 +8,13 @@
import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Set;
-public class R8CommandParser extends BaseCompilerCommandParser {
+public class R8CommandParser extends BaseCompilerCommandParser<R8Command, R8Command.Builder> {
private static final Set<String> OPTIONS_WITH_PARAMETER =
ImmutableSet.of(
@@ -49,36 +50,40 @@
static final String USAGE_MESSAGE =
String.join(
"\n",
- Arrays.asList(
- "Usage: r8 [options] <input-files>",
- " where <input-files> are any combination of dex, class, zip, jar, or apk files",
- " and options are:",
- " --release # Compile without debugging information (default).",
- " --debug # Compile with debugging information.",
- " --dex # Compile program to DEX file format (default).",
- " --classfile # Compile program to Java classfile format.",
- " --output <file> # Output result in <file>.",
- " # <file> must be an existing directory or a zip file.",
- " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
- " --classpath <file> # Add <file> as a classpath resource.",
- " --min-api <number> # Minimum Android API level compatibility, default: "
- + AndroidApiLevel.getDefault().getLevel()
- + ".",
- " --pg-conf <file> # Proguard configuration <file>.",
- " --pg-map-output <file> # Output the resulting name and line mapping to <file>.",
- " --desugared-lib <file> # Specify desugared library configuration.",
- " # <file> is a desugared library configuration (json).",
- " --no-tree-shaking # Force disable tree shaking of unreachable classes.",
- " --no-minification # Force disable minification of names.",
- " --no-data-resources # Ignore all data resources.",
- " --no-desugaring # Force disable desugaring.",
- " --main-dex-rules <file> # Proguard keep rules for classes to place in the",
- " # primary dex file.",
- " --main-dex-list <file> # List of classes to place in the primary dex file.",
- " --main-dex-list-output <file> ",
- " # Output the full main-dex list in <file>.",
- " --version # Print the version of r8.",
- " --help # Print this message."));
+ Iterables.concat(
+ Arrays.asList(
+ "Usage: r8 [options] <input-files>",
+ " where <input-files> are any combination of dex, class, zip, jar, or apk files",
+ " and options are:",
+ " --release # Compile without debugging information (default).",
+ " --debug # Compile with debugging information.",
+ " --dex # Compile program to DEX file format (default).",
+ " --classfile # Compile program to Java classfile format.",
+ " --output <file> # Output result in <file>.",
+ " # <file> must be an existing directory or a zip file.",
+ " --lib <file|jdk-home> # Add <file|jdk-home> as a library resource.",
+ " --classpath <file> # Add <file> as a classpath resource.",
+ " --min-api <number> # Minimum Android API level compatibility, default: "
+ + AndroidApiLevel.getDefault().getLevel()
+ + ".",
+ " --pg-conf <file> # Proguard configuration <file>.",
+ " --pg-map-output <file> # Output the resulting name and line mapping to"
+ + " <file>.",
+ " --desugared-lib <file> # Specify desugared library configuration.",
+ " # <file> is a desugared library configuration (json).",
+ " --no-tree-shaking # Force disable tree shaking of unreachable classes.",
+ " --no-minification # Force disable minification of names.",
+ " --no-data-resources # Ignore all data resources.",
+ " --no-desugaring # Force disable desugaring.",
+ " --main-dex-rules <file> # Proguard keep rules for classes to place in the",
+ " # primary dex file.",
+ " --main-dex-list <file> # List of classes to place in the primary dex file.",
+ " --main-dex-list-output <file> ",
+ " # Output the full main-dex list in <file>."),
+ ASSERTIONS_USAGE_MESSAGE,
+ Arrays.asList(
+ " --version # Print the version of r8.",
+ " --help # Print this message.")));
/**
* Parse the R8 command-line.
*
@@ -213,10 +218,12 @@
builder.addDesugaredLibraryConfiguration(StringResource.fromFile(Paths.get(nextArg)));
} else if (arg.equals("--no-data-resources")) {
state.includeDataResources = false;
- } else {
- if (arg.startsWith("--")) {
+ } else if (arg.startsWith("--")) {
+ if (!tryParseAssertionArgument(builder, arg, argsOrigin)) {
builder.error(new StringDiagnostic("Unknown option: " + arg, argsOrigin));
+ continue;
}
+ } else {
builder.addProgramFiles(Paths.get(arg));
}
}
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index db0baa3..fbacef6 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -13,6 +13,8 @@
import static org.junit.Assert.assertTrue;
import com.android.sdklib.AndroidVersion;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
import com.android.tools.r8.D8CommandParser.OrderedClassFileResourceProvider;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.dex.Marker;
@@ -519,6 +521,51 @@
assertEquals(0, new ZipFile(emptyZip.toFile(), StandardCharsets.UTF_8).size());
}
+ private void checkSingleForceAllAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(1, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.ALL, entries.get(0).getScope());
+ }
+
+ private void checkSingleForceClassAndPackageAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(2, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.CLASS, entries.get(0).getScope());
+ assertEquals("ClassName", entries.get(0).getValue());
+ assertEquals(transformation, entries.get(1).getTransformation());
+ assertEquals(AssertionTransformationScope.PACKAGE, entries.get(1).getScope());
+ assertEquals("PackageName", entries.get(1).getValue());
+ }
+
+ @Test
+ public void forceAssertionOption() throws Exception {
+ checkSingleForceAllAssertion(
+ parse("--force-enable-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceAllAssertion(
+ parse("--force-disable-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceAllAssertion(
+ parse("--force-passthrough-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ checkSingleForceClassAndPackageAssertion(
+ parse("--force-enable-assertions:ClassName", "--force-enable-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse("--force-disable-assertions:ClassName", "--force-disable-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse(
+ "--force-passthrough-assertions:ClassName",
+ "--force-passthrough-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ }
+
@Test(expected = CompilationFailedException.class)
public void missingParameterForLastOption() throws CompilationFailedException {
DiagnosticsChecker.checkErrorsContains(
diff --git a/src/test/java/com/android/tools/r8/L8CommandTest.java b/src/test/java/com/android/tools/r8/L8CommandTest.java
index 558ba0d..060bdbb 100644
--- a/src/test/java/com/android/tools/r8/L8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/L8CommandTest.java
@@ -8,6 +8,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
@@ -182,11 +184,79 @@
@Test
public void desugaredLibrary() throws CompilationFailedException {
- L8Command l8Command = parse("--desugared-lib", "src/library_desugar/desugar_jdk_libs.json");
+ L8Command l8Command =
+ parse("--desugared-lib", ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString());
assertFalse(
l8Command.getInternalOptions().desugaredLibraryConfiguration.getRewritePrefix().isEmpty());
}
+ private void checkSingleForceAllAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(1, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.ALL, entries.get(0).getScope());
+ }
+
+ private void checkSingleForceClassAndPackageAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(2, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.CLASS, entries.get(0).getScope());
+ assertEquals("ClassName", entries.get(0).getValue());
+ assertEquals(transformation, entries.get(1).getTransformation());
+ assertEquals(AssertionTransformationScope.PACKAGE, entries.get(1).getScope());
+ assertEquals("PackageName", entries.get(1).getValue());
+ }
+
+ @Test
+ public void forceAssertionOption() throws Exception {
+ checkSingleForceAllAssertion(
+ parse(
+ "--force-enable-assertions",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceAllAssertion(
+ parse(
+ "--force-disable-assertions",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceAllAssertion(
+ parse(
+ "--force-passthrough-assertions",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ checkSingleForceClassAndPackageAssertion(
+ parse(
+ "--force-enable-assertions:ClassName",
+ "--force-enable-assertions:PackageName...",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse(
+ "--force-disable-assertions:ClassName",
+ "--force-disable-assertions:PackageName...",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse(
+ "--force-passthrough-assertions:ClassName",
+ "--force-passthrough-assertions:PackageName...",
+ "--desugared-lib",
+ ToolHelper.DESUGAR_LIB_JSON_FOR_TESTING.toString())
+ .getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ }
+
private L8Command parse(String... args) throws CompilationFailedException {
return L8Command.parse(args, EmbeddedOrigin.INSTANCE).build();
}
diff --git a/src/test/java/com/android/tools/r8/R8CommandTest.java b/src/test/java/com/android/tools/r8/R8CommandTest.java
index 165b510..cc92bf3 100644
--- a/src/test/java/com/android/tools/r8/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/R8CommandTest.java
@@ -10,6 +10,8 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
+import com.android.tools.r8.AssertionsConfiguration.AssertionTransformationScope;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.dex.Marker;
@@ -632,6 +634,51 @@
runCustomResourceProcessing(false, false, 0);
}
+ private void checkSingleForceAllAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(1, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.ALL, entries.get(0).getScope());
+ }
+
+ private void checkSingleForceClassAndPackageAssertion(
+ List<AssertionsConfiguration> entries, AssertionTransformation transformation) {
+ assertEquals(2, entries.size());
+ assertEquals(transformation, entries.get(0).getTransformation());
+ assertEquals(AssertionTransformationScope.CLASS, entries.get(0).getScope());
+ assertEquals("ClassName", entries.get(0).getValue());
+ assertEquals(transformation, entries.get(1).getTransformation());
+ assertEquals(AssertionTransformationScope.PACKAGE, entries.get(1).getScope());
+ assertEquals("PackageName", entries.get(1).getValue());
+ }
+
+ @Test
+ public void forceAssertionOption() throws Exception {
+ checkSingleForceAllAssertion(
+ parse("--force-enable-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceAllAssertion(
+ parse("--force-disable-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceAllAssertion(
+ parse("--force-passthrough-assertions").getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ checkSingleForceClassAndPackageAssertion(
+ parse("--force-enable-assertions:ClassName", "--force-enable-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.ENABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse("--force-disable-assertions:ClassName", "--force-disable-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.DISABLE);
+ checkSingleForceClassAndPackageAssertion(
+ parse(
+ "--force-passthrough-assertions:ClassName",
+ "--force-passthrough-assertions:PackageName...")
+ .getAssertionsConfiguration(),
+ AssertionTransformation.PASSTHROUGH);
+ }
+
@Test(expected = CompilationFailedException.class)
public void missingParameterForLastOption() throws CompilationFailedException {
DiagnosticsChecker.checkErrorsContains(