cuchaz.enigma.TestJarIndexInheritanceTree.java Source code

Java tutorial

Introduction

Here is the source code for cuchaz.enigma.TestJarIndexInheritanceTree.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Jeff Martin.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public
 * License v3.0 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * Contributors:
 *     Jeff Martin - initial API and implementation
 ******************************************************************************/

package cuchaz.enigma;

import cuchaz.enigma.analysis.ClassCache;
import cuchaz.enigma.analysis.EntryReference;
import cuchaz.enigma.analysis.index.EntryIndex;
import cuchaz.enigma.analysis.index.InheritanceIndex;
import cuchaz.enigma.analysis.index.JarIndex;
import cuchaz.enigma.translation.mapping.EntryResolver;
import cuchaz.enigma.translation.mapping.IndexEntryResolver;
import cuchaz.enigma.translation.representation.AccessFlags;
import cuchaz.enigma.translation.representation.entry.ClassEntry;
import cuchaz.enigma.translation.representation.entry.FieldEntry;
import cuchaz.enigma.translation.representation.entry.MethodDefEntry;
import cuchaz.enigma.translation.representation.entry.MethodEntry;
import org.junit.Test;
import org.objectweb.asm.Opcodes;

import java.nio.file.Paths;
import java.util.Collection;

import static cuchaz.enigma.TestEntryFactory.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class TestJarIndexInheritanceTree {

    private JarIndex index;

    private ClassEntry baseClass = newClass("a");
    private ClassEntry subClassA = newClass("b");
    private ClassEntry subClassAA = newClass("d");
    private ClassEntry subClassB = newClass("c");
    private FieldEntry nameField = newField(baseClass, "a", "Ljava/lang/String;");
    private FieldEntry numThingsField = newField(subClassB, "a", "I");

    public TestJarIndexInheritanceTree() throws Exception {
        ClassCache classCache = ClassCache.of(Paths.get("build/test-obf/inheritanceTree.jar"));
        index = classCache.index(ProgressListener.none());
    }

    @Test
    public void obfEntries() {
        assertThat(index.getEntryIndex().getClasses(), containsInAnyOrder(newClass("cuchaz/enigma/inputs/Keep"),
                baseClass, subClassA, subClassAA, subClassB));
    }

    @Test
    public void translationIndex() {

        InheritanceIndex index = this.index.getInheritanceIndex();

        // base class
        assertThat(index.getParents(baseClass), is(empty()));
        assertThat(index.getAncestors(baseClass), is(empty()));
        assertThat(index.getChildren(baseClass), containsInAnyOrder(subClassA, subClassB));

        // subclass a
        assertThat(index.getParents(subClassA), contains(baseClass));
        assertThat(index.getAncestors(subClassA), containsInAnyOrder(baseClass));
        assertThat(index.getChildren(subClassA), contains(subClassAA));

        // subclass aa
        assertThat(index.getParents(subClassAA), contains(subClassA));
        assertThat(index.getAncestors(subClassAA), containsInAnyOrder(subClassA, baseClass));
        assertThat(index.getChildren(subClassAA), is(empty()));

        // subclass b
        assertThat(index.getParents(subClassB), contains(baseClass));
        assertThat(index.getAncestors(subClassB), containsInAnyOrder(baseClass));
        assertThat(index.getChildren(subClassB), is(empty()));
    }

    @Test
    public void access() {
        assertThat(index.getEntryIndex().getFieldAccess(nameField), is(new AccessFlags(Opcodes.ACC_PRIVATE)));
        assertThat(index.getEntryIndex().getFieldAccess(numThingsField), is(new AccessFlags(Opcodes.ACC_PRIVATE)));
    }

    @Test
    public void relatedMethodImplementations() {

        Collection<MethodEntry> entries;

        EntryResolver resolver = new IndexEntryResolver(index);
        // getName()
        entries = resolver.resolveEquivalentMethods(newMethod(baseClass, "a", "()Ljava/lang/String;"));
        assertThat(entries, containsInAnyOrder(newMethod(baseClass, "a", "()Ljava/lang/String;"),
                newMethod(subClassAA, "a", "()Ljava/lang/String;")));
        entries = resolver.resolveEquivalentMethods(newMethod(subClassAA, "a", "()Ljava/lang/String;"));
        assertThat(entries, containsInAnyOrder(newMethod(baseClass, "a", "()Ljava/lang/String;"),
                newMethod(subClassAA, "a", "()Ljava/lang/String;")));

        // doBaseThings()
        entries = resolver.resolveEquivalentMethods(newMethod(baseClass, "a", "()V"));
        assertThat(entries, containsInAnyOrder(newMethod(baseClass, "a", "()V"), newMethod(subClassAA, "a", "()V"),
                newMethod(subClassB, "a", "()V")));
        entries = resolver.resolveEquivalentMethods(newMethod(subClassAA, "a", "()V"));
        assertThat(entries, containsInAnyOrder(newMethod(baseClass, "a", "()V"), newMethod(subClassAA, "a", "()V"),
                newMethod(subClassB, "a", "()V")));
        entries = resolver.resolveEquivalentMethods(newMethod(subClassB, "a", "()V"));
        assertThat(entries, containsInAnyOrder(newMethod(baseClass, "a", "()V"), newMethod(subClassAA, "a", "()V"),
                newMethod(subClassB, "a", "()V")));

        // doBThings
        entries = resolver.resolveEquivalentMethods(newMethod(subClassB, "b", "()V"));
        assertThat(entries, containsInAnyOrder(newMethod(subClassB, "b", "()V")));
    }

    @Test
    @SuppressWarnings("unchecked")
    public void fieldReferences() {
        Collection<EntryReference<FieldEntry, MethodDefEntry>> references;

        // name
        references = index.getReferenceIndex().getReferencesToField(nameField);
        assertThat(references,
                containsInAnyOrder(
                        newFieldReferenceByMethod(nameField, baseClass.getName(), "<init>",
                                "(Ljava/lang/String;)V"),
                        newFieldReferenceByMethod(nameField, baseClass.getName(), "a", "()Ljava/lang/String;")));

        // numThings
        references = index.getReferenceIndex().getReferencesToField(numThingsField);
        assertThat(references,
                containsInAnyOrder(newFieldReferenceByMethod(numThingsField, subClassB.getName(), "<init>", "()V"),
                        newFieldReferenceByMethod(numThingsField, subClassB.getName(), "b", "()V")));
    }

    @Test
    @SuppressWarnings("unchecked")
    public void behaviorReferences() {

        MethodEntry source;
        Collection<EntryReference<MethodEntry, MethodDefEntry>> references;

        // baseClass constructor
        source = newMethod(baseClass, "<init>", "(Ljava/lang/String;)V");
        references = index.getReferenceIndex().getReferencesToMethod(source);
        assertThat(references,
                containsInAnyOrder(
                        newBehaviorReferenceByMethod(source, subClassA.getName(), "<init>",
                                "(Ljava/lang/String;)V"),
                        newBehaviorReferenceByMethod(source, subClassB.getName(), "<init>", "()V")));

        // subClassA constructor
        source = newMethod(subClassA, "<init>", "(Ljava/lang/String;)V");
        references = index.getReferenceIndex().getReferencesToMethod(source);
        assertThat(references,
                containsInAnyOrder(newBehaviorReferenceByMethod(source, subClassAA.getName(), "<init>", "()V")));

        // baseClass.getName()
        source = newMethod(baseClass, "a", "()Ljava/lang/String;");
        references = index.getReferenceIndex().getReferencesToMethod(source);
        assertThat(references,
                containsInAnyOrder(
                        newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"),
                        newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V")));

        // subclassAA.getName()
        source = newMethod(subClassAA, "a", "()Ljava/lang/String;");
        references = index.getReferenceIndex().getReferencesToMethod(source);
        assertThat(references,
                containsInAnyOrder(newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V")));
    }

    @Test
    public void containsEntries() {
        EntryIndex entryIndex = index.getEntryIndex();
        // classes
        assertThat(entryIndex.hasClass(baseClass), is(true));
        assertThat(entryIndex.hasClass(subClassA), is(true));
        assertThat(entryIndex.hasClass(subClassAA), is(true));
        assertThat(entryIndex.hasClass(subClassB), is(true));

        // fields
        assertThat(entryIndex.hasField(nameField), is(true));
        assertThat(entryIndex.hasField(numThingsField), is(true));

        // methods
        // getName()
        assertThat(entryIndex.hasMethod(newMethod(baseClass, "a", "()Ljava/lang/String;")), is(true));
        assertThat(entryIndex.hasMethod(newMethod(subClassA, "a", "()Ljava/lang/String;")), is(false));
        assertThat(entryIndex.hasMethod(newMethod(subClassAA, "a", "()Ljava/lang/String;")), is(true));
        assertThat(entryIndex.hasMethod(newMethod(subClassB, "a", "()Ljava/lang/String;")), is(false));

        // doBaseThings()
        assertThat(entryIndex.hasMethod(newMethod(baseClass, "a", "()V")), is(true));
        assertThat(entryIndex.hasMethod(newMethod(subClassA, "a", "()V")), is(false));
        assertThat(entryIndex.hasMethod(newMethod(subClassAA, "a", "()V")), is(true));
        assertThat(entryIndex.hasMethod(newMethod(subClassB, "a", "()V")), is(true));

        // doBThings()
        assertThat(entryIndex.hasMethod(newMethod(baseClass, "b", "()V")), is(false));
        assertThat(entryIndex.hasMethod(newMethod(subClassA, "b", "()V")), is(false));
        assertThat(entryIndex.hasMethod(newMethod(subClassAA, "b", "()V")), is(false));
        assertThat(entryIndex.hasMethod(newMethod(subClassB, "b", "()V")), is(true));

    }
}