2848 } |
2848 } |
2849 } |
2849 } |
2850 return undef; |
2850 return undef; |
2851 } |
2851 } |
2852 |
2852 |
|
2853 public class CandidatesCache { |
|
2854 public Map<Entry, List<MethodSymbol>> cache = new WeakHashMap<>(); |
|
2855 |
|
2856 class Entry { |
|
2857 Type site; |
|
2858 MethodSymbol msym; |
|
2859 |
|
2860 Entry(Type site, MethodSymbol msym) { |
|
2861 this.site = site; |
|
2862 this.msym = msym; |
|
2863 } |
|
2864 |
|
2865 @Override |
|
2866 public boolean equals(Object obj) { |
|
2867 if (obj instanceof Entry) { |
|
2868 Entry e = (Entry)obj; |
|
2869 return e.msym == msym && isSameType(site, e.site); |
|
2870 } else { |
|
2871 return false; |
|
2872 } |
|
2873 } |
|
2874 |
|
2875 @Override |
|
2876 public int hashCode() { |
|
2877 return Types.this.hashCode(site) & ~msym.hashCode(); |
|
2878 } |
|
2879 } |
|
2880 |
|
2881 public List<MethodSymbol> get(Entry e) { |
|
2882 return cache.get(e); |
|
2883 } |
|
2884 |
|
2885 public void put(Entry e, List<MethodSymbol> msymbols) { |
|
2886 cache.put(e, msymbols); |
|
2887 } |
|
2888 } |
|
2889 |
|
2890 public CandidatesCache candidatesCache = new CandidatesCache(); |
2853 |
2891 |
2854 //where |
2892 //where |
2855 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { |
2893 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { |
2856 Filter<Symbol> filter = new MethodFilter(ms, site); |
2894 CandidatesCache.Entry e = candidatesCache.new Entry(site, ms); |
2857 List<MethodSymbol> candidates = List.nil(); |
2895 List<MethodSymbol> candidates = candidatesCache.get(e); |
|
2896 if (candidates == null) { |
|
2897 Filter<Symbol> filter = new MethodFilter(ms, site); |
|
2898 List<MethodSymbol> candidates2 = List.nil(); |
2858 for (Symbol s : membersClosure(site, false).getSymbols(filter)) { |
2899 for (Symbol s : membersClosure(site, false).getSymbols(filter)) { |
2859 if (!site.tsym.isInterface() && !s.owner.isInterface()) { |
2900 if (!site.tsym.isInterface() && !s.owner.isInterface()) { |
2860 return List.of((MethodSymbol)s); |
2901 return List.of((MethodSymbol)s); |
2861 } else if (!candidates.contains(s)) { |
2902 } else if (!candidates2.contains(s)) { |
2862 candidates = candidates.prepend((MethodSymbol)s); |
2903 candidates2 = candidates2.prepend((MethodSymbol)s); |
2863 } |
2904 } |
2864 } |
2905 } |
2865 return prune(candidates); |
2906 candidates = prune(candidates2); |
2866 } |
2907 candidatesCache.put(e, candidates); |
|
2908 } |
|
2909 return candidates; |
|
2910 } |
2867 |
2911 |
2868 public List<MethodSymbol> prune(List<MethodSymbol> methods) { |
2912 public List<MethodSymbol> prune(List<MethodSymbol> methods) { |
2869 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>(); |
2913 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>(); |
2870 for (MethodSymbol m1 : methods) { |
2914 for (MethodSymbol m1 : methods) { |
2871 boolean isMin_m1 = true; |
2915 boolean isMin_m1 = true; |