summaryrefslogtreecommitdiff
path: root/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java')
-rw-r--r--test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java455
1 files changed, 455 insertions, 0 deletions
diff --git a/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java b/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
new file mode 100644
index 0000000..9b43207
--- /dev/null
+++ b/test/java/com/google/devtools/build/android/desugar/CoreLibrarySupportTest.java
@@ -0,0 +1,455 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.android.desugar;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.desugar.io.CoreLibraryRewriter;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(JUnit4.class)
+public class CoreLibrarySupportTest {
+
+ @Test
+ public void testIsRenamedCoreLibrary() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ null,
+ ImmutableList.of("java/time/"),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(support.isRenamedCoreLibrary("java/time/X")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("java/time/y/X")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("java/io/X")).isFalse();
+ assertThat(support.isRenamedCoreLibrary("java/io/X$$CC")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("java/io/X$$Lambda$17")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("com/google/X")).isFalse();
+ }
+
+ @Test
+ public void testIsRenamedCoreLibrary_prefixedLoader() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter("__/"),
+ null,
+ ImmutableList.of("java/time/"),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(support.isRenamedCoreLibrary("__/java/time/X")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("__/java/time/y/X")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("__/java/io/X")).isFalse();
+ assertThat(support.isRenamedCoreLibrary("__/java/io/X$$CC")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("__/java/io/X$$Lambda$17")).isTrue();
+ assertThat(support.isRenamedCoreLibrary("com/google/X")).isFalse();
+ }
+
+ @Test
+ public void testRenameCoreLibrary() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ null,
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(support.renameCoreLibrary("java/time/X")).isEqualTo("j$/time/X");
+ assertThat(support.renameCoreLibrary("com/google/X")).isEqualTo("com/google/X");
+ }
+
+ @Test
+ public void testRenameCoreLibrary_prefixedLoader() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter("__/"),
+ null,
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(support.renameCoreLibrary("__/java/time/X")).isEqualTo("j$/time/X");
+ assertThat(support.renameCoreLibrary("com/google/X")).isEqualTo("com/google/X");
+ }
+
+ @Test
+ public void testMoveTarget() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter("__/"),
+ null,
+ ImmutableList.of("java/util/Helper"),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Existing#match -> java/util/Helper"),
+ ImmutableList.of());
+ assertThat(support.getMoveTarget("__/java/util/Existing", "match")).isEqualTo("j$/util/Helper");
+ assertThat(support.getMoveTarget("java/util/Existing", "match")).isEqualTo("j$/util/Helper");
+ assertThat(support.getMoveTarget("__/java/util/Existing", "matchesnot")).isNull();
+ assertThat(support.getMoveTarget("__/java/util/ExistingOther", "match")).isNull();
+ }
+
+ @Test
+ public void testIsEmulatedCoreClassOrInterface() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of("java/util/concurrent/"),
+ ImmutableList.of("java/util/Map"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(support.isEmulatedCoreClassOrInterface("java/util/Map")).isTrue();
+ assertThat(support.isEmulatedCoreClassOrInterface("java/util/Map$$Lambda$17")).isFalse();
+ assertThat(support.isEmulatedCoreClassOrInterface("java/util/Map$$CC")).isFalse();
+ assertThat(support.isEmulatedCoreClassOrInterface("java/util/HashMap")).isTrue();
+ assertThat(support.isEmulatedCoreClassOrInterface("java/util/concurrent/ConcurrentMap"))
+ .isFalse(); // false for renamed prefixes
+ assertThat(support.isEmulatedCoreClassOrInterface("com/google/Map")).isFalse();
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_emulatedDefaultMethod() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Collection"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Collection",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ true))
+ .isEqualTo(Collection.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEVIRTUAL,
+ "java/util/ArrayList",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ false))
+ .isEqualTo(Collection.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "com/google/HypotheticalListInterface",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ true))
+ .isNull();
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_emulatedImplementationMoved() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of("java/util/Moved"),
+ ImmutableList.of("java/util/Map"),
+ ImmutableList.of("java/util/LinkedHashMap#forEach->java/util/Moved"),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Map",
+ "forEach",
+ "(Ljava/util/function/BiConsumer;)V",
+ true))
+ .isEqualTo(Map.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESPECIAL,
+ "java/util/Map",
+ "forEach",
+ "(Ljava/util/function/BiConsumer;)V",
+ true))
+ .isEqualTo(Map.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEVIRTUAL,
+ "java/util/LinkedHashMap",
+ "forEach",
+ "(Ljava/util/function/BiConsumer;)V",
+ false))
+ .isEqualTo(Map.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESPECIAL,
+ "java/util/LinkedHashMap",
+ "forEach",
+ "(Ljava/util/function/BiConsumer;)V",
+ false))
+ .isEqualTo(LinkedHashMap.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESPECIAL,
+ "java/util/HashMap",
+ "forEach",
+ "(Ljava/util/function/BiConsumer;)V",
+ false))
+ .isEqualTo(Map.class);
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_abstractMethod() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Collection"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Collection",
+ "size",
+ "()I",
+ true))
+ .isNull();
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEVIRTUAL,
+ "java/util/ArrayList",
+ "size",
+ "()I",
+ false))
+ .isNull();
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_emulatedDefaultOverride() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Map"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Map",
+ "putIfAbsent",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+ true))
+ .isEqualTo(Map.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/concurrent/ConcurrentMap",
+ "putIfAbsent",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+ true))
+ .isNull(); // putIfAbsent is default in Map but abstract in ConcurrentMap
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/concurrent/ConcurrentMap",
+ "getOrDefault",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+ true))
+ .isEqualTo(ConcurrentMap.class); // conversely, getOrDefault is overridden as default method
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_staticInterfaceMethod() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Comparator"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESTATIC,
+ "java/util/Comparator",
+ "reverseOrder",
+ "()Ljava/util/Comparator;",
+ true))
+ .isEqualTo(Comparator.class);
+ }
+
+ /**
+ * Tests that call sites of renamed core libraries are treated like call sites in regular
+ * {@link InterfaceDesugaring}.
+ */
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_renamed() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of("java/util/"),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of());
+
+ // regular invocations of default methods: ignored
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Collection",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ true))
+ .isNull();
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEVIRTUAL,
+ "java/util/ArrayList",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ false))
+ .isNull();
+
+ // abstract methods: ignored
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Collection",
+ "size",
+ "()I",
+ true))
+ .isNull();
+
+ // static interface method
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESTATIC,
+ "java/util/Comparator",
+ "reverseOrder",
+ "()Ljava/util/Comparator;",
+ true))
+ .isEqualTo(Comparator.class);
+
+ // invokespecial for default methods: find nearest definition
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESPECIAL,
+ "java/util/List",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ true))
+ .isEqualTo(Collection.class);
+ // invokespecial on a class: ignore (even if there's an inherited default method)
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKESPECIAL,
+ "java/util/ArrayList",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ false))
+ .isNull();
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_ignoreRenamedInvokeInterface() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of("java/util/concurrent/"), // should return null for these
+ ImmutableList.of("java/util/Map"),
+ ImmutableList.of(),
+ ImmutableList.of());
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/Map",
+ "getOrDefault",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+ true))
+ .isEqualTo(Map.class);
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/concurrent/ConcurrentMap",
+ "getOrDefault",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+ true))
+ .isNull();
+ }
+
+ @Test
+ public void testGetCoreInterfaceRewritingTarget_excludedMethodIgnored() throws Exception {
+ CoreLibrarySupport support =
+ new CoreLibrarySupport(
+ new CoreLibraryRewriter(""),
+ Thread.currentThread().getContextClassLoader(),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Collection"),
+ ImmutableList.of(),
+ ImmutableList.of("java/util/Collection#removeIf"));
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEINTERFACE,
+ "java/util/List",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ true))
+ .isNull();
+ assertThat(
+ support.getCoreInterfaceRewritingTarget(
+ Opcodes.INVOKEVIRTUAL,
+ "java/util/ArrayList",
+ "removeIf",
+ "(Ljava/util/function/Predicate;)Z",
+ false))
+ .isNull();
+ }
+
+ @Test
+ public void testEmulatedMethod_nullExceptions() throws Exception {
+ CoreLibrarySupport.EmulatedMethod m =
+ CoreLibrarySupport.EmulatedMethod.create(1, Number.class, "a", "()V", null);
+ assertThat(m.access()).isEqualTo(1);
+ assertThat(m.owner()).isEqualTo(Number.class);
+ assertThat(m.name()).isEqualTo("a");
+ assertThat(m.descriptor()).isEqualTo("()V");
+ assertThat(m.exceptions()).isEmpty();
+ }
+
+ @Test
+ public void testEmulatedMethod_givenExceptions() throws Exception {
+ CoreLibrarySupport.EmulatedMethod m =
+ CoreLibrarySupport.EmulatedMethod.create(
+ 1, Number.class, "a", "()V", new String[] {"b", "c"});
+ assertThat(m.access()).isEqualTo(1);
+ assertThat(m.owner()).isEqualTo(Number.class);
+ assertThat(m.name()).isEqualTo("a");
+ assertThat(m.descriptor()).isEqualTo("()V");
+ assertThat(m.exceptions()).containsExactly("b", "c").inOrder();
+ }
+}