3333import dev .denwav .hypo .model .data .MethodData ;
3434import dev .denwav .hypo .model .data .MethodDescriptor ;
3535import dev .denwav .hypo .model .data .types .JvmType ;
36+ import io .papermc .codebook .lvt .suggestion .ComplexGetSuggester ;
3637import io .papermc .codebook .lvt .suggestion .FluentGetterSuggester ;
3738import io .papermc .codebook .lvt .suggestion .GenericSuggester ;
3839import io .papermc .codebook .lvt .suggestion .LvtSuggester ;
5657import java .io .IOException ;
5758import java .util .List ;
5859import java .util .Set ;
60+ import java .util .stream .Collectors ;
5961import org .checkerframework .checker .nullness .qual .Nullable ;
6062import org .objectweb .asm .Opcodes ;
6163import org .objectweb .asm .tree .AbstractInsnNode ;
@@ -75,6 +77,7 @@ public final class RootLvtSuggester extends AbstractModule implements LvtSuggest
7577 MathSuggester .class ,
7678 StringSuggester .class ,
7779 PositionsSuggester .class ,
80+ ComplexGetSuggester .class ,
7881 NewPrefixSuggester .class ,
7982 SingleVerbSuggester .class ,
8083 VerbPrefixBooleanSuggester .class ,
@@ -171,9 +174,53 @@ public static String determineFinalName(final String suggestedName, final Set<St
171174 }
172175 }
173176
177+ private static final Set <BoxMethod > BOX_METHODS = Set .of (
178+ new BoxMethod ("java/lang/Byte" , "byteValue" , "()B" ),
179+ new BoxMethod ("java/lang/Short" , "shortValue" , "()S" ),
180+ new BoxMethod ("java/lang/Integer" , "intValue" , "()I" ),
181+ new BoxMethod ("java/lang/Long" , "longValue" , "()J" ),
182+ new BoxMethod ("java/lang/Float" , "floatValue" , "()F" ),
183+ new BoxMethod ("java/lang/Double" , "doubleValue" , "()D" ),
184+ new BoxMethod ("java/lang/Boolean" , "booleanValue" , "()Z" ),
185+ new BoxMethod ("java/lang/Character" , "charValue" , "()C" ));
186+ private static final Set <String > BOX_METHOD_NAMES =
187+ BOX_METHODS .stream ().map (BoxMethod ::name ).collect (Collectors .toUnmodifiableSet ());
188+
189+ private record BoxMethod (String owner , String name , String desc ) {
190+ boolean is (final MethodInsnNode node ) {
191+ return this .owner .equals (node .owner )
192+ && this .name .equals (node .name )
193+ && this .desc .equals (node .desc )
194+ && !node .itf ;
195+ }
196+ }
197+
198+ private @ Nullable AbstractInsnNode walkBack (final VarInsnNode assignmentNode ) {
199+ AbstractInsnNode prev = assignmentNode .getPrevious ();
200+ if (prev != null ) {
201+ final int op = prev .getOpcode ();
202+ if (op == Opcodes .INVOKEVIRTUAL ) {
203+ final MethodInsnNode methodInsnNode = (MethodInsnNode ) prev ;
204+ if (BOX_METHOD_NAMES .contains (methodInsnNode .name )
205+ && BOX_METHODS .stream ().anyMatch (bm -> bm .is (methodInsnNode ))) {
206+ prev = prev .getPrevious ();
207+ if (prev != null && prev .getOpcode () == Opcodes .CHECKCAST ) {
208+ return prev .getPrevious ();
209+ }
210+ return prev ;
211+ }
212+ }
213+ return prev ;
214+ }
215+ return null ;
216+ }
217+
174218 private @ Nullable String suggestNameFromFirstAssignment (final MethodData parent , final VarInsnNode varInsn )
175219 throws IOException {
176- final AbstractInsnNode prev = varInsn .getPrevious ();
220+ final @ Nullable AbstractInsnNode prev = this .walkBack (varInsn );
221+ if (prev == null ) {
222+ return null ;
223+ }
177224 final int op = prev .getOpcode ();
178225 if (op != Opcodes .INVOKESTATIC && op != Opcodes .INVOKEVIRTUAL && op != Opcodes .INVOKEINTERFACE ) {
179226 return null ;
0 commit comments