Skip to content

Commit

Permalink
Get classes in LvtTypeSuggester up front
Browse files Browse the repository at this point in the history
  • Loading branch information
DenWav committed Aug 5, 2023
1 parent d679934 commit 820c205
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 37 deletions.
15 changes: 8 additions & 7 deletions src/main/java/io/papermc/codebook/lvt/LvtNamer.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ public class LvtNamer {

public static final HypoKey<Set<String>> 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<String, AtomicInteger> 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 {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
54 changes: 30 additions & 24 deletions src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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) {
Expand All @@ -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";
Expand All @@ -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";
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/io/papermc/codebook/lvt/RootLvtSuggester.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, AtomicInteger> missedNameSuggestions;
private final List<? extends LvtSuggester> suggesters;

public RootLvtSuggester(final HypoContext hypoContext, final Map<String, AtomicInteger> missedNameSuggestions) {
public RootLvtSuggester(
final HypoContext hypoContext,
final LvtTypeSuggester lvtTypeSuggester,
final Map<String, AtomicInteger> missedNameSuggestions) {
this.hypoContext = hypoContext;
this.lvtTypeSuggester = lvtTypeSuggester;
this.missedNameSuggestions = missedNameSuggestions;
final Injector injector = Guice.createInjector(this);
this.suggesters = SUGGESTERS.stream().map(injector::getInstance).toList();
Expand All @@ -93,6 +98,7 @@ public RootLvtSuggester(final HypoContext hypoContext, final Map<String, AtomicI
@Override
protected void configure() {
this.bind(HypoContext.class).toInstance(this.hypoContext);
this.bind(LvtTypeSuggester.class).toInstance(this.lvtTypeSuggester);
}

public String suggestName(
Expand Down Expand Up @@ -139,7 +145,7 @@ public String suggestName(

// we couldn't determine a name from the assignment, so determine a name from the type
final JvmType lvtType = toJvmType(lvt.desc);
return determineFinalName(LvtTypeSuggester.suggestNameFromType(this.hypoContext, lvtType), scopedNames);
return determineFinalName(this.lvtTypeSuggester.suggestNameFromType(lvtType), scopedNames);
}

public static String determineFinalName(final String suggestedName, final Set<String> scopedNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,28 @@
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");

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
Expand All @@ -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
Expand Down

0 comments on commit 820c205

Please sign in to comment.