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)); + } }