com.google.devtools.build.android.desugar.CoreLibrarySupportTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.build.android.desugar.CoreLibrarySupportTest.java

Source

// 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();
    }
}