Skip to content

Commit

Permalink
Handle fluent getters for primitive return types
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Sep 15, 2023
1 parent 9fbf232 commit 53e9d67
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import dev.denwav.hypo.model.data.MethodData;
import dev.denwav.hypo.model.data.MethodDescriptor;
import dev.denwav.hypo.model.data.types.JvmType;
import io.papermc.codebook.lvt.suggestion.FluentGetterSuggester;
import io.papermc.codebook.lvt.suggestion.GenericSuggester;
import io.papermc.codebook.lvt.suggestion.LvtSuggester;
import io.papermc.codebook.lvt.suggestion.MathSuggester;
Expand Down Expand Up @@ -76,6 +77,7 @@ public final class RootLvtSuggester extends AbstractModule implements LvtSuggest
SingleVerbSuggester.class,
VerbPrefixBooleanSuggester.class,
SingleVerbBooleanSuggester.class,
FluentGetterSuggester.class,
RecordComponentSuggester.class,
GenericSuggester.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.papermc.codebook.lvt.suggestion;

import dev.denwav.hypo.model.data.types.PrimitiveType;
import io.papermc.codebook.lvt.suggestion.context.ContainerContext;
import io.papermc.codebook.lvt.suggestion.context.method.MethodCallContext;
import io.papermc.codebook.lvt.suggestion.context.method.MethodInsnContext;
import java.io.IOException;
import java.util.function.IntPredicate;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;

public class FluentGetterSuggester implements LvtSuggester {

// 3 instructions, load "this" local var, getfield, return - TODO maybe if there is a CAST,
private static final IntPredicate[] OPCODES_IN_ORDER = new IntPredicate[] {
i -> i == Opcodes.ALOAD, i -> i == Opcodes.GETFIELD, i -> i >= Opcodes.IRETURN && i <= Opcodes.RETURN};

@Override
public @Nullable String suggestFromMethod(final MethodCallContext call, final MethodInsnContext insn, final ContainerContext container) throws IOException {
// I think it's best to only work with primitive types here, as other types should already have names
// and this dramatically cuts down on the number of methods analyzed because we aren't filtering by
// method name
if (!(call.data().returnType() instanceof PrimitiveType)
|| !call.data().params().isEmpty()) {
return null;
}
int opcodeIndex = 0;
final InsnList instructions = call.node().instructions;
if (instructions.size() == 0) {
return null;
}
for (final AbstractInsnNode methodInsn : instructions) {
if (methodInsn.getOpcode() == -1) {
continue;
}
if (opcodeIndex == OPCODES_IN_ORDER.length) {
break; // matched the correct order
}
if (OPCODES_IN_ORDER[opcodeIndex].test(methodInsn.getOpcode())) {
opcodeIndex++;
} else {
return null;
}
}
if (call.data().isStatic()) { // limit static matches
if ("java/lang/System".equals(insn.node().owner) && "currentTimeMillis".equals(insn.node().name)) {
return "currentTimeMillis";
}
} else {
return call.data().name();
}
return null;
}
}

0 comments on commit 53e9d67

Please sign in to comment.