diff --git a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/IndexEntryResolver.java b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/IndexEntryResolver.java index 9c53cc713..e7b553d32 100644 --- a/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/IndexEntryResolver.java +++ b/enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/IndexEntryResolver.java @@ -64,7 +64,7 @@ public > Collection resolveEntry(E entry, ResolutionStrate } Entry entryAsClassChild = this.getClassChild(entry); - if (entryAsClassChild != null && !(entryAsClassChild instanceof ClassEntry)) { + if (entryAsClassChild != null) { AccessFlags access = this.entryIndex.getEntryAccess(entryAsClassChild); // If we're looking for the closest and this entry exists, we're done looking @@ -73,8 +73,12 @@ public > Collection resolveEntry(E entry, ResolutionStrate } // Don't search existing private and/or static entries up the hierarchy - // Fields and classes can't be redefined, don't search them up the hierarchy - if (access != null && (access.isPrivate() || access.isStatic() || entry instanceof FieldEntry || entry instanceof ClassEntry)) { + // Fields can't be redefined, don't search them up the hierarchy + // Constructors can't be redefined, don't search them up the hierarchy + if ( + (access != null && (access.isPrivate() || access.isStatic() || entry instanceof FieldEntry)) + || (entry instanceof MethodEntry method && method.isConstructor()) + ) { return Collections.singleton(entry); } else { // Search the entry up the hierarchy; if the entry exists we can skip static entries, since this one isn't static @@ -97,7 +101,10 @@ public > Collection resolveEntry(E entry, ResolutionStrate * Get a direct child of any class that is an ancestor of the given entry. * * @param entry the descendant of a class - * @return the direct child of a class, which is an ancestor of the given entry or the entry itself + * + * @return the direct child of a class, which is an ancestor of the given entry or the entry itself; + * returns {@code null} if the passed {@code entry} is a {@link ClassEntry} or if all of its ancestors are + * {@link ClassEntry}s; never returns a {@link ClassEntry} */ @Nullable private Entry getClassChild(Entry entry) { diff --git a/enigma/src/test/java/org/quiltmc/enigma/TestJarIndexInheritanceTree.java b/enigma/src/test/java/org/quiltmc/enigma/TestJarIndexInheritanceTree.java index cf823f561..4144eb309 100644 --- a/enigma/src/test/java/org/quiltmc/enigma/TestJarIndexInheritanceTree.java +++ b/enigma/src/test/java/org/quiltmc/enigma/TestJarIndexInheritanceTree.java @@ -15,6 +15,7 @@ import org.quiltmc.enigma.api.class_provider.ProjectClassProvider; import org.quiltmc.enigma.api.translation.mapping.EntryResolver; import org.quiltmc.enigma.api.translation.mapping.IndexEntryResolver; +import org.quiltmc.enigma.api.translation.mapping.ResolutionStrategy; import org.quiltmc.enigma.api.translation.representation.AccessFlags; import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; import org.quiltmc.enigma.api.translation.representation.entry.FieldEntry; @@ -35,13 +36,19 @@ public class TestJarIndexInheritanceTree { public static final Path JAR = TestUtil.obfJar("inheritance_tree"); private static final ClassEntry OBJECT_CLASS = TestEntryFactory.newClass("java/lang/Object"); + private static final ClassEntry BASE_CLASS = TestEntryFactory.newClass("a"); - private static final ClassEntry SUB_CLASS_A = TestEntryFactory.newClass("c"); - private static final ClassEntry SUB_CLASS_AA = TestEntryFactory.newClass("e"); - private static final ClassEntry SUB_CLASS_B = TestEntryFactory.newClass("d"); + private static final ClassEntry SUB_CLASS_A = TestEntryFactory.newClass("e"); + private static final ClassEntry SUB_CLASS_AA = TestEntryFactory.newClass("g"); + private static final ClassEntry SUB_CLASS_B = TestEntryFactory.newClass("f"); private static final FieldEntry NAME_FIELD = TestEntryFactory.newField(BASE_CLASS, "a", "Ljava/lang/String;"); private static final FieldEntry NUM_THINGS_FIELD = TestEntryFactory.newField(SUB_CLASS_B, "a", "I"); + private static final ClassEntry CONSTRUCTOR_PARENT = TestEntryFactory.newClass("b"); + private static final ClassEntry CONSTRUCTOR_SUB_CLASS = TestEntryFactory.newClass("c"); + private static final MethodEntry SUB_CLASS_NO_ARGS_CONSTRUCTOR = TestEntryFactory.newMethod(CONSTRUCTOR_SUB_CLASS.getFullName(), "", "()V"); + private static final MethodEntry SUB_CLASS_INT_CONSTRUCTOR = TestEntryFactory.newMethod(CONSTRUCTOR_SUB_CLASS.getFullName(), "", "(I)V"); + private final JarIndex index; public TestJarIndexInheritanceTree() throws Exception { @@ -55,6 +62,7 @@ public void obfEntries() { assertThat(this.index.getIndex(EntryIndex.class).getClasses(), Matchers.containsInAnyOrder( TestEntryFactory.newClass("org/quiltmc/enigma/input/Keep"), BASE_CLASS, SUB_CLASS_A, SUB_CLASS_AA, SUB_CLASS_B, + CONSTRUCTOR_PARENT, CONSTRUCTOR_SUB_CLASS, InterfaceTree.OUTER, InterfaceTree.ROOT, InterfaceTree.BRANCH_1_2, InterfaceTree.BRANCH_3_4, @@ -224,6 +232,20 @@ public void containsEntries() { } @Test + public void noConstructorInheritance() { + assertThat( + this.index.getEntryResolver() + .resolveEntry(SUB_CLASS_NO_ARGS_CONSTRUCTOR, ResolutionStrategy.RESOLVE_ROOT), + contains(SUB_CLASS_NO_ARGS_CONSTRUCTOR) + ); + + assertThat( + this.index.getEntryResolver() + .resolveEntry(SUB_CLASS_INT_CONSTRUCTOR, ResolutionStrategy.RESOLVE_ROOT), + contains(SUB_CLASS_INT_CONSTRUCTOR) + ); + } + void streamAncestorsOrder() { final List ancestors = this.index.getIndex(InheritanceIndex.class) .streamAncestors(InterfaceTree.ROOT) @@ -268,7 +290,7 @@ void getAncestorsOrder() { } private interface InterfaceTree { - String OUTER_NAME = "b"; + String OUTER_NAME = "d"; String OUTER_PREFIX = OUTER_NAME + "$"; ClassEntry OUTER = TestEntryFactory.newClass(OUTER_NAME); diff --git a/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorParent.java b/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorParent.java new file mode 100644 index 000000000..e3f8fe495 --- /dev/null +++ b/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorParent.java @@ -0,0 +1,7 @@ +package org.quiltmc.enigma.input.inheritance_tree; + +public class ConstructorParent { + ConstructorParent() { } + + ConstructorParent(int i) { } +} diff --git a/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorSubClass.java b/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorSubClass.java new file mode 100644 index 000000000..781b51c89 --- /dev/null +++ b/enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/ConstructorSubClass.java @@ -0,0 +1,7 @@ +package org.quiltmc.enigma.input.inheritance_tree; + +class ConstructorSubClass extends ConstructorParent { + ConstructorSubClass() { } + + ConstructorSubClass(int i) { } +}