Backport Java 9 Map.entry factory
Test: tools/test.py --dex_vm all --no-internal -v *Backport*Test*
Test: tools/test.py --no-internal -v *GenerateBackportMethods*
Change-Id: Ieffa2fbc7e93d51a54209c8f5f1c208963136f13
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index b796600..f6f34e6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -1056,6 +1056,12 @@
addProvider(
new MethodGenerator(
method, BackportedMethods::CollectionMethods_mapOfEntries, "ofEntries"));
+
+ // Map.Entry<K, V> Map.entry(K, V)
+ type = factory.mapType;
+ proto = factory.createProto(factory.mapEntryType, factory.objectType, factory.objectType);
+ method = factory.createMethod(type, proto, "entry");
+ addProvider(new MethodGenerator(method, BackportedMethods::CollectionMethods_mapEntry));
}
private void initializeJava11MethodProviders(DexItemFactory factory) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
index aadf9e5..864099b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
@@ -597,6 +597,60 @@
ImmutableList.of());
}
+ public static CfCode CollectionMethods_mapEntry(InternalOptions options, DexMethod method) {
+ CfLabel label0 = new CfLabel();
+ CfLabel label1 = new CfLabel();
+ CfLabel label2 = new CfLabel();
+ CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ return new CfCode(
+ method.holder,
+ 4,
+ 2,
+ ImmutableList.of(
+ label0,
+ new CfNew(
+ options.itemFactory.createType("Ljava/util/AbstractMap$SimpleImmutableEntry;")),
+ new CfStackInstruction(CfStackInstruction.Opcode.Dup),
+ new CfLoad(ValueType.OBJECT, 0),
+ label1,
+ new CfInvoke(
+ 184,
+ options.itemFactory.createMethod(
+ options.itemFactory.createType("Ljava/util/Objects;"),
+ options.itemFactory.createProto(
+ options.itemFactory.createType("Ljava/lang/Object;"),
+ options.itemFactory.createType("Ljava/lang/Object;")),
+ options.itemFactory.createString("requireNonNull")),
+ false),
+ new CfLoad(ValueType.OBJECT, 1),
+ label2,
+ new CfInvoke(
+ 184,
+ options.itemFactory.createMethod(
+ options.itemFactory.createType("Ljava/util/Objects;"),
+ options.itemFactory.createProto(
+ options.itemFactory.createType("Ljava/lang/Object;"),
+ options.itemFactory.createType("Ljava/lang/Object;")),
+ options.itemFactory.createString("requireNonNull")),
+ false),
+ new CfInvoke(
+ 183,
+ options.itemFactory.createMethod(
+ options.itemFactory.createType("Ljava/util/AbstractMap$SimpleImmutableEntry;"),
+ options.itemFactory.createProto(
+ options.itemFactory.createType("V"),
+ options.itemFactory.createType("Ljava/lang/Object;"),
+ options.itemFactory.createType("Ljava/lang/Object;")),
+ options.itemFactory.createString("<init>")),
+ false),
+ label3,
+ new CfReturn(ValueType.OBJECT),
+ label4),
+ ImmutableList.of(),
+ ImmutableList.of());
+ }
+
public static CfCode CollectionMethods_mapOfEntries(InternalOptions options, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
diff --git a/src/test/examplesJava9/backport/MapBackportJava9Main.java b/src/test/examplesJava9/backport/MapBackportJava9Main.java
index 2aa5cfd..442fd9b 100644
--- a/src/test/examplesJava9/backport/MapBackportJava9Main.java
+++ b/src/test/examplesJava9/backport/MapBackportJava9Main.java
@@ -15,6 +15,7 @@
testOf2();
testOf10();
testOfEntries();
+ testEntry();
}
private static void testOf0() {
@@ -218,6 +219,31 @@
}
}
+ private static void testEntry() {
+ Object key = new Object();
+ Object value = new Object();
+ Map.Entry<Object, Object> entry = Map.entry(key, value);
+ assertSame(key, entry.getKey());
+ assertSame(value, entry.getValue());
+
+ try {
+ entry.setValue(new Object());
+ throw new AssertionError();
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ Map.entry(null, value);
+ throw new AssertionError();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ Map.entry(key, null);
+ throw new AssertionError();
+ } catch (NullPointerException expected) {
+ }
+ }
+
private static void assertMutationNotAllowed(Map<Object, Object> ofObject) {
try {
ofObject.put(new Object(), new Object());
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/CollectionMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/CollectionMethods.java
index 0dd1a53..ae3aef1 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/CollectionMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/CollectionMethods.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.desugar.backports;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -44,4 +45,10 @@
}
return Collections.unmodifiableMap(map);
}
+
+ public static <K, V> Map.Entry<K, V> mapEntry(K key, V value) {
+ return new AbstractMap.SimpleImmutableEntry<>(
+ Objects.requireNonNull(key),
+ Objects.requireNonNull(value));
+ }
}