| 8 | import matcher.type.MethodVarInstance; |
| 9 | |
| 10 | public final class SimilarityChecker { |
| 11 | public static float compare(ClassInstance a, ClassInstance b) { |
| 12 | if (a.getMatch() != b) return 0; |
| 13 | |
| 14 | float ret = 0; |
| 15 | |
| 16 | for (MethodInstance m : a.getMethods()) { |
| 17 | if (m.getMatch() != null) { |
| 18 | ret += compare(m, m.getMatch()); |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | for (FieldInstance m : a.getFields()) { |
| 23 | if (m.getMatch() != null) { |
| 24 | ret += compare(m, m.getMatch()); |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | int div = a.getMethods().length + a.getFields().length; |
| 29 | |
| 30 | for (MethodInstance m : b.getMethods()) { |
| 31 | if (m.getMatch() == null) { |
| 32 | div++; |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | for (FieldInstance m : b.getFields()) { |
| 37 | if (m.getMatch() == null) { |
| 38 | div++; |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | return div > 0 ? ret / div : 1; |
| 43 | } |
| 44 | |
| 45 | public static <T extends MemberInstance<T>> float compare(MemberInstance<T> a, MemberInstance<T> b) { |
| 46 | if (a instanceof MethodInstance) { |
| 47 | return compare((MethodInstance) a, (MethodInstance) b); |
| 48 | } else { |
| 49 | return compare((FieldInstance) a, (FieldInstance) b); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | public static float compare(MethodInstance a, MethodInstance b) { |
| 54 | if (a.getMatch() != b) return 0; |
| 55 | |
| 56 | if (a.getAsmNode() == null || b.getAsmNode() == null) { |
| 57 | return (a.getAsmNode() == null) == (b.getAsmNode() == null) ? 1 : 0; |
| 58 | } |
| 59 | |
| 60 | float retTypeScore = ClassifierUtil.checkPotentialEquality(a.getRetType(), b.getRetType()) ? 1 : 0; |
| 61 | float argTypeScore = 0; |
| 62 | |
| 63 | for (MethodVarInstance v : a.getArgs()) { |
| 64 | if (v.getMatch() != null) { |
| 65 | argTypeScore += compare(v, v.getMatch()); |
| 66 | } |
| 67 | } |
nothing calls this directly
no outgoing calls
no test coverage detected