mirror of
https://github.com/moparisthebest/fernflower
synced 2025-02-16 15:00:16 -05:00
java-decompiler: extra casts on method calls omitted
(loosely based on https://github.com/JetBrains/intellij-community/pull/217)
This commit is contained in:
parent
38f1a1a9ee
commit
020f5c404b
@ -53,6 +53,8 @@ public class InvocationExprent extends Exprent {
|
||||
public static final int CONSTRUCTOR_THIS = 1;
|
||||
public static final int CONSTRUCTOR_SUPER = 2;
|
||||
|
||||
private static final BitSet EMPTY_BIT_SET = new BitSet(0);
|
||||
|
||||
private String name;
|
||||
|
||||
private String classname;
|
||||
@ -321,7 +323,7 @@ public class InvocationExprent extends Exprent {
|
||||
|
||||
break;
|
||||
case TYP_CLINIT:
|
||||
throw new RuntimeException("Explicite invocation of <clinit>");
|
||||
throw new RuntimeException("Explicit invocation of <clinit>");
|
||||
case TYP_INIT:
|
||||
if (super_qualifier != null) {
|
||||
buf.append("super(");
|
||||
@ -355,7 +357,7 @@ public class InvocationExprent extends Exprent {
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> setAmbiguousParameters = getAmbiguousParameters();
|
||||
BitSet setAmbiguousParameters = getAmbiguousParameters();
|
||||
|
||||
boolean firstParameter = true;
|
||||
int start = isEnum ? 2 : 0;
|
||||
@ -366,7 +368,7 @@ public class InvocationExprent extends Exprent {
|
||||
}
|
||||
|
||||
TextBuffer buff = new TextBuffer();
|
||||
boolean ambiguous = setAmbiguousParameters.contains(i);
|
||||
boolean ambiguous = setAmbiguousParameters.get(i);
|
||||
ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, ambiguous, tracer);
|
||||
buf.append(buff);
|
||||
|
||||
@ -379,47 +381,56 @@ public class InvocationExprent extends Exprent {
|
||||
return buf;
|
||||
}
|
||||
|
||||
private Set<Integer> getAmbiguousParameters() {
|
||||
private BitSet getAmbiguousParameters() {
|
||||
StructClass cl = DecompilerContext.getStructContext().getClass(classname);
|
||||
if (cl == null) return EMPTY_BIT_SET;
|
||||
|
||||
Set<Integer> ret = new HashSet<Integer>();
|
||||
|
||||
StructClass cstr = DecompilerContext.getStructContext().getClass(classname);
|
||||
if (cstr != null) {
|
||||
List<MethodDescriptor> lstMethods = new ArrayList<MethodDescriptor>();
|
||||
for (StructMethod meth : cstr.getMethods()) {
|
||||
if (name.equals(meth.getName())) {
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(meth.getDescriptor());
|
||||
if (md.params.length == descriptor.params.length) {
|
||||
boolean equals = true;
|
||||
for (int i = 0; i < md.params.length; i++) {
|
||||
if (md.params[i].type_family != descriptor.params[i].type_family) {
|
||||
equals = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (equals) {
|
||||
lstMethods.add(md);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lstMethods.size() > 1) {
|
||||
for (int i = 0; i < descriptor.params.length; i++) {
|
||||
VarType partype = descriptor.params[i];
|
||||
|
||||
for (MethodDescriptor md : lstMethods) {
|
||||
if (!partype.equals(md.params[i])) {
|
||||
ret.add(i);
|
||||
break;
|
||||
// check number of matches
|
||||
List<MethodDescriptor> matches = new ArrayList<MethodDescriptor>();
|
||||
nextMethod:
|
||||
for (StructMethod mt : cl.getMethods()) {
|
||||
if (name.equals(mt.getName())) {
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
|
||||
if (md.params.length == descriptor.params.length) {
|
||||
for (int i = 0; i < md.params.length; i++) {
|
||||
if (md.params[i].type_family != descriptor.params[i].type_family) {
|
||||
continue nextMethod;
|
||||
}
|
||||
}
|
||||
matches.add(md);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches.size() == 1) return EMPTY_BIT_SET;
|
||||
|
||||
return ret;
|
||||
// check if a call is unambiguous
|
||||
StructMethod mt = cl.getMethod(InterpreterUtil.makeUniqueKey(name, stringDescriptor));
|
||||
if (mt != null) {
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
|
||||
if (md.params.length == lstParameters.size()) {
|
||||
boolean exact = true;
|
||||
for (int i = 0; i < md.params.length; i++) {
|
||||
if (!md.params[i].equals(lstParameters.get(i).getExprType())) {
|
||||
exact = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exact) return EMPTY_BIT_SET;
|
||||
}
|
||||
}
|
||||
|
||||
// mark parameters
|
||||
BitSet ambiguous = new BitSet(descriptor.params.length);
|
||||
for (int i = 0; i < descriptor.params.length; i++) {
|
||||
VarType paramType = descriptor.params[i];
|
||||
for (MethodDescriptor md : matches) {
|
||||
if (!paramType.equals(md.params[i])) {
|
||||
ambiguous.set(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ambiguous;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
|
@ -35,7 +35,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class StructLocalVariableTableAttribute extends StructGeneralAttribute {
|
||||
|
||||
private Map<Integer, String> mapVarNames = new HashMap<Integer, String>();
|
||||
private Map<Integer, String> mapVarNames = Collections.emptyMap();
|
||||
|
||||
@Override
|
||||
public void initContent(ConstantPool pool) throws IOException {
|
||||
|
@ -37,4 +37,6 @@ public class SingleClassesTest extends SingleClassesTestBase {
|
||||
@Test public void testInnerClassConstructor() { doTest("pkg/TestInnerClassConstructor"); }
|
||||
@Test public void testInnerClassConstructor11() { doTest("v11/TestInnerClassConstructor"); }
|
||||
@Test public void testTryCatchFinally() { doTest("pkg/TestTryCatchFinally"); }
|
||||
@Test public void testAmbiguousCall() { doTest("pkg/TestAmbiguousCall"); }
|
||||
@Test public void testAmbiguousCallWithDebugInfo() { doTest("pkg/TestAmbiguousCallWithDebugInfo"); }
|
||||
}
|
||||
|
BIN
testData/classes/pkg/TestAmbiguousCall.class
Normal file
BIN
testData/classes/pkg/TestAmbiguousCall.class
Normal file
Binary file not shown.
BIN
testData/classes/pkg/TestAmbiguousCallWithDebugInfo.class
Normal file
BIN
testData/classes/pkg/TestAmbiguousCallWithDebugInfo.class
Normal file
Binary file not shown.
18
testData/results/TestAmbiguousCall.dec
Normal file
18
testData/results/TestAmbiguousCall.dec
Normal file
@ -0,0 +1,18 @@
|
||||
package pkg;
|
||||
|
||||
class TestAmbiguousCall {
|
||||
void m1(RuntimeException var1, String var2) {
|
||||
}
|
||||
|
||||
void m1(IllegalArgumentException var1, String var2) {
|
||||
}
|
||||
|
||||
void test() {
|
||||
IllegalArgumentException var1 = new IllegalArgumentException();
|
||||
this.m1((RuntimeException)var1, "RE");
|
||||
this.m1(var1, "IAE");
|
||||
IllegalArgumentException var2 = new IllegalArgumentException();
|
||||
this.m1((RuntimeException)var2, "RE");
|
||||
this.m1((IllegalArgumentException)var2, "IAE");
|
||||
}
|
||||
}
|
18
testData/results/TestAmbiguousCallWithDebugInfo.dec
Normal file
18
testData/results/TestAmbiguousCallWithDebugInfo.dec
Normal file
@ -0,0 +1,18 @@
|
||||
package pkg;
|
||||
|
||||
class TestAmbiguousCall {
|
||||
void m1(RuntimeException e, String s) {
|
||||
}
|
||||
|
||||
void m1(IllegalArgumentException e, String s) {
|
||||
}
|
||||
|
||||
void test() {
|
||||
IllegalArgumentException iae = new IllegalArgumentException();
|
||||
this.m1((RuntimeException)iae, "RE");
|
||||
this.m1(iae, "IAE");
|
||||
IllegalArgumentException re = new IllegalArgumentException();
|
||||
this.m1((RuntimeException)re, "RE");
|
||||
this.m1((IllegalArgumentException)re, "IAE");
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ public enum TestEnum {
|
||||
}
|
||||
|
||||
private TestEnum() {
|
||||
this((String)"?");
|
||||
this("?");
|
||||
}
|
||||
|
||||
private TestEnum(@Deprecated String var3) {
|
||||
|
16
testData/src/pkg/TestAmbiguousCall.java
Normal file
16
testData/src/pkg/TestAmbiguousCall.java
Normal file
@ -0,0 +1,16 @@
|
||||
package pkg;
|
||||
|
||||
class TestAmbiguousCall {
|
||||
void m1(RuntimeException e, String s) { }
|
||||
void m1(IllegalArgumentException e, String s) { }
|
||||
|
||||
void test() {
|
||||
IllegalArgumentException iae = new IllegalArgumentException();
|
||||
m1((RuntimeException)iae, "RE");
|
||||
m1(iae, "IAE");
|
||||
|
||||
RuntimeException re = new IllegalArgumentException();
|
||||
m1(re, "RE");
|
||||
m1((IllegalArgumentException)re, "IAE");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user