Merge commit 'fb689fd74919f5298d94b300f3dcf98234a4b22e' into dev-release
diff --git a/infra/config/global/generated/cr-buildbucket.cfg b/infra/config/global/generated/cr-buildbucket.cfg
index 73e65b4..577a0d0 100644
--- a/infra/config/global/generated/cr-buildbucket.cfg
+++ b/infra/config/global/generated/cr-buildbucket.cfg
@@ -471,6 +471,80 @@
}
}
builders {
+ name: "linux-android-14.0.0"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cores:8"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-18.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--dex_vm=14.0.0",'
+ ' "--all_tests",'
+ ' "--tool=r8",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
+ name: "linux-android-14.0.0_release"
+ swarming_host: "chrome-swarming.appspot.com"
+ swarming_tags: "vpython:native-python-wrapper"
+ dimensions: "cores:8"
+ dimensions: "cpu:x86-64"
+ dimensions: "normal:true"
+ dimensions: "os:Ubuntu-18.04"
+ dimensions: "pool:luci.r8.ci"
+ exe {
+ cipd_package: "infra_internal/recipe_bundles/chrome-internal.googlesource.com/chrome/tools/build_limited/scripts/slave"
+ cipd_version: "refs/heads/master"
+ cmd: "luciexe"
+ }
+ properties:
+ '{'
+ ' "builder_group": "internal.client.r8",'
+ ' "recipe": "rex",'
+ ' "test_options": ['
+ ' "--dex_vm=14.0.0",'
+ ' "--all_tests",'
+ ' "--tool=r8",'
+ ' "--no_internal",'
+ ' "--one_line_per_test",'
+ ' "--archive_failures"'
+ ' ]'
+ '}'
+ priority: 26
+ execution_timeout_secs: 21600
+ expiration_secs: 126000
+ build_numbers: YES
+ service_account: "r8-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+ experiments {
+ key: "luci.recipes.use_python3"
+ value: 100
+ }
+ }
+ builders {
name: "linux-android-4.0.4"
swarming_host: "chrome-swarming.appspot.com"
swarming_tags: "vpython:native-python-wrapper"
diff --git a/infra/config/global/generated/luci-milo.cfg b/infra/config/global/generated/luci-milo.cfg
index c550e41..b1481fe 100644
--- a/infra/config/global/generated/luci-milo.cfg
+++ b/infra/config/global/generated/luci-milo.cfg
@@ -96,6 +96,11 @@
short_name: "13.0.0"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-android-14.0.0"
+ category: "R8"
+ short_name: "14.0.0"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/windows"
category: "R8"
short_name: "windows"
@@ -231,6 +236,11 @@
short_name: "13.0.0"
}
builders {
+ name: "buildbucket/luci.r8.ci/linux-android-14.0.0_release"
+ category: "Release|R8"
+ short_name: "14.0.0"
+ }
+ builders {
name: "buildbucket/luci.r8.ci/windows_release"
category: "Release|R8"
short_name: "windows"
diff --git a/infra/config/global/generated/luci-notify.cfg b/infra/config/global/generated/luci-notify.cfg
index c9717b2..fa8d5b0 100644
--- a/infra/config/global/generated/luci-notify.cfg
+++ b/infra/config/global/generated/luci-notify.cfg
@@ -132,6 +132,30 @@
}
builders {
bucket: "ci"
+ name: "linux-android-14.0.0"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
+ name: "linux-android-14.0.0_release"
+ repository: "https://r8.googlesource.com/r8"
+ }
+}
+notifiers {
+ notifications {
+ on_failure: true
+ on_new_failure: true
+ notify_blamelist {}
+ }
+ builders {
+ bucket: "ci"
name: "linux-android-4.0.4"
repository: "https://r8.googlesource.com/r8"
}
diff --git a/infra/config/global/generated/luci-scheduler.cfg b/infra/config/global/generated/luci-scheduler.cfg
index b775cde..dbd8f00 100644
--- a/infra/config/global/generated/luci-scheduler.cfg
+++ b/infra/config/global/generated/luci-scheduler.cfg
@@ -195,6 +195,35 @@
}
}
job {
+ id: "linux-android-14.0.0"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 4
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-android-14.0.0"
+ }
+}
+job {
+ id: "linux-android-14.0.0_release"
+ realm: "ci"
+ acl_sets: "ci"
+ triggering_policy {
+ kind: GREEDY_BATCHING
+ max_concurrent_invocations: 4
+ max_batch_size: 1
+ }
+ buildbucket {
+ server: "cr-buildbucket.appspot.com"
+ bucket: "ci"
+ builder: "linux-android-14.0.0_release"
+ }
+}
+job {
id: "linux-android-4.0.4"
realm: "ci"
acl_sets: "ci"
@@ -711,6 +740,17 @@
}
}
trigger {
+ id: "branch-gitiles-8.1-forward"
+ realm: "ci"
+ acl_sets: "ci"
+ triggers: "linux-android-14.0.0_release"
+ gitiles {
+ repo: "https://r8.googlesource.com/r8"
+ refs: "regexp:refs/heads/([8]\\.[1-9]+(\\.[0-9]+)?|[9]\\.[0-9]+(\\.[0-9]+)?)"
+ path_regexps: "src/main/java/com/android/tools/r8/Version.java"
+ }
+}
+trigger {
id: "branch-gitiles-trigger"
realm: "ci"
acl_sets: "ci"
@@ -747,6 +787,7 @@
triggers: "linux-android-10.0.0"
triggers: "linux-android-12.0.0"
triggers: "linux-android-13.0.0"
+ triggers: "linux-android-14.0.0"
triggers: "linux-android-4.0.4"
triggers: "linux-android-4.4.4"
triggers: "linux-android-5.1.1"
diff --git a/infra/config/global/generated/project.cfg b/infra/config/global/generated/project.cfg
index bb18107..90b913a 100644
--- a/infra/config/global/generated/project.cfg
+++ b/infra/config/global/generated/project.cfg
@@ -7,7 +7,7 @@
name: "r8"
access: "group:all"
lucicfg {
- version: "1.32.1"
+ version: "1.38.1"
package_dir: ".."
config_dir: "generated"
entry_point: "main.star"
diff --git a/infra/config/global/main.star b/infra/config/global/main.star
index 8574aa5..bbbf235 100755
--- a/infra/config/global/main.star
+++ b/infra/config/global/main.star
@@ -109,6 +109,14 @@
)
luci.gitiles_poller(
+ name = "branch-gitiles-8.1-forward",
+ bucket = "ci",
+ repo = "https://r8.googlesource.com/r8",
+ refs = ["refs/heads/([8]\\.[1-9]+(\\.[0-9]+)?|[9]\\.[0-9]+(\\.[0-9]+)?)"],
+ path_regexps = ["src/main/java/com/android/tools/r8/Version.java"]
+)
+
+luci.gitiles_poller(
name = "branch-gitiles-3.3-forward",
bucket = "ci",
repo = "https://r8.googlesource.com/r8",
@@ -307,6 +315,10 @@
r8_tester_with_default("linux-android-13.0.0",
["--dex_vm=13.0.0", "--all_tests"],
release_trigger=["branch-gitiles-3.3-forward"])
+r8_tester_with_default("linux-android-14.0.0",
+ ["--dex_vm=14.0.0", "--all_tests"],
+ release_trigger=["branch-gitiles-8.1-forward"])
+
r8_tester_with_default("windows", ["--all_tests"],
dimensions=get_dimensions(windows=True))
diff --git a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
index ee98d51..96d4bfa 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -284,7 +284,7 @@
Builder(InternalOptions options, Timing timing) {
super(options, timing);
this.classpathClasses = ClasspathClassCollection.empty();
- this.libraryClasses = null;
+ this.libraryClasses = LibraryClassCollection.empty();
}
private Builder(LazyLoadedDexApplication application) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
index 45aa53f..c62d6b1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
@@ -507,6 +507,15 @@
.append(" Also supported with covariant return type.")
.append(HTML_SPLIT);
}
+ if (!classAnnotation.getUnsupportedFields().isEmpty()) {
+ commentBuilder
+ .append("Some fields (")
+ .append(classAnnotation.getUnsupportedFields().size())
+ .append(") present in Android ")
+ .append(MAX_TESTED_ANDROID_API_LEVEL)
+ .append(" are not supported.")
+ .append(HTML_SPLIT);
+ }
if (!classAnnotation.getUnsupportedMethods().isEmpty()) {
commentBuilder
.append("Some methods (")
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
index 63dec3c..5bfbe46 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
@@ -51,6 +51,9 @@
public class GenerateLintFiles extends AbstractGenerateFiles {
+ // Only recent versions of studio support the format with fields.
+ private static final boolean FORMAT_WITH_FIELD = true;
+
public static GenerateLintFiles createForTesting(
Path specification, Set<Path> implementation, Path outputDirectory) throws Exception {
return new GenerateLintFiles(specification, implementation, outputDirectory);
@@ -181,6 +184,15 @@
+ method.getReference().proto.toDescriptorString());
}
});
+ if (FORMAT_WITH_FIELD) {
+ supportedClass.forEachFieldAndAnnotation(
+ (field, fieldAnnotation) -> {
+ if (fieldAnnotation == null || !fieldAnnotation.unsupportedInMinApiRange) {
+ desugaredApisSignatures.add(
+ classBinaryName + '#' + field.getReference().name);
+ }
+ });
+ }
} else {
desugaredApisSignatures.add(classBinaryName);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
index 8d01c4b..307def9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClasses.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.TriConsumer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
import java.util.Collection;
@@ -121,8 +122,10 @@
this.clazz = clazz;
}
- void forEachMethods(BiConsumer<DexClass, Collection<DexEncodedMethod>> biConsumer) {
- biConsumer.accept(clazz, supportedMethods.values());
+ public void forEachFieldsAndMethods(
+ TriConsumer<DexClass, Collection<DexEncodedField>, Collection<DexEncodedMethod>>
+ triConsumer) {
+ triConsumer.accept(clazz, supportedFields.values(), supportedMethods.values());
}
void forEachMethod(BiConsumer<DexClass, DexEncodedMethod> biConsumer) {
@@ -166,10 +169,6 @@
fieldAnnotations.put(field, annotation.combine(prev));
}
- MethodAnnotation getMethodAnnotation(DexMethod method) {
- return methodAnnotations.get(method);
- }
-
SupportedClass build() {
return new SupportedClass(
clazz,
@@ -196,10 +195,12 @@
return builder.classAnnotation;
}
- void forEachClassAndMethods(BiConsumer<DexClass, Collection<DexEncodedMethod>> biConsumer) {
+ void forEachClassFieldsAndMethods(
+ TriConsumer<DexClass, Collection<DexEncodedField>, Collection<DexEncodedMethod>>
+ triConsumer) {
supportedClassBuilders
.values()
- .forEach(classBuilder -> classBuilder.forEachMethods(biConsumer));
+ .forEach(classBuilder -> classBuilder.forEachFieldsAndMethods(triConsumer));
}
void forEachClassAndMethod(BiConsumer<DexClass, DexEncodedMethod> biConsumer) {
@@ -254,10 +255,16 @@
annotateMethod(method, annotation);
}
- MethodAnnotation getMethodAnnotation(DexMethod method) {
- SupportedClass.Builder classBuilder = supportedClassBuilders.get(method.getHolderType());
+ public Map<DexField, FieldAnnotation> getFieldAnnotations(DexClass clazz) {
+ SupportedClass.Builder classBuilder = supportedClassBuilders.get(clazz.getType());
assert classBuilder != null;
- return classBuilder.getMethodAnnotation(method);
+ return classBuilder.fieldAnnotations;
+ }
+
+ Map<DexMethod, MethodAnnotation> getMethodAnnotations(DexClass clazz) {
+ SupportedClass.Builder classBuilder = supportedClassBuilders.get(clazz.getType());
+ assert classBuilder != null;
+ return classBuilder.methodAnnotations;
}
SupportedClasses build() {
@@ -274,12 +281,18 @@
private final boolean additionalMembersOnClass;
private final boolean fullySupported;
- // Methods in latest android.jar but unsupported.
+ // Members in latest android.jar but unsupported.
+ private final List<DexField> unsupportedFields;
private final List<DexMethod> unsupportedMethods;
- public ClassAnnotation(boolean fullySupported, List<DexMethod> unsupportedMethods) {
+ public ClassAnnotation(
+ boolean fullySupported,
+ List<DexField> unsupportedFields,
+ List<DexMethod> unsupportedMethods) {
this.additionalMembersOnClass = false;
this.fullySupported = fullySupported;
+ unsupportedFields.sort(Comparator.naturalOrder());
+ this.unsupportedFields = unsupportedFields;
unsupportedMethods.sort(Comparator.naturalOrder());
this.unsupportedMethods = ImmutableList.copyOf(unsupportedMethods);
}
@@ -287,6 +300,7 @@
private ClassAnnotation() {
this.additionalMembersOnClass = true;
this.fullySupported = false;
+ this.unsupportedFields = ImmutableList.of();
this.unsupportedMethods = ImmutableList.of();
}
@@ -304,6 +318,10 @@
return fullySupported;
}
+ public List<DexField> getUnsupportedFields() {
+ return unsupportedFields;
+ }
+
public List<DexMethod> getUnsupportedMethods() {
return unsupportedMethods;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
index f286bae..b165a93 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
@@ -16,8 +16,11 @@
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMember;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -82,36 +85,45 @@
private void annotateClasses(
SupportedClasses.Builder builder, DirectMappedDexApplication appForMax) {
- builder.forEachClassAndMethods(
- (clazz, methods) -> {
+ builder.forEachClassFieldsAndMethods(
+ (clazz, fields, methods) -> {
ClassAnnotation classAnnotation = builder.getClassAnnotation(clazz.type);
if (classAnnotation != null && classAnnotation.isAdditionalMembersOnClass()) {
return;
}
DexClass maxClass = appForMax.definitionFor(clazz.type);
- List<DexMethod> missing = new ArrayList<>();
+ List<DexField> missingFields = new ArrayList<>();
+ List<DexMethod> missingMethods = new ArrayList<>();
boolean fullySupported = true;
- for (DexEncodedMethod method : maxClass.methods()) {
- if (!(method.isPublic() || method.isProtectedMethod())) {
- continue;
- }
- // If the method is in android.jar but not in the desugared library, or annotated, then
- // the class is not marked as fully supported.
- if (methods.stream().noneMatch(em -> em.getReference() == method.getReference())) {
- missing.add(method.getReference());
- fullySupported = false;
- }
+ fullySupported &= analyzeMissingMembers(maxClass.fields(), fields, missingFields);
+ fullySupported &= analyzeMissingMembers(maxClass.methods(), methods, missingMethods);
+ fullySupported &= builder.getFieldAnnotations(clazz).isEmpty();
+ for (MethodAnnotation methodAnnotation : builder.getMethodAnnotations(clazz).values()) {
+ fullySupported &= methodAnnotation.isCovariantReturnSupported();
}
- for (DexEncodedMethod method : clazz.methods()) {
- MethodAnnotation methodAnnotation = builder.getMethodAnnotation(method.getReference());
- if (methodAnnotation != null && !methodAnnotation.isCovariantReturnSupported()) {
- fullySupported = false;
- }
- }
- builder.annotateClass(clazz.type, new ClassAnnotation(fullySupported, missing));
+ builder.annotateClass(
+ clazz.type, new ClassAnnotation(fullySupported, missingFields, missingMethods));
});
}
+ private <EM extends DexEncodedMember<EM, M>, M extends DexMember<EM, M>>
+ boolean analyzeMissingMembers(
+ Iterable<EM> maxClassMembers, Collection<EM> referenceMembers, List<M> missingMembers) {
+ boolean fullySupported = true;
+ for (EM member : maxClassMembers) {
+ if (!(member.getAccessFlags().isPublic() || member.getAccessFlags().isProtected())) {
+ continue;
+ }
+ // If the field is in android.jar but not in the desugared library, then
+ // the class is not marked as fully supported.
+ if (referenceMembers.stream().noneMatch(em -> em.getReference() == member.getReference())) {
+ missingMembers.add(member.getReference());
+ fullySupported = false;
+ }
+ }
+ return fullySupported;
+ }
+
private void annotatePartialDesugaringMembers(
SupportedClasses.Builder builder, Path specification) throws IOException {
for (int api = AndroidApiLevel.K.getLevel();
diff --git a/src/main/java/com/android/tools/r8/utils/LibraryClassCollection.java b/src/main/java/com/android/tools/r8/utils/LibraryClassCollection.java
index c274aad..d1957a4 100644
--- a/src/main/java/com/android/tools/r8/utils/LibraryClassCollection.java
+++ b/src/main/java/com/android/tools/r8/utils/LibraryClassCollection.java
@@ -13,6 +13,10 @@
super(null, classProvider);
}
+ public static LibraryClassCollection empty() {
+ return new LibraryClassCollection(null);
+ }
+
@Override
DexLibraryClass resolveClassConflict(DexLibraryClass a, DexLibraryClass b) {
return a;