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;