Merge commit 'e93002edb8c0bd7207fb1f33fe8d2354079abfb1' into dev-release
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index eb5f45e..79ec8a5 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -3,95 +3,78 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
-import com.android.tools.r8.ProgramResource.Kind;
+import static com.android.tools.r8.utils.StringUtils.quote;
+
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker;
-import com.android.tools.r8.dex.VDexParser;
-import com.android.tools.r8.dex.VDexReader;
-import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.MarkerInfoConsumerDataImpl;
+import com.android.tools.r8.utils.MarkerInfoImpl;
+import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.Timing;
-import com.google.common.io.ByteStreams;
import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.concurrent.ExecutionException;
+import java.util.Comparator;
+import java.util.List;
+/**
+ * A tool to extract markers generated by the R8 compiler and related tools.
+ *
+ * <p>The tool is run by defining a consumer and then building the command, such as:
+ *
+ * <pre>
+ * ExtractMarker.run(ExtractMarkerCommand.builder()
+ * .addProgramFiles(inputPathA, inputPathB)
+ * .setMarkerInfoConsumer(new MyInfoConsumer())
+ * .build());
+ * </pre>
+ */
+@Keep
public class ExtractMarker {
- public static class VdexOrigin extends Origin {
- private final int index;
+ private static class MarkerInfoPrintConsumer implements MarkerInfoConsumer {
- public VdexOrigin(Origin vdexOrigin, int index) {
- super(vdexOrigin);
- this.index = index;
+ private final PrintStream stream;
+
+ public MarkerInfoPrintConsumer(PrintStream stream) {
+ this.stream = stream;
+ }
+
+ private void printRow(Origin inputOrigin, String rawMarker) {
+ stream.print(inputOrigin.toString());
+ stream.print(": ");
+ stream.print(rawMarker);
+ stream.println();
}
@Override
- public String part() {
- return Integer.toString(index);
- }
- }
-
- public static Collection<Marker> extractMarkerFromDexFile(Path file)
- throws IOException, ResourceException {
- AndroidApp.Builder appBuilder = AndroidApp.builder();
- addDexResources(appBuilder, file);
- return extractMarker(appBuilder.build());
- }
-
- public static Collection<Marker> extractMarkerFromJarFile(Path file) throws IOException {
- return extractMarker(AndroidApp.builder().addProgramFile(file).build());
- }
-
- public static int extractDexSize(Path file) throws IOException, ResourceException {
- AndroidApp.Builder appBuilder = AndroidApp.builder();
- addDexResources(appBuilder, file);
- int size = 0;
- for (ProgramResource resource : appBuilder.build().computeAllProgramResources()) {
- if (resource.getKind() == Kind.DEX) {
- try (InputStream input = resource.getByteStream()) {
- size += ByteStreams.toByteArray(input).length;
+ public void acceptMarkerInfo(MarkerInfoConsumerData data) {
+ if (data.hasMarkers()) {
+ for (MarkerInfo marker : data.getMarkers()) {
+ printRow(data.getInputOrigin(), marker.getRawEncoding());
}
+ } else {
+ printRow(data.getInputOrigin(), quote("no marker"));
}
}
- return size;
+
+ @Override
+ public void finished() {}
}
- public static Collection<Marker> extractMarkerFromDexProgramData(byte[] data) throws IOException {
- AndroidApp app = AndroidApp.builder().addDexProgramData(data, Origin.unknown()).build();
- return extractMarker(app);
- }
+ private static class InterceptedException extends RuntimeException {
+ private final CompilationFailedException compilationFailedException;
- public static Collection<Marker> extractMarkerFromClassProgramData(byte[] data)
- throws IOException {
- AndroidApp app = AndroidApp.builder().addClassProgramData(data, Origin.unknown()).build();
- return extractMarker(app);
- }
-
- private static void addDexResources(AndroidApp.Builder appBuilder, Path file) throws IOException {
- if (FileUtils.isVDexFile(file)) {
- PathOrigin vdexOrigin = new PathOrigin(file);
- try (InputStream fileInputStream = Files.newInputStream(file)) {
- VDexReader vdexReader = new VDexReader(vdexOrigin, fileInputStream);
- VDexParser vDexParser = new VDexParser(vdexReader);
- int index = 0;
- for (byte[] bytes : vDexParser.getDexFiles()) {
- appBuilder.addDexProgramData(bytes, new VdexOrigin(vdexOrigin, index));
- index++;
- }
- }
- } else {
- appBuilder.addProgramFiles(file);
+ private InterceptedException(CompilationFailedException e) {
+ this.compilationFailedException = e;
}
}
@@ -103,70 +86,67 @@
return dexApp.dexItemFactory.extractMarkers();
}
- public static void main(String[] args)
- throws IOException, ExecutionException, ResourceException {
+ private static void extractForConsumer(
+ MarkerInfoConsumer consumer, Reporter reporter, Origin origin, AndroidApp.Builder builder) {
+ List<Marker> markers = new ArrayList<>();
+ try {
+ ExceptionUtils.withCompilationHandler(
+ reporter, () -> markers.addAll(extractMarker(builder.build())));
+ } catch (CompilationFailedException e) {
+ throw new InterceptedException(e);
+ }
+ // Ensure the markers are sorted, so we have deterministic callback/print order.
+ markers.sort(Comparator.comparing(Marker::toString));
+ List<MarkerInfo> infos = ListUtils.map(markers, MarkerInfoImpl::new);
+ consumer.acceptMarkerInfo(new MarkerInfoConsumerDataImpl(origin, infos));
+ }
+
+ /**
+ * Main API entry for the extract marker tool.
+ *
+ * @param command Extract marker command specification.
+ */
+ public static void run(ExtractMarkerCommand command) throws CompilationFailedException {
+ MarkerInfoConsumer consumer = command.getMarkerInfoConsumer();
+ Reporter reporter = new Reporter(command.getDiagnosticsHandler());
+ try {
+ command.forEachEntry(
+ (path, origin) ->
+ extractForConsumer(
+ consumer, reporter, origin, AndroidApp.builder().addProgramFile(path)),
+ (data, origin) ->
+ extractForConsumer(
+ consumer, reporter, origin, AndroidApp.builder().addDexProgramData(data, origin)),
+ (data, origin) ->
+ extractForConsumer(
+ consumer,
+ reporter,
+ origin,
+ AndroidApp.builder().addClassProgramData(data, origin)));
+ } catch (InterceptedException e) {
+ throw e.compilationFailedException;
+ }
+ }
+
+ private static void run(String[] args) throws CompilationFailedException {
+ PrintStream out = System.out;
ExtractMarkerCommand.Builder builder = ExtractMarkerCommand.parse(args);
- ExtractMarkerCommand command = builder.build();
+ MarkerInfoConsumer consumer = new MarkerInfoPrintConsumer(out);
+ ExtractMarkerCommand command = builder.setMarkerInfoConsumer(consumer).build();
if (command.isPrintHelp()) {
System.out.println(ExtractMarkerCommand.USAGE_MESSAGE);
return;
}
+ run(command);
+ }
- Path cwd = Paths.get(System.getProperty("user.dir"));
- // Dex code is not needed for getting the marker. VDex files typically contains quickened byte
- // codes which cannot be read, and we want to get the marker from vdex files as well.
- int d8Count = 0;
- int r8Count = 0;
- int otherCount = 0;
- for (Path programFile : command.getProgramFiles()) {
- Collection<Marker> markers;
- try {
- markers = extractMarkerFromDexFile(programFile);
- } catch (CompilationError e) {
- System.out.println(
- "Failed to read dex/vdex file `" + programFile + "`: '" + e.getMessage() + "'");
- continue;
- }
- System.out.print("In file: " + cwd.toAbsolutePath().relativize(programFile.toAbsolutePath()));
- System.out.println(", " + extractDexSize(programFile) + " bytes:");
- for (Marker marker : markers) {
- if (marker == null) {
- otherCount++;
- if (!command.getIncludeOther()) {
- continue;
- }
- } else {
- if (marker.isD8()) {
- d8Count++;
- } else {
- r8Count++;
- }
- }
- if (command.getCSV()) {
- System.out.print("\"" + programFile + "\"");
- System.out.print(", ");
- if (marker == null) {
- System.out.print("\"no marker\"");
- } else {
- System.out.print("\"" + (marker.isD8() ? "D8" : "R8") + "\"");
- }
- System.out.print(", ");
- System.out.print(extractDexSize(programFile));
- } else {
- if (command.getVerbose()) {
- System.out.print(programFile);
- System.out.print(": ");
- }
- System.out.print(marker == null ? "D8/R8 marker not found" : marker);
- }
- System.out.println();
- }
- }
- if (command.getSummary()) {
- System.out.println("D8: " + d8Count);
- System.out.println("R8: " + r8Count);
- System.out.println("Other: " + otherCount);
- System.out.println("Total: " + (d8Count + r8Count + otherCount));
- }
+ /**
+ * Command-line entry to the extract marker tool.
+ *
+ * <p>See {@link ExtractMarkerCommand#USAGE_MESSAGE} or run with {@code --help} for usage
+ * information.
+ */
+ public static void main(String[] args) throws Exception {
+ ExceptionUtils.withMainProgramHandler(() -> run(args));
}
}
diff --git a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
index a2b44dc..ac084da 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
@@ -4,22 +4,35 @@
package com.android.tools.r8;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.utils.Pair;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
+import java.util.function.BiConsumer;
-class ExtractMarkerCommand {
+/** Immutable command structure for an invocation of the {@link ExtractMarker} tool. */
+@Keep
+public class ExtractMarkerCommand {
+ /** Builder for constructing a {@link ExtractMarkerCommand}. */
+ @Keep
public static class Builder {
private boolean printHelp = false;
- private boolean includeOther = true;
- private boolean verbose;
- private boolean summary;
- private boolean csv;
private final List<Path> programFiles = new ArrayList<>();
+ private final List<Pair<Origin, byte[]>> dexData = new ArrayList<>();
+ private final List<Pair<Origin, byte[]>> cfData = new ArrayList<>();
+ private MarkerInfoConsumer consumer;
+ private DiagnosticsHandler handler;
+
+ Builder(DiagnosticsHandler handler) {
+ this.handler = handler;
+ }
public Builder setPrintHelp(boolean printHelp) {
this.printHelp = printHelp;
@@ -30,28 +43,40 @@
return printHelp;
}
- public Builder setIncludeOther(boolean includeOther) {
- this.includeOther = includeOther;
+ /**
+ * Add program files to extract marker information from.
+ *
+ * <p>All program files supported by the input and output of D8/R8 can be passed here.
+ */
+ public Builder addProgramFiles(Path... programFiles) {
+ return addProgramFiles(Arrays.asList(programFiles));
+ }
+
+ /**
+ * Add program files to extract marker information from.
+ *
+ * <p>All program files supported by the input and output of D8/R8 can be passed here.
+ */
+ public Builder addProgramFiles(Collection<Path> programFiles) {
+ this.programFiles.addAll(programFiles);
return this;
}
- public Builder setVerbose(boolean verbose) {
- this.verbose = verbose;
+ /** Add dex encoded bytes to extract marker information from. */
+ public Builder addDexProgramData(byte[] data, Origin origin) {
+ dexData.add(new Pair<>(origin, data));
return this;
}
- public Builder setSummary(boolean summary) {
- this.summary = summary;
+ /** Add classfile encoded bytes to extract marker information from. */
+ public Builder addClassProgramData(byte[] data, Origin origin) {
+ cfData.add(new Pair<>(origin, data));
return this;
}
- public Builder setCSV(boolean csv) {
- this.csv = csv;
- return this;
- }
-
- public Builder addProgramFile(Path programFile) {
- programFiles.add(programFile);
+ /** Set the callback to obtain the collected marker information. */
+ public Builder setMarkerInfoConsumer(MarkerInfoConsumer consumer) {
+ this.consumer = consumer;
return this;
}
@@ -60,24 +85,27 @@
if (isPrintHelp()) {
return new ExtractMarkerCommand(isPrintHelp());
}
- return new ExtractMarkerCommand(includeOther, verbose, summary, csv, programFiles);
+ return new ExtractMarkerCommand(handler, consumer, programFiles, dexData, cfData);
}
}
- static final String USAGE_MESSAGE = String.join("\n", ImmutableList.of(
- "Usage: extractmarker [options] <input-files>",
- " where <input-files> are dex or vdex files",
- " --no-other # Only show information for D8 or R8 processed files.",
- " --verbose # More verbose output.",
- " --summary # Print summary at the end.",
- " --csv # Output in CSV format.",
- " --help # Print this message."));
+ static final String USAGE_MESSAGE =
+ String.join(
+ "\n",
+ ImmutableList.of(
+ "Usage: extractmarker [options] <input-files>",
+ " where <input-files> are D8 supported input/output files and options are:",
+ " --help # Print this message."));
public static Builder builder() {
- return new Builder();
+ return builder(new DiagnosticsHandler() {});
}
- public static Builder parse(String[] args) throws IOException {
+ public static Builder builder(DiagnosticsHandler handler) {
+ return new Builder(handler);
+ }
+
+ public static Builder parse(String[] args) {
Builder builder = builder();
parse(args, builder);
return builder;
@@ -86,74 +114,65 @@
private static void parse(String[] args, Builder builder) {
for (int i = 0; i < args.length; i++) {
String arg = args[i].trim();
- if (arg.length() == 0) {
- continue;
- } else if (arg.equals("--no-other")) {
- builder.setIncludeOther(false);
- } else if (arg.equals("--verbose")) {
- builder.setVerbose(true);
- } else if (arg.equals("--summary")) {
- builder.setSummary(true);
- } else if (arg.equals("--csv")) {
- builder.setCSV(true);
- } else if (arg.equals("--help")) {
+ if (arg.equals("--help")) {
builder.setPrintHelp(true);
} else {
if (arg.startsWith("--")) {
throw new CompilationError("Unknown option: " + arg);
}
- builder.addProgramFile(Paths.get(arg));
+ builder.addProgramFiles(Paths.get(arg));
}
}
}
private final boolean printHelp;
- private final boolean includeOther;
- private final boolean verbose;
- private final boolean summary;
- private final boolean csv;
+ private final DiagnosticsHandler handler;
+ private final MarkerInfoConsumer consumer;
private final List<Path> programFiles;
+ private final List<Pair<Origin, byte[]>> dexData;
+ private final List<Pair<Origin, byte[]>> cfData;
- private ExtractMarkerCommand(boolean includeOther, boolean verbose, boolean summary,
- boolean csv, List<Path> programFiles) {
+ private ExtractMarkerCommand(
+ DiagnosticsHandler handler,
+ MarkerInfoConsumer consumer,
+ List<Path> programFiles,
+ List<Pair<Origin, byte[]>> dexData,
+ List<Pair<Origin, byte[]>> cfData) {
this.printHelp = false;
- this.includeOther = includeOther;
- this.verbose = verbose;
- this.summary = summary;
- this.csv = csv;
+ this.handler = handler;
+ this.consumer = consumer;
this.programFiles = programFiles;
+ this.dexData = dexData;
+ this.cfData = cfData;
}
private ExtractMarkerCommand(boolean printHelp) {
this.printHelp = printHelp;
- this.includeOther = true;
- this.verbose = false;
- this.summary = false;
- this.csv = false;
- programFiles = ImmutableList.of();
+ handler = null;
+ consumer = null;
+ programFiles = null;
+ dexData = null;
+ cfData = null;
}
public boolean isPrintHelp() {
return printHelp;
}
- public List<Path> getProgramFiles() {
- return programFiles;
+ public MarkerInfoConsumer getMarkerInfoConsumer() {
+ return consumer;
}
- public boolean getIncludeOther() {
- return includeOther;
+ public DiagnosticsHandler getDiagnosticsHandler() {
+ return handler;
}
- public boolean getVerbose() {
- return verbose;
- }
-
- public boolean getSummary() {
- return summary;
- }
-
- public boolean getCSV() {
- return csv;
+ public void forEachEntry(
+ BiConsumer<Path, Origin> onProgramFile,
+ BiConsumer<byte[], Origin> onDexData,
+ BiConsumer<byte[], Origin> onCfData) {
+ programFiles.forEach(path -> onProgramFile.accept(path, new PathOrigin(path)));
+ dexData.forEach(pair -> onDexData.accept(pair.getSecond(), pair.getFirst()));
+ cfData.forEach(pair -> onCfData.accept(pair.getSecond(), pair.getFirst()));
}
}
diff --git a/src/main/java/com/android/tools/r8/MarkerInfo.java b/src/main/java/com/android/tools/r8/MarkerInfo.java
new file mode 100644
index 0000000..32578c1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/MarkerInfo.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+/** Information present in a given marker. */
+@Keep
+public interface MarkerInfo {
+
+ /** Get the tool that has generated the marker. */
+ String getTool();
+
+ /** True of the generating tool was the R8 compiler. */
+ boolean isR8();
+
+ /** True of the generating tool was the D8 compiler. */
+ boolean isD8();
+
+ /** True of the generating tool was the L8 compiler. */
+ boolean isL8();
+
+ /** Get the min-api specified by the marker, or -1 if not defined. */
+ int getMinApi();
+
+ /**
+ * Get the raw encoding of the marker used by the compilers.
+ *
+ * <p>Warning: The format of this encoding may be subject to change and its concrete encoding
+ * should not be assumed. For usages of concrete information in the marker the structured API on
+ * {@link MarkerInfo} should be used.
+ */
+ String getRawEncoding();
+}
diff --git a/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java b/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java
new file mode 100644
index 0000000..48e4a30
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/MarkerInfoConsumer.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+/** Interface for consumers of the marker information. */
+@Keep
+public interface MarkerInfoConsumer {
+
+ void acceptMarkerInfo(MarkerInfoConsumerData data);
+
+ void finished();
+}
diff --git a/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java b/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java
new file mode 100644
index 0000000..1b2d500
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/MarkerInfoConsumerData.java
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+import com.android.tools.r8.origin.Origin;
+import java.util.Collection;
+
+/** Information about which markers are present in a given input. */
+@Keep
+public interface MarkerInfoConsumerData {
+
+ Origin getInputOrigin();
+
+ boolean hasMarkers();
+
+ Collection<MarkerInfo> getMarkers();
+}
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
index 47bcc73..7af0129 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
@@ -807,6 +807,9 @@
expect(':');
skipWhitespace();
int to = parseNumber();
+ if (from > to) {
+ throw new ParseException("From is larger than to in range: " + from + ":" + to);
+ }
return nonCardinalRangeCache.get(from, to);
}
diff --git a/src/main/java/com/android/tools/r8/utils/ExtractMarkerUtils.java b/src/main/java/com/android/tools/r8/utils/ExtractMarkerUtils.java
new file mode 100644
index 0000000..b8d0bb0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/ExtractMarkerUtils.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.utils;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.ExtractMarker;
+import com.android.tools.r8.ExtractMarkerCommand;
+import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.origin.Origin;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+// Internal tools for accessing marker info.
+public class ExtractMarkerUtils {
+
+ public static Collection<Marker> extractMarkersFromFile(Path file)
+ throws CompilationFailedException {
+ return extractMarkers(ExtractMarkerCommand.builder().addProgramFiles(file));
+ }
+
+ public static Collection<Marker> extractMarkerFromDexProgramData(byte[] data)
+ throws CompilationFailedException {
+ return extractMarkers(ExtractMarkerCommand.builder().addDexProgramData(data, Origin.unknown()));
+ }
+
+ public static Collection<Marker> extractMarkerFromClassProgramData(byte[] data)
+ throws CompilationFailedException {
+ return extractMarkers(
+ ExtractMarkerCommand.builder().addClassProgramData(data, Origin.unknown()));
+ }
+
+ private static List<Marker> extractMarkers(ExtractMarkerCommand.Builder builder)
+ throws CompilationFailedException {
+ List<Marker> markers = new ArrayList<>();
+ ExtractMarker.run(
+ builder.setMarkerInfoConsumer(new MarkerInfoToInternalMarkerConsumer(markers)).build());
+ return markers;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/MarkerInfoConsumerDataImpl.java b/src/main/java/com/android/tools/r8/utils/MarkerInfoConsumerDataImpl.java
new file mode 100644
index 0000000..7a844a1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/MarkerInfoConsumerDataImpl.java
@@ -0,0 +1,36 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.utils;
+
+import com.android.tools.r8.MarkerInfo;
+import com.android.tools.r8.MarkerInfoConsumerData;
+import com.android.tools.r8.origin.Origin;
+import java.util.Collection;
+import java.util.List;
+
+public class MarkerInfoConsumerDataImpl implements MarkerInfoConsumerData {
+
+ private final Origin origin;
+ private final List<MarkerInfo> markerInfos;
+
+ public MarkerInfoConsumerDataImpl(Origin origin, List<MarkerInfo> markerInfos) {
+ this.origin = origin;
+ this.markerInfos = markerInfos;
+ }
+
+ @Override
+ public Origin getInputOrigin() {
+ return origin;
+ }
+
+ @Override
+ public boolean hasMarkers() {
+ return !markerInfos.isEmpty();
+ }
+
+ @Override
+ public Collection<MarkerInfo> getMarkers() {
+ return markerInfos;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/MarkerInfoImpl.java b/src/main/java/com/android/tools/r8/utils/MarkerInfoImpl.java
new file mode 100644
index 0000000..bcbbeeb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/MarkerInfoImpl.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.utils;
+
+import com.android.tools.r8.MarkerInfo;
+import com.android.tools.r8.dex.Marker;
+
+public class MarkerInfoImpl implements MarkerInfo {
+
+ private final Marker marker;
+
+ public MarkerInfoImpl(Marker marker) {
+ this.marker = marker;
+ }
+
+ Marker getInternalMarker() {
+ return marker;
+ }
+
+ @Override
+ public String getTool() {
+ return marker.getTool().toString();
+ }
+
+ @Override
+ public boolean isR8() {
+ return marker.isR8();
+ }
+
+ @Override
+ public boolean isD8() {
+ return marker.isD8();
+ }
+
+ @Override
+ public boolean isL8() {
+ return marker.isL8();
+ }
+
+ @Override
+ public int getMinApi() {
+ return marker.hasMinApi() ? marker.getMinApi().intValue() : -1;
+ }
+
+ @Override
+ public String getRawEncoding() {
+ return marker.toString();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/MarkerInfoToInternalMarkerConsumer.java b/src/main/java/com/android/tools/r8/utils/MarkerInfoToInternalMarkerConsumer.java
new file mode 100644
index 0000000..099d9b1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/MarkerInfoToInternalMarkerConsumer.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.utils;
+
+import com.android.tools.r8.MarkerInfo;
+import com.android.tools.r8.MarkerInfoConsumer;
+import com.android.tools.r8.MarkerInfoConsumerData;
+import com.android.tools.r8.dex.Marker;
+import java.util.List;
+
+/** Consumer to convert the marker interface to the internal marker class. */
+public class MarkerInfoToInternalMarkerConsumer implements MarkerInfoConsumer {
+
+ private final List<Marker> markers;
+
+ public MarkerInfoToInternalMarkerConsumer(List<Marker> markers) {
+ this.markers = markers;
+ }
+
+ @Override
+ public void acceptMarkerInfo(MarkerInfoConsumerData data) {
+ if (data.hasMarkers()) {
+ for (MarkerInfo marker : data.getMarkers()) {
+ MarkerInfoImpl impl = (MarkerInfoImpl) marker;
+ markers.add(impl.getInternalMarker());
+ }
+ }
+ }
+
+ @Override
+ public void finished() {}
+}
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index 11cebfd..487451f 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -32,6 +32,7 @@
import com.android.tools.r8.startup.diagnostic.MissingStartupProfileItemsDiagnostic;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
@@ -137,7 +138,7 @@
input.toString());
assertEquals(0, ToolHelper.forkD8(working, "@flags.txt").exitCode);
assertTrue(Files.exists(output));
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
assertEquals(1, markers.size());
Marker marker = markers.iterator().next();
assertEquals(24, marker.getMinApi().intValue());
diff --git a/src/test/java/com/android/tools/r8/ExtractMarkerTest.java b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
index 6ed73d8..1f0ef3c 100644
--- a/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Set;
@@ -68,7 +69,7 @@
Marker marker;
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromDexProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromDexProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
@@ -109,7 +110,7 @@
Marker marker;
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromClassProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromClassProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
diff --git a/src/test/java/com/android/tools/r8/L8CommandTest.java b/src/test/java/com/android/tools/r8/L8CommandTest.java
index a2c7122..e2d8b20 100644
--- a/src/test/java/com/android/tools/r8/L8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/L8CommandTest.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.origin.EmbeddedOrigin;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
@@ -97,7 +98,7 @@
.setOutput(output, OutputMode.DexIndexed)
.build());
assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(output),
+ ExtractMarkerUtils.extractMarkersFromFile(output),
ImmutableList.of(markerTool(Tool.L8), markerTool(Tool.D8)));
}
@@ -112,7 +113,7 @@
.addDesugaredLibraryConfiguration(getDesugaredLibraryConfiguration())
.setOutput(output, OutputMode.ClassFile)
.build());
- assertMarkersMatch(ExtractMarker.extractMarkerFromDexFile(output), markerTool(Tool.L8));
+ assertMarkersMatch(ExtractMarkerUtils.extractMarkersFromFile(output), markerTool(Tool.L8));
}
private List<String> buildCommand(int minAPI, Path output) {
@@ -140,7 +141,7 @@
L8Command l8Command = parse(command.toArray(new String[0]));
L8.run(l8Command);
assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(output),
+ ExtractMarkerUtils.extractMarkersFromFile(output),
ImmutableList.of(markerTool(Tool.L8), markerTool(Tool.D8)));
}
@@ -151,7 +152,7 @@
command.add("--classfile");
L8Command l8Command = parse(command.toArray(new String[0]));
L8.run(l8Command);
- assertMarkersMatch(ExtractMarker.extractMarkerFromDexFile(output), markerTool(Tool.L8));
+ assertMarkersMatch(ExtractMarkerUtils.extractMarkersFromFile(output), markerTool(Tool.L8));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/MarkersTest.java b/src/test/java/com/android/tools/r8/MarkersTest.java
index d5a61db..bd3a45d 100644
--- a/src/test/java/com/android/tools/r8/MarkersTest.java
+++ b/src/test/java/com/android/tools/r8/MarkersTest.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
@@ -90,7 +91,7 @@
builder.addProguardConfiguration(ImmutableList.of("-keep class * { *; }"), Origin.unknown());
}
L8.run(builder.build());
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
JsonObject jsonObject =
new JsonParser()
.parse(
@@ -138,7 +139,7 @@
} else {
D8.run(builder.build());
}
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
Matcher<Marker> matcher =
allOf(
markerTool(Tool.D8),
@@ -167,11 +168,11 @@
if (noCfMarkerForDesugaredCode) {
ToolHelper.runD8(
builder, options -> options.desugarSpecificOptions().noCfMarkerForDesugaredCode = true);
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
assertTrue(markers.isEmpty());
} else {
D8.run(builder.build());
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
Matcher<Marker> matcher =
allOf(
markerTool(Tool.D8),
@@ -206,7 +207,7 @@
} else {
R8.run(builder.build());
}
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
Matcher<Marker> matcher =
allOf(
markerTool(Tool.R8),
@@ -238,7 +239,7 @@
} else {
R8.run(builder.build());
}
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
Matcher<Marker> matcher =
allOf(
markerTool(Tool.R8),
@@ -267,12 +268,12 @@
if (noCfMarkerForDesugaredCode) {
ToolHelper.runD8(
builder, options -> options.desugarSpecificOptions().noCfMarkerForDesugaredCode = true);
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(d8DesugaredOutput);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(d8DesugaredOutput);
assertTrue(markers.isEmpty());
} else {
D8.run(builder.build());
assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(d8DesugaredOutput),
+ ExtractMarkerUtils.extractMarkersFromFile(d8DesugaredOutput),
allOf(
markerTool(Tool.D8),
markerCompilationMode(compilationSpecification.getProgramCompilationMode()),
@@ -292,7 +293,7 @@
.setOutput(output, OutputMode.ClassFile)
.build());
assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(output),
+ ExtractMarkerUtils.extractMarkersFromFile(output),
allOf(
markerTool(Tool.R8),
markerCompilationMode(compilationSpecification.getProgramCompilationMode()),
diff --git a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
index f0b68de..f827134 100644
--- a/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/ProguardMapMarkerTest.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.naming.ProguardMapSupplier;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.VersionProperties;
import java.nio.file.Paths;
import java.util.Collection;
@@ -71,7 +72,7 @@
Marker marker;
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromDexProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromDexProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
@@ -116,7 +117,7 @@
Marker marker;
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromClassProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromClassProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
diff --git a/src/test/java/com/android/tools/r8/R8CommandTest.java b/src/test/java/com/android/tools/r8/R8CommandTest.java
index 57fda02..152992d 100644
--- a/src/test/java/com/android/tools/r8/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/R8CommandTest.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.ApiModelTestingOptions;
@@ -199,7 +200,7 @@
input.toString());
assertEquals(0, ToolHelper.forkR8(working, "@flags.txt").exitCode);
assertTrue(Files.exists(output));
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(output);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(output);
assertEquals(1, markers.size());
Marker marker = markers.iterator().next();
assertEquals(24, marker.getMinApi().intValue());
diff --git a/src/test/java/com/android/tools/r8/R8ModeMarkerTest.java b/src/test/java/com/android/tools/r8/R8ModeMarkerTest.java
index 32f0871..f4c1a3b 100644
--- a/src/test/java/com/android/tools/r8/R8ModeMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/R8ModeMarkerTest.java
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import java.util.Collection;
import java.util.Set;
import org.junit.Test;
@@ -44,7 +45,7 @@
int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromDexProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromDexProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
@@ -70,7 +71,7 @@
public void accept(ByteDataView data, String descriptors, DiagnosticsHandler handler) {
try {
Collection<Marker> markers =
- ExtractMarker.extractMarkerFromClassProgramData(data.copyByteData());
+ ExtractMarkerUtils.extractMarkerFromClassProgramData(data.copyByteData());
assertEquals(1, markers.size());
marker = markers.iterator().next();
} catch (Exception e) {
diff --git a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
index c2d4a30..1bbaf31 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/CompilerApiTestCollection.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.compilerapi.desugardependencies.DesugarDependenciesTest;
import com.android.tools.r8.compilerapi.diagnostics.ProguardKeepRuleDiagnosticsApiTest;
import com.android.tools.r8.compilerapi.diagnostics.UnsupportedFeaturesDiagnosticApiTest;
+import com.android.tools.r8.compilerapi.extractmarker.ExtractMarkerApiTest;
import com.android.tools.r8.compilerapi.globalsynthetics.GlobalSyntheticsTest;
import com.android.tools.r8.compilerapi.inputdependencies.InputDependenciesTest;
import com.android.tools.r8.compilerapi.mapid.CustomMapIdTest;
@@ -52,15 +53,16 @@
CommandLineParserTest.ApiTest.class,
EnableMissingLibraryApiModelingTest.ApiTest.class,
AndroidPlatformBuildApiTest.ApiTest.class,
- UnsupportedFeaturesDiagnosticApiTest.ApiTest.class);
-
- private static final List<Class<? extends CompilerApiTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
- ImmutableList.of(
+ UnsupportedFeaturesDiagnosticApiTest.ApiTest.class,
ArtProfilesForRewritingApiTest.ApiTest.class,
StartupProfileApiTest.ApiTest.class,
ClassConflictResolverTest.ApiTest.class,
ProguardKeepRuleDiagnosticsApiTest.ApiTest.class,
- SyntheticContextsConsumerTest.ApiTest.class);
+ SyntheticContextsConsumerTest.ApiTest.class,
+ ExtractMarkerApiTest.ApiTest.class);
+
+ private static final List<Class<? extends CompilerApiTest>> CLASSES_PENDING_BINARY_COMPATIBILITY =
+ ImmutableList.of();
private final TemporaryFolder temp;
diff --git a/src/test/java/com/android/tools/r8/compilerapi/extractmarker/ExtractMarkerApiTest.java b/src/test/java/com/android/tools/r8/compilerapi/extractmarker/ExtractMarkerApiTest.java
new file mode 100644
index 0000000..20e2bd4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/compilerapi/extractmarker/ExtractMarkerApiTest.java
@@ -0,0 +1,195 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.compilerapi.extractmarker;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.ByteDataView;
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.ExtractMarker;
+import com.android.tools.r8.ExtractMarkerCommand;
+import com.android.tools.r8.MarkerInfo;
+import com.android.tools.r8.MarkerInfoConsumer;
+import com.android.tools.r8.MarkerInfoConsumerData;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.compilerapi.CompilerApiTest;
+import com.android.tools.r8.compilerapi.CompilerApiTestRunner;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.utils.Box;
+import com.android.tools.r8.utils.IntBox;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import org.junit.Test;
+
+public class ExtractMarkerApiTest extends CompilerApiTestRunner {
+
+ public ExtractMarkerApiTest(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<? extends CompilerApiTest> binaryTestClass() {
+ return ApiTest.class;
+ }
+
+ public static class SomeClass {}
+
+ public static class SomeOrigin extends Origin {
+ private final String name;
+
+ public SomeOrigin(String name) {
+ super(Origin.root());
+ this.name = name;
+ }
+
+ @Override
+ public String part() {
+ return name;
+ }
+ }
+
+ @Test
+ public void test() throws Exception {
+
+ Path inputFile = ToolHelper.getClassFileForTestClass(SomeClass.class);
+ byte[] inputCf = ToolHelper.getClassAsBytes(SomeClass.class);
+ Box<byte[]> inputDex = new Box<>();
+
+ // Compile DEX code for use as byte input.
+ testForD8(Backend.DEX)
+ .addProgramClasses(SomeClass.class)
+ .setMinApi(1)
+ .setProgramConsumer(
+ new DexIndexedConsumer() {
+ byte[] bytes = null;
+
+ @Override
+ public void accept(
+ int fileIndex,
+ ByteDataView data,
+ Set<String> descriptors,
+ DiagnosticsHandler handler) {
+ assertEquals(0, fileIndex);
+ assertNull(bytes);
+ bytes = data.copyByteData();
+ }
+
+ @Override
+ public void finished(DiagnosticsHandler handler) {
+ assertNotNull(bytes);
+ inputDex.set(bytes);
+ }
+ })
+ .compile();
+
+ assertNotNull(inputDex.get());
+
+ Origin originDex = new SomeOrigin("dex bytes");
+ Origin originCf = new SomeOrigin("cf bytes");
+ IntBox calls = new IntBox(0);
+ new ApiTest(ApiTest.PARAMETERS)
+ .run(
+ inputFile,
+ inputDex.get(),
+ originDex,
+ inputCf,
+ originCf,
+ (origin, marker) -> {
+ calls.increment();
+ if (origin == originDex) {
+ assertEquals("D8", marker.getTool());
+ assertTrue(marker.isD8());
+ assertFalse(marker.isR8());
+ assertFalse(marker.isL8());
+ assertEquals(1, marker.getMinApi());
+ assertThat(marker.getRawEncoding(), startsWith("~~D8{"));
+ } else {
+ assertTrue(origin == originCf || origin.equals(new PathOrigin(inputFile)));
+ // The CF input file and bytes have no marker as they are javac generated.
+ assertNull(marker);
+ }
+ });
+ assertEquals(4, calls.get());
+ }
+
+ public static class ApiTest extends CompilerApiTest {
+
+ public ApiTest(Object parameters) {
+ super(parameters);
+ }
+
+ public void run(
+ Path inputFile,
+ byte[] inputDex,
+ Origin dexOrigin,
+ byte[] inputCf,
+ Origin cfOrigin,
+ BiConsumer<Origin, MarkerInfo> consumer)
+ throws Exception {
+ ExtractMarkerCommand.Builder builder = ExtractMarkerCommand.builder();
+ if (inputFile != null) {
+ builder.addProgramFiles(inputFile).addProgramFiles(Collections.singleton(inputFile));
+ }
+ if (inputDex != null) {
+ builder.addDexProgramData(inputDex, dexOrigin);
+ }
+ if (inputCf != null) {
+ builder.addClassProgramData(inputCf, cfOrigin);
+ }
+ builder.setMarkerInfoConsumer(
+ new MarkerInfoConsumer() {
+ @Override
+ public void acceptMarkerInfo(MarkerInfoConsumerData data) {
+ if (data.hasMarkers()) {
+ data.getMarkers()
+ .forEach(
+ marker -> {
+ consumer.accept(data.getInputOrigin(), marker);
+ });
+ } else {
+ consumer.accept(data.getInputOrigin(), null);
+ }
+ }
+
+ @Override
+ public void finished() {}
+ });
+ ExtractMarker.run(builder.build());
+ }
+
+ @Test
+ public void test() throws Exception {
+ byte[] inputCf = getBytesForClass(getMockClass());
+ run(
+ null,
+ null,
+ null,
+ inputCf,
+ Origin.root(),
+ (origin, marker) -> {
+ // Marker is null here but use all currently defined methods on marker info to force
+ // binary compatible usage.
+ if (marker != null) {
+ String tool = marker.getTool();
+ boolean d8 = marker.isD8();
+ boolean r8 = marker.isR8();
+ boolean l8 = marker.isL8();
+ int minApi = marker.getMinApi();
+ String raw = marker.getRawEncoding();
+ }
+ });
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
index 26a5169..642b0f8 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/MergingWithDesugaredLibraryTest.java
@@ -18,7 +18,6 @@
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8TestCompileResult;
-import com.android.tools.r8.ExtractMarker;
import com.android.tools.r8.LibraryDesugaringTestConfiguration;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
@@ -27,6 +26,7 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -110,7 +110,7 @@
markerCompilationMode(CompilationMode.RELEASE),
not(markerIsDesugared()),
not(markerHasDesugaredLibraryIdentifier()));
- assertMarkersMatch(ExtractMarker.extractMarkerFromJarFile(shrunkenLib), libraryMatcher);
+ assertMarkersMatch(ExtractMarkerUtils.extractMarkersFromFile(shrunkenLib), libraryMatcher);
// Build an app with the R8 compiled library.
Path app =
@@ -135,7 +135,8 @@
markerHasDesugaredLibraryIdentifier(
libraryDesugaringSpecification.hasAnyDesugaring(parameters)));
assertMarkersMatch(
- ExtractMarker.extractMarkerFromDexFile(app), ImmutableList.of(libraryMatcher, d8Matcher));
+ ExtractMarkerUtils.extractMarkersFromFile(app),
+ ImmutableList.of(libraryMatcher, d8Matcher));
}
@Test
@@ -157,7 +158,7 @@
markerIsDesugared(),
markerMinApi(parameters.getApiLevel()),
not(markerHasDesugaredLibraryIdentifier()));
- assertMarkersMatch(ExtractMarker.extractMarkerFromJarFile(desugaredLibCf), markerMatcher);
+ assertMarkersMatch(ExtractMarkerUtils.extractMarkersFromFile(desugaredLibCf), markerMatcher);
Path desugaredLibDex =
testForD8()
@@ -178,7 +179,7 @@
not(markerHasDesugaredLibraryIdentifier()));
List<Matcher<Marker>> markerMatcherAfterDex = ImmutableList.of(markerMatcher, dexMarkerMatcher);
assertMarkersMatch(
- ExtractMarker.extractMarkerFromJarFile(desugaredLibDex), markerMatcherAfterDex);
+ ExtractMarkerUtils.extractMarkersFromFile(desugaredLibDex), markerMatcherAfterDex);
// Build an app using library desugaring merging with library not using library desugaring.
Path app;
@@ -203,7 +204,7 @@
markerMinApi(parameters.getApiLevel()),
markerHasDesugaredLibraryIdentifier()));
}
- assertMarkersMatch(ExtractMarker.extractMarkerFromDexFile(app), expectedMarkers);
+ assertMarkersMatch(ExtractMarkerUtils.extractMarkersFromFile(app), expectedMarkers);
}
private boolean expectError() {
diff --git a/src/test/java/com/android/tools/r8/dexsplitter/R8FeatureSplitTest.java b/src/test/java/com/android/tools/r8/dexsplitter/R8FeatureSplitTest.java
index cf890cf..130f0e5 100644
--- a/src/test/java/com/android/tools/r8/dexsplitter/R8FeatureSplitTest.java
+++ b/src/test/java/com/android/tools/r8/dexsplitter/R8FeatureSplitTest.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.ExtractMarker;
import com.android.tools.r8.FeatureSplit;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.ResourceException;
@@ -20,6 +19,7 @@
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ExtractMarkerUtils;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -109,9 +109,9 @@
Path basePath = compiledWithFeature.getBasePath();
Path feature1Path = compiledWithFeature.getFeature1Path();
Path feature2Path = compiledWithFeature.getFeature2Path();
- Collection<Marker> markers = ExtractMarker.extractMarkerFromDexFile(basePath);
- Collection<Marker> feature1Markers = ExtractMarker.extractMarkerFromDexFile(feature1Path);
- Collection<Marker> feature2Markers = ExtractMarker.extractMarkerFromDexFile(feature2Path);
+ Collection<Marker> markers = ExtractMarkerUtils.extractMarkersFromFile(basePath);
+ Collection<Marker> feature1Markers = ExtractMarkerUtils.extractMarkersFromFile(feature1Path);
+ Collection<Marker> feature2Markers = ExtractMarkerUtils.extractMarkersFromFile(feature2Path);
assertEquals(markers.size(), 1);
assertEquals(feature1Markers.size(), 1);
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
index c8ce59b..d06cbe6 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -7,6 +7,7 @@
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
@@ -46,6 +47,8 @@
import com.android.tools.r8.retrace.stacktraces.InlineSourceFileContextStackTrace;
import com.android.tools.r8.retrace.stacktraces.InlineSourceFileStackTrace;
import com.android.tools.r8.retrace.stacktraces.InlineWithLineNumbersStackTrace;
+import com.android.tools.r8.retrace.stacktraces.InvalidMinifiedRangeStackTrace;
+import com.android.tools.r8.retrace.stacktraces.InvalidOriginalRangeStackTrace;
import com.android.tools.r8.retrace.stacktraces.InvalidStackTrace;
import com.android.tools.r8.retrace.stacktraces.MapVersionWarningStackTrace;
import com.android.tools.r8.retrace.stacktraces.MemberFieldOverlapStackTrace;
@@ -457,6 +460,22 @@
runRetraceTest(new TrailingWhitespaceStackTrace());
}
+ @Test
+ public void testInvalidMinifiedRangeStackTrace() {
+ assumeFalse(external);
+ assertThrows(
+ InvalidMappingFileException.class,
+ () -> runRetraceTest(new InvalidMinifiedRangeStackTrace()));
+ }
+
+ @Test
+ public void testInvalidOriginalRangeStackTrace() {
+ assumeFalse(external);
+ assertThrows(
+ InvalidMappingFileException.class,
+ () -> runRetraceTest(new InvalidOriginalRangeStackTrace()));
+ }
+
private void inspectRetraceTest(
StackTraceForTest stackTraceForTest, Consumer<Retracer> inspection) {
inspection.accept(
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidMinifiedRangeStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidMinifiedRangeStackTrace.java
new file mode 100644
index 0000000..ad16a40
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidMinifiedRangeStackTrace.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.stacktraces;
+
+import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class InvalidMinifiedRangeStackTrace implements StackTraceForTest {
+
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return Arrays.asList(
+ "Exception in thread \"main\" java.lang.NullPointerException",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.dummy:3)");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<String> retraceVerboseStackTrace() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.lines(
+ "com.android.tools.r8.naming.retrace.Main -> com.android.tools.r8.naming.retrace.Main:",
+ " 5:3:void main(java.lang.String[]) -> main");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidOriginalRangeStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidOriginalRangeStackTrace.java
new file mode 100644
index 0000000..3b8fa63
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InvalidOriginalRangeStackTrace.java
@@ -0,0 +1,42 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.stacktraces;
+
+import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class InvalidOriginalRangeStackTrace implements StackTraceForTest {
+
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return Arrays.asList(
+ "Exception in thread \"main\" java.lang.NullPointerException",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.dummy:3)");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<String> retraceVerboseStackTrace() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.lines(
+ "com.android.tools.r8.naming.retrace.Main -> com.android.tools.r8.naming.retrace.Main:",
+ " 2:5:void main(java.lang.String[]):5:2 -> main");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+}
diff --git a/third_party/bazel.tar.gz.sha1 b/third_party/bazel.tar.gz.sha1
index 956036b..dbc680e 100644
--- a/third_party/bazel.tar.gz.sha1
+++ b/third_party/bazel.tar.gz.sha1
@@ -1 +1 @@
-2533d70cd7892c7597bb6aa57e812d07e2a72c46
\ No newline at end of file
+4c5816530d149bc83aab1e26f7342cfb595523e8
\ No newline at end of file
diff --git a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1 b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
index 8a2887d..b83c4a2 100644
--- a/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
+++ b/third_party/binary_compatibility_tests/compiler_api_tests.tar.gz.sha1
@@ -1 +1 @@
-42f88c3f809026d506e15c14804dd584bc0b9474
\ No newline at end of file
+ae9c0faab45cba310dbe57a3ce0dcba7bed355a3
\ No newline at end of file