diff --git a/src/main/java/io/papermc/codebook/lvt/LvtNamer.java b/src/main/java/io/papermc/codebook/lvt/LvtNamer.java index 6c8fef8..666e184 100644 --- a/src/main/java/io/papermc/codebook/lvt/LvtNamer.java +++ b/src/main/java/io/papermc/codebook/lvt/LvtNamer.java @@ -57,16 +57,16 @@ public class LvtNamer { public static final HypoKey> SCOPED_NAMES = HypoKey.create("Scoped Names"); - private final HypoContext context; private final MappingSet mappings; - private final RootLvtSuggester lvtSuggester; + private final LvtTypeSuggester lvtTypeSuggester; + private final RootLvtSuggester lvtAssignSuggester; public final Map missedNameSuggestions = new ConcurrentHashMap<>(); public LvtNamer(final HypoContext context, final MappingSet mappings) throws IOException { this.mappings = mappings; - this.context = context; - this.lvtSuggester = new RootLvtSuggester(context, this.missedNameSuggestions); + this.lvtTypeSuggester = new LvtTypeSuggester(context); + this.lvtAssignSuggester = new RootLvtSuggester(context, this.lvtTypeSuggester, this.missedNameSuggestions); } public void processClass(final AsmClassData classData) throws IOException { @@ -208,7 +208,7 @@ private void fillNames0(final MethodData method) throws IOException { .orElse(null); if (paramName == null) { - paramName = LvtTypeSuggester.suggestNameFromType(this.context, paramTypes.get(i)); + paramName = this.lvtTypeSuggester.suggestNameFromType(paramTypes.get(i)); } final String finalName = RootLvtSuggester.determineFinalName(paramName, scopedNames); @@ -315,8 +315,9 @@ private void fillNames0(final MethodData method) throws IOException { mappedName = RootLvtSuggester.determineFinalName(paramName, scopedNames); } - final String selectedName = - mappedName != null ? mappedName : this.lvtSuggester.suggestName(method, node, lvt, scopedNames); + final String selectedName = mappedName != null + ? mappedName + : this.lvtAssignSuggester.suggestName(method, node, lvt, scopedNames); lvt.name = selectedName; usedNames[usedNameIndex++] = new UsedLvtName(lvt.name, lvt.desc, lvt.index); diff --git a/src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java b/src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java index d804dba..c15c514 100644 --- a/src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java +++ b/src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java @@ -31,14 +31,30 @@ import dev.denwav.hypo.model.data.types.PrimitiveType; import java.io.IOException; import java.util.List; +import java.util.Objects; import org.checkerframework.checker.nullness.qual.Nullable; public final class LvtTypeSuggester { - private LvtTypeSuggester() {} + private final ClassData listClass; + private final ClassData setClass; + private final ClassData mapClass; - public static String suggestNameFromType(final @Nullable HypoContext context, final JvmType type) - throws IOException { + private final HypoContext context; + + public LvtTypeSuggester(final HypoContext context) throws IOException { + this.context = context; + + final @Nullable ClassData list = context.getContextProvider().findClass("java/util/List"); + final @Nullable ClassData set = context.getContextProvider().findClass("java/util/Set"); + final @Nullable ClassData map = context.getContextProvider().findClass("java/util/Map"); + + this.listClass = Objects.requireNonNull(list, "java/util/List not found"); + this.setClass = Objects.requireNonNull(set, "java/util/Set not found"); + this.mapClass = Objects.requireNonNull(map, "java/util/Map not found"); + } + + public String suggestNameFromType(final JvmType type) throws IOException { if (type instanceof PrimitiveType) { return switch ((PrimitiveType) type) { case CHAR -> "c"; @@ -52,7 +68,7 @@ public static String suggestNameFromType(final @Nullable HypoContext context, fi case VOID -> throw new IllegalStateException("Illegal local variable type: " + type); }; } else if (type instanceof ClassType) { - return suggestNameFromClassType(context, (ClassType) type); + return this.suggestNameFromClassType((ClassType) type); } else if (type instanceof ArrayType) { final JvmType baseType = ((ArrayType) type).baseType(); if (baseType instanceof PrimitiveType) { @@ -68,15 +84,14 @@ public static String suggestNameFromType(final @Nullable HypoContext context, fi case VOID -> throw new IllegalStateException("Illegal local variable type: " + type); }; } else { - return suggestNameFromType(context, baseType) + "s"; + return this.suggestNameFromType(baseType) + "s"; } } else { throw new IllegalStateException("Unknown type: " + type); } } - private static String suggestNameFromClassType(final @Nullable HypoContext context, final ClassType type) - throws IOException { + private String suggestNameFromClassType(final ClassType type) throws IOException { final String name = type.asInternalName(); if (name.equals("Ljava/lang/String;")) { return "string"; @@ -87,23 +102,14 @@ private static String suggestNameFromClassType(final @Nullable HypoContext conte } // TODO Try to determine name from signature, rather than just descriptor - if (context != null) { - final @Nullable ClassData typeClass = context.getContextProvider().findClass(type); - if (typeClass != null) { - @Nullable - final ClassData listClass = context.getContextProvider().findClass("java/util/List"); - @Nullable - final ClassData setClass = context.getContextProvider().findClass("java/util/Set"); - @Nullable - final ClassData mapClass = context.getContextProvider().findClass("java/util/Map"); - - if (listClass != null && typeClass.doesImplement(listClass)) { - return "list"; - } else if (setClass != null && typeClass.doesImplement(setClass)) { - return "set"; - } else if (mapClass != null && typeClass.doesImplement(mapClass)) { - return "map"; - } + final @Nullable ClassData typeClass = context.getContextProvider().findClass(type); + if (typeClass != null) { + if (typeClass.doesExtendOrImplement(this.listClass)) { + return "list"; + } else if (typeClass.doesExtendOrImplement(this.setClass)) { + return "set"; + } else if (typeClass.doesExtendOrImplement(this.mapClass)) { + return "map"; } } diff --git a/src/main/java/io/papermc/codebook/lvt/RootLvtSuggester.java b/src/main/java/io/papermc/codebook/lvt/RootLvtSuggester.java index 33b2bb2..24f4c69 100644 --- a/src/main/java/io/papermc/codebook/lvt/RootLvtSuggester.java +++ b/src/main/java/io/papermc/codebook/lvt/RootLvtSuggester.java @@ -80,11 +80,16 @@ public final class RootLvtSuggester extends AbstractModule implements LvtSuggest GenericSuggester.class); private final HypoContext hypoContext; + private final LvtTypeSuggester lvtTypeSuggester; public final Map missedNameSuggestions; private final List suggesters; - public RootLvtSuggester(final HypoContext hypoContext, final Map missedNameSuggestions) { + public RootLvtSuggester( + final HypoContext hypoContext, + final LvtTypeSuggester lvtTypeSuggester, + final Map missedNameSuggestions) { this.hypoContext = hypoContext; + this.lvtTypeSuggester = lvtTypeSuggester; this.missedNameSuggestions = missedNameSuggestions; final Injector injector = Guice.createInjector(this); this.suggesters = SUGGESTERS.stream().map(injector::getInstance).toList(); @@ -93,6 +98,7 @@ public RootLvtSuggester(final HypoContext hypoContext, final Map scopedNames) { diff --git a/src/main/java/io/papermc/codebook/lvt/suggestion/SingleVerbBooleanSuggester.java b/src/main/java/io/papermc/codebook/lvt/suggestion/SingleVerbBooleanSuggester.java index bb46185..21d23e8 100644 --- a/src/main/java/io/papermc/codebook/lvt/suggestion/SingleVerbBooleanSuggester.java +++ b/src/main/java/io/papermc/codebook/lvt/suggestion/SingleVerbBooleanSuggester.java @@ -47,10 +47,12 @@ public class SingleVerbBooleanSuggester implements LvtSuggester { private final HypoContext hypoContext; + private final LvtTypeSuggester lvtTypeSuggester; @Inject - SingleVerbBooleanSuggester(final HypoContext hypoContext) { + SingleVerbBooleanSuggester(final HypoContext hypoContext, final LvtTypeSuggester lvtTypeSuggester) { this.hypoContext = hypoContext; + this.lvtTypeSuggester = lvtTypeSuggester; } @Override @@ -97,7 +99,7 @@ && isStringAllUppercase(fieldInsnNode.name)) { if ("Lnet/minecraft/tags/TagKey;".equals(paramTypeDesc)) { // isTag is better than isTagKey return "isTag"; } - final String typeName = LvtTypeSuggester.suggestNameFromType(this.hypoContext, toJvmType(paramTypeDesc)); + final String typeName = this.lvtTypeSuggester.suggestNameFromType(toJvmType(paramTypeDesc)); return prefix + capitalize(typeName, 0); } } diff --git a/src/test/java/io/papermc/codebook/lvt/LvtAssignmentSuggesterTest.java b/src/test/java/io/papermc/codebook/lvt/LvtAssignmentSuggesterTest.java index c2796c6..4a9dfce 100644 --- a/src/test/java/io/papermc/codebook/lvt/LvtAssignmentSuggesterTest.java +++ b/src/test/java/io/papermc/codebook/lvt/LvtAssignmentSuggesterTest.java @@ -51,11 +51,13 @@ import org.mockito.Mock; import org.mockito.MockSettings; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.MethodInsnNode; @ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) class LvtAssignmentSuggesterTest { static final JvmType RANDOM_SOURCE_TYPE = new ClassType("net/minecraft/util/RandomSource"); @@ -63,7 +65,14 @@ class LvtAssignmentSuggesterTest { private static final MockSettings LENIENT = withSettings().strictness(Strictness.LENIENT); private RootLvtSuggester suggester; - @Mock(strictness = Mock.Strictness.LENIENT) + @Mock + private ClassData listClass; + @Mock + private ClassData setClass; + @Mock + private ClassData mapClass; + + @Mock private ClassData randomSourceClass; @BeforeEach @@ -72,11 +81,15 @@ void setup() throws Exception { final HypoContext context = HypoContext.builder().withContextProviders(provider).build(); + when(provider.findClass("java/util/List")).thenReturn(this.listClass); + when(provider.findClass("java/util/Set")).thenReturn(this.setClass); + when(provider.findClass("java/util/Map")).thenReturn(this.mapClass); + when(provider.findClass(RANDOM_SOURCE_TYPE.asInternalName())).thenReturn(this.randomSourceClass); when(this.randomSourceClass.name()).thenReturn(RANDOM_SOURCE_TYPE.asInternalName()); - this.suggester = new RootLvtSuggester(context, new HashMap<>()); + this.suggester = new RootLvtSuggester(context, new LvtTypeSuggester(context), new HashMap<>()); } @ParameterizedTest