Skip to content

Commit 6470113

Browse files
author
emmanue1
committed
Fix #33 : Cast is not added when overloading method with array parameter exists
1 parent 95b4dee commit 6470113

File tree

6 files changed

+289
-80
lines changed

6 files changed

+289
-80
lines changed

src/main/java/org/jd/core/v1/model/javasyntax/type/ObjectType.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ public ObjectType createType(BaseTypeArgument typeArguments) {
165165
}
166166
}
167167

168+
public boolean rawEquals(Object o) {
169+
if (this == o) return true;
170+
if (o == null || getClass() != o.getClass()) return false;
171+
172+
ObjectType that = (ObjectType) o;
173+
174+
if (dimension != that.dimension) return false;
175+
176+
return internalName.equals(that.internalName);
177+
}
178+
168179
@Override
169180
public boolean equals(Object o) {
170181
if (this == o) return true;

src/main/java/org/jd/core/v1/model/javasyntax/type/UnmodifiableTypes.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
package org.jd.core.v1.model.javasyntax.type;
99

10-
import java.util.Collection;
11-
import java.util.ListIterator;
10+
import java.util.*;
1211
import java.util.function.Predicate;
1312
import java.util.function.UnaryOperator;
1413

@@ -71,12 +70,12 @@ public boolean retainAll(Collection<?> collection) {
7170

7271
@Override
7372
public ListIterator<Type> listIterator(int i) {
74-
throw new UnsupportedOperationException();
73+
return new UnmodifiableTypesListIterator(super.listIterator(i));
7574
}
7675

7776
@Override
7877
public ListIterator<Type> listIterator() {
79-
throw new UnsupportedOperationException();
78+
return new UnmodifiableTypesListIterator(super.listIterator());
8079
}
8180

8281
@Override
@@ -93,4 +92,25 @@ public boolean removeIf(Predicate<? super Type> predicate) {
9392
public void replaceAll(UnaryOperator<Type> unaryOperator) {
9493
throw new UnsupportedOperationException();
9594
}
95+
96+
97+
// --- ListIterator --- //
98+
private class UnmodifiableTypesListIterator implements ListIterator<Type> {
99+
protected ListIterator<Type> listIterator;
100+
101+
public UnmodifiableTypesListIterator(ListIterator<Type> listIterator) {
102+
this.listIterator = listIterator;
103+
}
104+
105+
@Override public int nextIndex() { return listIterator.nextIndex(); }
106+
@Override public int previousIndex() { return listIterator.previousIndex(); }
107+
@Override public boolean hasNext() { return listIterator.hasNext(); }
108+
@Override public boolean hasPrevious() { return listIterator.hasPrevious(); }
109+
@Override public Type next() { return listIterator.next(); }
110+
@Override public Type previous() { return listIterator.previous(); }
111+
112+
@Override public void set(Type element) { throw new UnsupportedOperationException(); }
113+
@Override public void add(Type element) { throw new UnsupportedOperationException(); }
114+
@Override public void remove() { throw new UnsupportedOperationException(); }
115+
}
96116
}

src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/util/TypeMaker.java

Lines changed: 103 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import org.jd.core.v1.model.classfile.Field;
1414
import org.jd.core.v1.model.classfile.Method;
1515
import org.jd.core.v1.model.classfile.attribute.*;
16+
import org.jd.core.v1.model.javasyntax.expression.BaseExpression;
17+
import org.jd.core.v1.model.javasyntax.expression.Expression;
1618
import org.jd.core.v1.model.javasyntax.type.*;
1719
import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.BindTypesToTypesVisitor;
1820
import org.jd.core.v1.service.deserializer.classfile.ClassFileFormatException;
@@ -21,9 +23,7 @@
2123
import java.io.ByteArrayOutputStream;
2224
import java.io.IOException;
2325
import java.io.InputStream;
24-
import java.util.HashMap;
25-
import java.util.Iterator;
26-
import java.util.Map;
26+
import java.util.*;
2727

2828
import static org.jd.core.v1.model.javasyntax.type.ObjectType.TYPE_OBJECT;
2929
import static org.jd.core.v1.model.javasyntax.type.ObjectType.TYPE_UNDEFINED_OBJECT;
@@ -55,7 +55,8 @@ public class TypeMaker {
5555
private HashMap<String, ObjectType> descriptorToObjectType = new HashMap<>(1024);
5656
private HashMap<String, ObjectType> internalTypeNameToObjectType = new HashMap<>(1024);
5757
private HashMap<String, TypeTypes> internalTypeNameToTypeTypes = new HashMap<>(1024);
58-
private HashMap<String, Boolean> internalTypeNameMethodNameParameterCountToBoolean = new HashMap<>(1024);
58+
private HashMap<String, Set<BaseType>> internalTypeNameMethodNameParameterCountToDeclaredParameterTypes = new HashMap<>(1024);
59+
private HashMap<String, Set<BaseType>> internalTypeNameMethodNameParameterCountToParameterTypes = new HashMap<>(1024);
5960
private HashMap<String, MethodTypes> internalTypeNameMethodNameDescriptorToMethodTypes = new HashMap<>(1024);
6061
private HashMap<String, MethodTypes> signatureToMethodTypes = new HashMap<>(1024);
6162

@@ -878,7 +879,7 @@ public ObjectType searchSuperParameterizedType(ObjectType superObjectType, Objec
878879
}
879880

880881
public boolean isAssignable(Map<String, BaseType> typeBounds, ObjectType left, ObjectType right) {
881-
if ((left == TYPE_UNDEFINED_OBJECT) || left.equals(TYPE_OBJECT) || left.equals(right)) {
882+
if ((right == TYPE_UNDEFINED_OBJECT) || (left == TYPE_UNDEFINED_OBJECT) || left.equals(TYPE_OBJECT) || left.equals(right)) {
882883
return true;
883884
} else if ((left.getDimension() > 0) || (right.getDimension() > 0)) {
884885
return false;
@@ -1211,7 +1212,7 @@ private Type loadFieldType(ObjectType objectType, String fieldName, String descr
12111212
if ((type != null) && (typeArguments != null)) {
12121213
TypeTypes typeTypes = makeTypeTypes(internalTypeName);
12131214

1214-
if (typeTypes.typeParameters != null) {
1215+
if ((typeTypes != null) && (typeTypes.typeParameters != null)) {
12151216
BindTypesToTypesVisitor bindTypesToTypesVisitor = new BindTypesToTypesVisitor();
12161217
HashMap<String, TypeArgument> bindings = new HashMap<>();
12171218

@@ -1563,11 +1564,15 @@ private void loadFieldsAndMethods(String internalTypeName, byte[] data) throws E
15631564

15641565
int parameterCount = (methodTypes.parameterTypes == null) ? 0 : methodTypes.parameterTypes.size();
15651566
key = internalTypeName + ':' + name + ':' + parameterCount;
1567+
Set<BaseType> set = internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.get(key);
15661568

1567-
if (internalTypeNameMethodNameParameterCountToBoolean.containsKey(key)) {
1568-
internalTypeNameMethodNameParameterCountToBoolean.put(key, Boolean.TRUE);
1569-
} else {
1570-
internalTypeNameMethodNameParameterCountToBoolean.put(key, Boolean.FALSE);
1569+
if (parameterCount > 0) {
1570+
if (set == null) {
1571+
internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.put(key, set = new HashSet<>());
1572+
}
1573+
set.add(methodTypes.parameterTypes);
1574+
} else if (set == null) {
1575+
internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.put(key, Collections.emptySet());
15711576
}
15721577
}
15731578
}
@@ -1776,50 +1781,107 @@ public String toString() {
17761781
}
17771782
}
17781783

1779-
public boolean multipleMethods(String internalTypeName, String name, int parameterCount) {
1784+
public int matchCount(String internalTypeName, String name, int parameterCount, boolean constructor) {
17801785
String suffixKey = ":" + name + ':' + parameterCount;
1781-
Boolean bool = multipleMethods(internalTypeName, suffixKey);
1782-
return (bool == null) ? false : bool.booleanValue();
1786+
return getSetOfParameterTypes(internalTypeName, suffixKey, constructor).size();
17831787
}
17841788

1785-
private Boolean multipleMethods(String internalTypeName, String suffixKey) {
1786-
String key = internalTypeName + suffixKey;
1787-
Boolean bool = internalTypeNameMethodNameParameterCountToBoolean.get(key);
1789+
public int matchCount(Map<String, BaseType> typeBounds, String internalTypeName, String name, BaseExpression parameters, boolean constructor) {
1790+
int parameterCount = parameters.size();
17881791

1789-
if (bool == null) {
1790-
// Load methods
1791-
if (loadFieldsAndMethods(internalTypeName)) {
1792-
bool = internalTypeNameMethodNameParameterCountToBoolean.get(key);
1792+
String suffixKey = ":" + name + ':' + parameterCount;
1793+
Set<BaseType> setOfParameterTypes = getSetOfParameterTypes(internalTypeName, suffixKey, constructor);
17931794

1794-
if (bool == null) {
1795-
TypeTypes typeTypes = makeTypeTypes(internalTypeName);
1795+
if (parameterCount == 0) {
1796+
return setOfParameterTypes.size();
1797+
}
17961798

1797-
if (typeTypes != null) {
1798-
if (typeTypes.superType != null) {
1799-
bool = multipleMethods(typeTypes.superType.getInternalName(), suffixKey);
1800-
}
1799+
if (setOfParameterTypes.size() <= 1) {
1800+
return setOfParameterTypes.size();
1801+
} else {
1802+
int counter = 0;
18011803

1802-
if ((bool == null) && (typeTypes.interfaces != null)) {
1803-
if (typeTypes.interfaces.isList()) {
1804-
for (Type interfaze : typeTypes.interfaces) {
1805-
bool = multipleMethods(((ObjectType)interfaze).getInternalName(), suffixKey);
1806-
if (bool != null)
1807-
break;
1808-
}
1809-
} else {
1810-
bool = multipleMethods(((ObjectType)typeTypes.interfaces.getFirst()).getInternalName(), suffixKey);
1811-
}
1812-
}
1813-
}
1804+
for (BaseType parameterTypes : setOfParameterTypes) {
1805+
if (match(typeBounds, parameterTypes, parameters)) {
1806+
counter++;
18141807
}
1808+
}
1809+
1810+
return counter;
1811+
}
1812+
}
1813+
1814+
private Set<BaseType> getSetOfParameterTypes(String internalTypeName, String suffixKey, boolean constructor) {
1815+
String key = internalTypeName + suffixKey;
1816+
Set<BaseType> setOfParameterTypes = internalTypeNameMethodNameParameterCountToParameterTypes.get(key);
1817+
1818+
if (setOfParameterTypes == null) {
1819+
setOfParameterTypes = new HashSet<>();
18151820

1816-
if (bool != null) {
1817-
internalTypeNameMethodNameParameterCountToBoolean.put(key, bool);
1821+
if (!constructor) {
1822+
TypeTypes typeTypes = makeTypeTypes(internalTypeName);
1823+
1824+
if ((typeTypes != null) && (typeTypes.superType != null)) {
1825+
setOfParameterTypes.addAll(getSetOfParameterTypes(typeTypes.superType.getInternalName(), suffixKey, constructor));
18181826
}
18191827
}
1828+
1829+
Set<BaseType> declaredParameterTypes = internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.get(key);
1830+
1831+
if ((declaredParameterTypes == null) && loadFieldsAndMethods(internalTypeName)) {
1832+
declaredParameterTypes = internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.get(key);
1833+
}
1834+
if (declaredParameterTypes != null) {
1835+
setOfParameterTypes.addAll(declaredParameterTypes);
1836+
}
1837+
1838+
internalTypeNameMethodNameParameterCountToParameterTypes.put(key, setOfParameterTypes);
18201839
}
18211840

1822-
return bool;
1841+
return setOfParameterTypes;
1842+
}
1843+
1844+
private boolean match(Map<String, BaseType> typeBounds, BaseType parameterTypes, BaseExpression parameters) {
1845+
if (parameterTypes.size() != parameters.size()) {
1846+
return false;
1847+
}
1848+
1849+
switch (parameterTypes.size()) {
1850+
case 0:
1851+
return true;
1852+
case 1:
1853+
return match(typeBounds, parameterTypes.getFirst(), parameters.getFirst().getType());
1854+
default:
1855+
Iterator<Type> iteratorType = parameterTypes.getList().iterator();
1856+
Iterator<Expression> iteratorExpression = parameters.getList().iterator();
1857+
1858+
while (iteratorType.hasNext()) {
1859+
if (!match(typeBounds, iteratorType.next(), iteratorExpression.next().getType())) {
1860+
return false;
1861+
}
1862+
}
1863+
1864+
return true;
1865+
}
1866+
}
1867+
1868+
private boolean match(Map<String, BaseType> typeBounds, Type leftType, Type rightType) {
1869+
if (leftType.equals(rightType)) {
1870+
return true;
1871+
}
1872+
1873+
if (leftType.isPrimitiveType() && rightType.isPrimitiveType()) {
1874+
int flags = ((PrimitiveType)leftType).getFlags() | ((PrimitiveType)rightType).getFlags();
1875+
return flags != 0;
1876+
}
1877+
1878+
if (leftType.isObjectType() && rightType.isObjectType()) {
1879+
ObjectType ot1 = (ObjectType)leftType;
1880+
ObjectType ot2 = (ObjectType)rightType;
1881+
return isAssignable(typeBounds, ot1, ot2);
1882+
}
1883+
1884+
return false;
18231885
}
18241886

18251887
public static class TypeTypes {

0 commit comments

Comments
 (0)