summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Zerny <zerny@google.com>2022-06-22 09:34:30 +0200
committerIan Zerny <zerny@google.com>2022-08-16 10:00:48 +0000
commitad807a703c7720187d93e75af2fea8fdb344abea (patch)
tree915fae3124d3d0183d32d69c3821f0b83f026a6e
parentd5c523b482d0dfb1a6fd15099ff507af02cc9f5d (diff)
downloadbase-ad807a703c7720187d93e75af2fea8fdb344abea.tar.gz
Use D8 unsupported features diagnostics API.
Bug: b/154778581 Test: DexDisabledIssueCheckerTest DexDisabledIssueCheckerIntegrationTest Change-Id: Ib9a8d31fdcf5feaba9c941f1c8775b790674c32c
-rw-r--r--build-system/builder/src/main/java/com/android/builder/dexing/D8DexArchiveBuilder.java89
-rw-r--r--build-system/builder/src/main/java/com/android/builder/dexing/D8DiagnosticsHandler.java6
2 files changed, 75 insertions, 20 deletions
diff --git a/build-system/builder/src/main/java/com/android/builder/dexing/D8DexArchiveBuilder.java b/build-system/builder/src/main/java/com/android/builder/dexing/D8DexArchiveBuilder.java
index 51c0aadec0..1aa65b4fb6 100644
--- a/build-system/builder/src/main/java/com/android/builder/dexing/D8DexArchiveBuilder.java
+++ b/build-system/builder/src/main/java/com/android/builder/dexing/D8DexArchiveBuilder.java
@@ -26,17 +26,22 @@ import com.android.tools.r8.D8Command;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.StringConsumer.FileConsumer;
+import com.android.tools.r8.errors.UnsupportedFeatureDiagnostic;
import com.google.common.util.concurrent.MoreExecutors;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
final class D8DexArchiveBuilder extends DexArchiveBuilder {
private static final String INVOKE_CUSTOM =
- "Invoke-customs are only supported starting with Android O";
+ "Invoke-customs are only supported starting with Android O (--min-api 26)";
private static final String DEFAULT_INTERFACE_METHOD =
"Default interface methods are only supported starting with Android N (--min-api 24)";
@@ -56,10 +61,10 @@ final class D8DexArchiveBuilder extends DexArchiveBuilder {
@NonNull Path output,
@Nullable DependencyGraphUpdater<File> desugarGraphUpdater)
throws DexArchiveBuilderException {
- D8DiagnosticsHandler d8DiagnosticsHandler = new InterceptingDiagnosticsHandler();
+ InterceptingDiagnosticsHandler diagnosticsHandler = new InterceptingDiagnosticsHandler();
try {
- D8Command.Builder builder = D8Command.builder(d8DiagnosticsHandler);
+ D8Command.Builder builder = D8Command.builder(diagnosticsHandler);
AtomicInteger entryCount = new AtomicInteger();
input.forEach(
entry -> {
@@ -114,7 +119,7 @@ final class D8DexArchiveBuilder extends DexArchiveBuilder {
D8.run(builder.build(), MoreExecutors.newDirectExecutorService());
} catch (Throwable e) {
- throw getExceptionToRethrow(e, d8DiagnosticsHandler);
+ throw getExceptionToRethrow(e, diagnosticsHandler, dexParams.getWithDesugaring());
}
}
@@ -129,14 +134,52 @@ final class D8DexArchiveBuilder extends DexArchiveBuilder {
@NonNull
private static DexArchiveBuilderException getExceptionToRethrow(
- @NonNull Throwable t, D8DiagnosticsHandler d8DiagnosticsHandler) {
+ @NonNull Throwable t,
+ InterceptingDiagnosticsHandler diagnosticsHandler,
+ boolean isDesugaring) {
StringBuilder msg = new StringBuilder();
msg.append("Error while dexing.");
- for (String hint : d8DiagnosticsHandler.getPendingHints()) {
+ Set<String> unsupportedFeatures = diagnosticsHandler.getUnsupportedFeatures();
+ if (!unsupportedFeatures.isEmpty()) {
+ // Get the largest required level needed to support the features.
+ int minSdkVersion = diagnosticsHandler.getRequiredSdkVersion();
+ if (!isDesugaring) {
+ diagnosticsHandler.addHint(getEnableDesugaringHint(minSdkVersion));
+ } else if (minSdkVersion != -1) {
+ diagnosticsHandler.addHint(
+ "Increase the minSdkVersion to " + minSdkVersion + " or above.\n");
+ }
+ // Construct a new exception to replace the D8 thrown exception.
+ // This avoids the need to maintain pattern-match on D8 exceptions and
+ // instead base matching on the stable diagnostics API.
+ StringBuilder builder = new StringBuilder();
+ if (unsupportedFeatures.contains("invoke-custom")) {
+ builder.append("Error: ").append(INVOKE_CUSTOM);
+ } else if (unsupportedFeatures.contains("default-interface-method")) {
+ builder.append("Error: ").append(DEFAULT_INTERFACE_METHOD);
+ } else if (unsupportedFeatures.contains("static-interface-method")) {
+ builder.append("Error: ").append(STATIC_INTERFACE_METHOD);
+ } else {
+ // If not one of the three above legacy cases, construct an error message with a
+ // line
+ // for each unsupported feature. These are not currently pattern-matched on, so
+ // generalizing the reporting of these can be changed at a later point.
+ List<String> sorted = new ArrayList<>(unsupportedFeatures);
+ sorted.sort(String::compareTo);
+ for (String featureDescriptor : sorted) {
+ builder.append("Error: UnsupportedFeature(")
+ .append(featureDescriptor)
+ .append(")\n");
+ }
+ }
+ Throwable rt = new RuntimeException(builder.toString());
+ rt.addSuppressed(t);
+ t = rt;
+ }
+ for (String hint : diagnosticsHandler.getPendingHints()) {
msg.append(System.lineSeparator());
msg.append(hint);
}
-
return new DexArchiveBuilderException(msg.toString(), t);
}
@@ -156,25 +199,33 @@ final class D8DexArchiveBuilder extends DexArchiveBuilder {
}
private class InterceptingDiagnosticsHandler extends D8DiagnosticsHandler {
+
+ private Set<String> unsupportedFeatureDescriptors = new HashSet<>();
+ private int requiredSdkVersion = -1;
+
public InterceptingDiagnosticsHandler() {
super(D8DexArchiveBuilder.this.dexParams.getMessageReceiver());
}
- @Override
- protected Message convertToMessage(Message.Kind kind, Diagnostic diagnostic) {
-
- if (diagnostic.getDiagnosticMessage().startsWith(INVOKE_CUSTOM)) {
- addHint(getEnableDesugaringHint(26));
- }
+ public int getRequiredSdkVersion() {
+ return requiredSdkVersion;
+ }
- if (diagnostic.getDiagnosticMessage().startsWith(DEFAULT_INTERFACE_METHOD)) {
- addHint(getEnableDesugaringHint(24));
- }
+ public Set<String> getUnsupportedFeatures() {
+ return unsupportedFeatureDescriptors;
+ }
- if (diagnostic.getDiagnosticMessage().startsWith(STATIC_INTERFACE_METHOD)) {
- addHint(getEnableDesugaringHint(24));
+ @Override
+ protected Message convertToMessage(Message.Kind kind, Diagnostic diagnostic) {
+ if (diagnostic instanceof UnsupportedFeatureDiagnostic) {
+ UnsupportedFeatureDiagnostic feature = (UnsupportedFeatureDiagnostic) diagnostic;
+ String featureDescriptor = feature.getFeatureDescriptor();
+ int minSdkVersion = feature.getSupportedApiLevel();
+ unsupportedFeatureDescriptors.add(featureDescriptor);
+ if (requiredSdkVersion < minSdkVersion) {
+ requiredSdkVersion = minSdkVersion;
+ }
}
-
return super.convertToMessage(kind, diagnostic);
}
}
diff --git a/build-system/builder/src/main/java/com/android/builder/dexing/D8DiagnosticsHandler.java b/build-system/builder/src/main/java/com/android/builder/dexing/D8DiagnosticsHandler.java
index bc24ba79b7..c270ab712f 100644
--- a/build-system/builder/src/main/java/com/android/builder/dexing/D8DiagnosticsHandler.java
+++ b/build-system/builder/src/main/java/com/android/builder/dexing/D8DiagnosticsHandler.java
@@ -107,9 +107,13 @@ public class D8DiagnosticsHandler implements DiagnosticsHandler {
protected Message convertToMessage(Message.Kind kind, Diagnostic diagnostic) {
String textMessage = diagnostic.getDiagnosticMessage();
-
Origin origin = diagnostic.getOrigin();
Position positionInOrigin = diagnostic.getPosition();
+ return convertToMessage(kind, textMessage, origin, positionInOrigin);
+ }
+
+ protected Message convertToMessage(
+ Message.Kind kind, String textMessage, Origin origin, Position positionInOrigin) {
SourceFilePosition position;
if (origin instanceof PathOrigin) {
File originFile = ((PathOrigin) origin).getPath().toFile();