Skip to content

Commit

Permalink
skip primitive unboxing
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Jan 15, 2024
1 parent 8e81698 commit ab06286
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
11 changes: 11 additions & 0 deletions codebook-lvt/src/main/java/io/papermc/codebook/lvt/LvtUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import dev.denwav.hypo.asm.HypoAsmUtil;
import dev.denwav.hypo.model.data.types.JvmType;
import java.util.List;
import java.util.Locale;
import java.util.function.Predicate;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.Opcodes;
Expand Down Expand Up @@ -168,4 +169,14 @@ public static String parseSimpleTypeNameFromMethod(final String methodName, int
}
return prev;
}

public static String staticFinalFieldNameToLocalName(final String fieldName) {
final String[] split = fieldName.split("_");
final StringBuilder builder = new StringBuilder();
builder.append(split[0].toLowerCase(Locale.ENGLISH));
for (int i = 1; i < split.length; i++) {
builder.append(capitalize(split[i].toLowerCase(Locale.ENGLISH), 0));
}
return builder.toString();
}
}
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.ComplexGetSuggester;
import io.papermc.codebook.lvt.suggestion.FluentGetterSuggester;
import io.papermc.codebook.lvt.suggestion.GenericSuggester;
import io.papermc.codebook.lvt.suggestion.LvtSuggester;
Expand All @@ -56,6 +57,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
Expand All @@ -75,6 +77,7 @@ public final class RootLvtSuggester extends AbstractModule implements LvtSuggest
MathSuggester.class,
StringSuggester.class,
PositionsSuggester.class,
ComplexGetSuggester.class,
NewPrefixSuggester.class,
SingleVerbSuggester.class,
VerbPrefixBooleanSuggester.class,
Expand Down Expand Up @@ -171,9 +174,49 @@ public static String determineFinalName(final String suggestedName, final Set<St
}
}

private static final Set<BoxMethod> BOX_METHODS = Set.of(
new BoxMethod("java/lang/Byte", "byteValue", "()B"),
new BoxMethod("java/lang/Short", "shortValue", "()S"),
new BoxMethod("java/lang/Integer", "intValue", "()I"),
new BoxMethod("java/lang/Long", "longValue", "()J"),
new BoxMethod("java/lang/Float", "floatValue", "()F"),
new BoxMethod("java/lang/Double", "doubleValue", "()D"),
new BoxMethod("java/lang/Boolean", "booleanValue", "()Z"),
new BoxMethod("java/lang/Character", "charValue", "()C")
);
private static final Set<String> BOX_METHOD_NAMES = BOX_METHODS.stream().map(BoxMethod::name).collect(Collectors.toUnmodifiableSet());

private record BoxMethod(String owner, String name, String desc) {
boolean is(final MethodInsnNode node) {
return this.owner.equals(node.owner) && this.name.equals(node.name) && this.desc.equals(node.desc) && !node.itf;
}
}

private @Nullable AbstractInsnNode walkBack(final VarInsnNode assignmentNode) {
AbstractInsnNode prev = assignmentNode.getPrevious();
if (prev != null) {
final int op = prev.getOpcode();
if (op == Opcodes.INVOKEVIRTUAL) {
final MethodInsnNode methodInsnNode = (MethodInsnNode) prev;
if (BOX_METHOD_NAMES.contains(methodInsnNode.name) && BOX_METHODS.stream().anyMatch(bm -> bm.is(methodInsnNode))) {
prev = prev.getPrevious();
if (prev != null && prev.getOpcode() == Opcodes.CHECKCAST) {
return prev.getPrevious();
}
return prev;
}
}
return prev;
}
return null;
}

private @Nullable String suggestNameFromFirstAssignment(final MethodData parent, final VarInsnNode varInsn)
throws IOException {
final AbstractInsnNode prev = varInsn.getPrevious();
final @Nullable AbstractInsnNode prev = this.walkBack(varInsn);
if (prev == null) {
return null;
}
final int op = prev.getOpcode();
if (op != Opcodes.INVOKESTATIC && op != Opcodes.INVOKEVIRTUAL && op != Opcodes.INVOKEINTERFACE) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.papermc.codebook.lvt.suggestion;

import static io.papermc.codebook.lvt.LvtUtil.staticFinalFieldNameToLocalName;

import io.papermc.codebook.lvt.LvtUtil;
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.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;

public class ComplexGetSuggester implements LvtSuggester {

private static final StaticFieldEntry BLOCK_STATE_PROPERTY = new StaticFieldEntry(
Set.of(
"net/minecraft/world/level/block/state/StateHolder",
"net/minecraft/world/level/block/state/BlockState",
"net/minecraft/world/level/block/state/BlockBehaviour$Properties",
"net/minecraft/world/level/material/FluidState"
),
Set.of(
Map.entry("getValue", "(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;")
),
Set.of(
"Lnet/minecraft/world/level/block/state/properties/IntegerProperty;",
"Lnet/minecraft/world/level/block/state/properties/BooleanProperty;"
),
"Value"
);

@Override
public @Nullable String suggestFromMethod(final MethodCallContext call, final MethodInsnContext insn, final ContainerContext container) throws IOException {
final MethodInsnNode node = insn.node();
if (BLOCK_STATE_PROPERTY.test(node)) {
return BLOCK_STATE_PROPERTY.transform(node);
}
return null;
}

private record StaticFieldEntry(Set<String> owners, Set<Entry<String, String>> methods, Set<String> fieldTypes, @Nullable String suffix) {

boolean test(final MethodInsnNode node) {
return this.owners.contains(node.owner) && this.methods.stream().anyMatch(e -> e.getKey().equals(node.name) && e.getValue().equals(node.desc));
}

@Nullable String transform(final MethodInsnNode node) {
final AbstractInsnNode prev = node.getPrevious();
if (prev instanceof final FieldInsnNode fieldInsnNode && fieldInsnNode.getOpcode() == Opcodes.GETSTATIC && this.fieldTypes.contains(fieldInsnNode.desc)) {
return staticFinalFieldNameToLocalName(fieldInsnNode.name) + (this.suffix == null ? "" : this.suffix);
}
return null;
}
}

}

0 comments on commit ab06286

Please sign in to comment.