|
13 | 13 | import org.jd.core.v1.model.classfile.Field; |
14 | 14 | import org.jd.core.v1.model.classfile.Method; |
15 | 15 | 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; |
16 | 18 | import org.jd.core.v1.model.javasyntax.type.*; |
17 | 19 | import org.jd.core.v1.service.converter.classfiletojavasyntax.visitor.BindTypesToTypesVisitor; |
18 | 20 | import org.jd.core.v1.service.deserializer.classfile.ClassFileFormatException; |
|
21 | 23 | import java.io.ByteArrayOutputStream; |
22 | 24 | import java.io.IOException; |
23 | 25 | import java.io.InputStream; |
24 | | -import java.util.HashMap; |
25 | | -import java.util.Iterator; |
26 | | -import java.util.Map; |
| 26 | +import java.util.*; |
27 | 27 |
|
28 | 28 | import static org.jd.core.v1.model.javasyntax.type.ObjectType.TYPE_OBJECT; |
29 | 29 | import static org.jd.core.v1.model.javasyntax.type.ObjectType.TYPE_UNDEFINED_OBJECT; |
@@ -55,7 +55,8 @@ public class TypeMaker { |
55 | 55 | private HashMap<String, ObjectType> descriptorToObjectType = new HashMap<>(1024); |
56 | 56 | private HashMap<String, ObjectType> internalTypeNameToObjectType = new HashMap<>(1024); |
57 | 57 | 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); |
59 | 60 | private HashMap<String, MethodTypes> internalTypeNameMethodNameDescriptorToMethodTypes = new HashMap<>(1024); |
60 | 61 | private HashMap<String, MethodTypes> signatureToMethodTypes = new HashMap<>(1024); |
61 | 62 |
|
@@ -878,7 +879,7 @@ public ObjectType searchSuperParameterizedType(ObjectType superObjectType, Objec |
878 | 879 | } |
879 | 880 |
|
880 | 881 | 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)) { |
882 | 883 | return true; |
883 | 884 | } else if ((left.getDimension() > 0) || (right.getDimension() > 0)) { |
884 | 885 | return false; |
@@ -1211,7 +1212,7 @@ private Type loadFieldType(ObjectType objectType, String fieldName, String descr |
1211 | 1212 | if ((type != null) && (typeArguments != null)) { |
1212 | 1213 | TypeTypes typeTypes = makeTypeTypes(internalTypeName); |
1213 | 1214 |
|
1214 | | - if (typeTypes.typeParameters != null) { |
| 1215 | + if ((typeTypes != null) && (typeTypes.typeParameters != null)) { |
1215 | 1216 | BindTypesToTypesVisitor bindTypesToTypesVisitor = new BindTypesToTypesVisitor(); |
1216 | 1217 | HashMap<String, TypeArgument> bindings = new HashMap<>(); |
1217 | 1218 |
|
@@ -1563,11 +1564,15 @@ private void loadFieldsAndMethods(String internalTypeName, byte[] data) throws E |
1563 | 1564 |
|
1564 | 1565 | int parameterCount = (methodTypes.parameterTypes == null) ? 0 : methodTypes.parameterTypes.size(); |
1565 | 1566 | key = internalTypeName + ':' + name + ':' + parameterCount; |
| 1567 | + Set<BaseType> set = internalTypeNameMethodNameParameterCountToDeclaredParameterTypes.get(key); |
1566 | 1568 |
|
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()); |
1571 | 1576 | } |
1572 | 1577 | } |
1573 | 1578 | } |
@@ -1776,50 +1781,107 @@ public String toString() { |
1776 | 1781 | } |
1777 | 1782 | } |
1778 | 1783 |
|
1779 | | - public boolean multipleMethods(String internalTypeName, String name, int parameterCount) { |
| 1784 | + public int matchCount(String internalTypeName, String name, int parameterCount, boolean constructor) { |
1780 | 1785 | String suffixKey = ":" + name + ':' + parameterCount; |
1781 | | - Boolean bool = multipleMethods(internalTypeName, suffixKey); |
1782 | | - return (bool == null) ? false : bool.booleanValue(); |
| 1786 | + return getSetOfParameterTypes(internalTypeName, suffixKey, constructor).size(); |
1783 | 1787 | } |
1784 | 1788 |
|
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(); |
1788 | 1791 |
|
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); |
1793 | 1794 |
|
1794 | | - if (bool == null) { |
1795 | | - TypeTypes typeTypes = makeTypeTypes(internalTypeName); |
| 1795 | + if (parameterCount == 0) { |
| 1796 | + return setOfParameterTypes.size(); |
| 1797 | + } |
1796 | 1798 |
|
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; |
1801 | 1803 |
|
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++; |
1814 | 1807 | } |
| 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<>(); |
1815 | 1820 |
|
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)); |
1818 | 1826 | } |
1819 | 1827 | } |
| 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); |
1820 | 1839 | } |
1821 | 1840 |
|
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; |
1823 | 1885 | } |
1824 | 1886 |
|
1825 | 1887 | public static class TypeTypes { |
|
0 commit comments