Skip to content

Commit

Permalink
Properly walk the inheritance tree when checking for possibly ambiguo…
Browse files Browse the repository at this point in the history
…us unboxing calls (#444)
  • Loading branch information
Owen1212055 authored Dec 16, 2024
1 parent ef138de commit d63fc67
Show file tree
Hide file tree
Showing 4 changed files with 461 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler.exps;

import org.jetbrains.annotations.Nullable;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
Expand Down Expand Up @@ -34,6 +35,7 @@

import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class InvocationExprent extends Exprent {
Expand Down Expand Up @@ -992,32 +994,30 @@ public TextBuffer appendParamList(int indent) {
VarType.VARTYPE_CHAR;
}

// TODO: better way to select boxing? this doesn't seem to consider superclass implementations
int count = 0;
StructClass stClass = DecompilerContext.getStructContext().getClass(classname);
if (stClass != null) {
nextMethod:
for (StructMethod mt : stClass.getMethods()) {
if (name.equals(mt.getName()) && (currCls == null || canAccess(currCls.classStruct, mt))) {
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
if (md.params.length == descriptor.params.length) {
for (int x = 0; x < md.params.length; x++) {
if (md.params[x].typeFamily != descriptor.params[x].typeFamily &&
md.params[x].typeFamily != types[x].typeFamily
) {
continue nextMethod;
}
List<StructMethod> customMatchedDescriptors = getMatchedDescriptors((md) -> {
if (md.params.length == descriptor.params.length) {
for (int x = 0; x < md.params.length; x++) {
if (md.params[x].typeFamily != descriptor.params[x].typeFamily &&
md.params[x].typeFamily != types[x].typeFamily
) {
return false;
}

if (md.params[x].arrayDim != descriptor.params[x].arrayDim &&
md.params[x].arrayDim != types[x].arrayDim
) {
continue nextMethod;
}
if (md.params[x].arrayDim != descriptor.params[x].arrayDim &&
md.params[x].arrayDim != types[x].arrayDim
) {
return false;
}
count++;
}
return true;
}
}

return false;
});
count = customMatchedDescriptors.size();
}

if (count != matches.size()) { //We become more ambiguous? Lets keep the explicit boxing
Expand Down Expand Up @@ -1286,6 +1286,9 @@ public boolean shouldForceUnboxing() {
}

private List<StructMethod> getMatchedDescriptors() {
return getMatchedDescriptors(null);
}
private List<StructMethod> getMatchedDescriptors(@Nullable Predicate<MethodDescriptor> customParamMatcher) {
List<StructMethod> matches = new ArrayList<>();
ClassNode currCls = DecompilerContext.getContextProperty(DecompilerContext.CURRENT_CLASS_NODE);
StructClass cl = DecompilerContext.getStructContext().getClass(classname);
Expand All @@ -1303,7 +1306,13 @@ private List<StructMethod> getMatchedDescriptors() {
for (StructMethod mt : cls.getMethods()) {
if (name.equals(mt.getName())) {
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
if (matches(md.params, descriptor.params) && (currCls == null || canAccess(currCls.classStruct, mt))) {
boolean matchedParams;
if (customParamMatcher == null) {
matchedParams = matches(md.params, descriptor.params);
} else {
matchedParams = customParamMatcher.test(md);
}
if (matchedParams && (currCls == null || canAccess(currCls.classStruct, mt))) {
matches.add(mt);
}
}
Expand Down
1 change: 1 addition & 0 deletions test/org/jetbrains/java/decompiler/SingleClassesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ private void registerDefault() {
register(JAVA_8, "TestAnonymousClassToLambda");
// TODO: broken stack processing, deleted ternary!
register(JAVA_17, "TestPatternMatchingLoops");
register(JAVA_8, "TestBoxingSuperclass");
}

private void registerEntireClassPath() {
Expand Down
Loading

0 comments on commit d63fc67

Please sign in to comment.