1440 */ |
1439 */ |
1441 public Type memberType(Type t, Symbol sym) { |
1440 public Type memberType(Type t, Symbol sym) { |
1442 return (sym.flags() & STATIC) != 0 |
1441 return (sym.flags() & STATIC) != 0 |
1443 ? sym.type |
1442 ? sym.type |
1444 : memberType.visit(t, sym); |
1443 : memberType.visit(t, sym); |
1445 } |
1444 } |
1446 // where |
1445 // where |
1447 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() { |
1446 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() { |
1448 |
1447 |
1449 public Type visitType(Type t, Symbol sym) { |
1448 public Type visitType(Type t, Symbol sym) { |
1450 return sym.type; |
1449 return sym.type; |
1550 private Type erasure(Type t, boolean recurse) { |
1549 private Type erasure(Type t, boolean recurse) { |
1551 if (t.tag <= lastBaseTag) |
1550 if (t.tag <= lastBaseTag) |
1552 return t; /* fast special case */ |
1551 return t; /* fast special case */ |
1553 else |
1552 else |
1554 return erasure.visit(t, recurse); |
1553 return erasure.visit(t, recurse); |
1555 } |
1554 } |
1556 // where |
1555 // where |
1557 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() { |
1556 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() { |
1558 public Type visitType(Type t, Boolean recurse) { |
1557 public Type visitType(Type t, Boolean recurse) { |
1559 if (t.tag <= lastBaseTag) |
1558 if (t.tag <= lastBaseTag) |
1560 return t; /*fast special case*/ |
1559 return t; /*fast special case*/ |
1942 * @return true if either argument is a sub signature of the other. |
1941 * @return true if either argument is a sub signature of the other. |
1943 */ |
1942 */ |
1944 public boolean overrideEquivalent(Type t, Type s) { |
1943 public boolean overrideEquivalent(Type t, Type s) { |
1945 return hasSameArgs(t, s) || |
1944 return hasSameArgs(t, s) || |
1946 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); |
1945 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); |
|
1946 } |
|
1947 |
|
1948 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_check = |
|
1949 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>(); |
|
1950 |
|
1951 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_nocheck = |
|
1952 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>(); |
|
1953 |
|
1954 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) { |
|
1955 Map<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache = checkResult ? |
|
1956 implCache_check : implCache_nocheck; |
|
1957 SoftReference<Map<TypeSymbol, MethodSymbol>> ref_cache = implCache.get(ms); |
|
1958 Map<TypeSymbol, MethodSymbol> cache = ref_cache != null ? ref_cache.get() : null; |
|
1959 if (cache == null) { |
|
1960 cache = new HashMap<TypeSymbol, MethodSymbol>(); |
|
1961 implCache.put(ms, new SoftReference<Map<TypeSymbol, MethodSymbol>>(cache)); |
|
1962 } |
|
1963 MethodSymbol impl = cache.get(origin); |
|
1964 if (impl == null) { |
|
1965 for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) { |
|
1966 while (t.tag == TYPEVAR) |
|
1967 t = t.getUpperBound(); |
|
1968 TypeSymbol c = t.tsym; |
|
1969 for (Scope.Entry e = c.members().lookup(ms.name); |
|
1970 e.scope != null; |
|
1971 e = e.next()) { |
|
1972 if (e.sym.kind == Kinds.MTH) { |
|
1973 MethodSymbol m = (MethodSymbol) e.sym; |
|
1974 if (m.overrides(ms, origin, types, checkResult) && |
|
1975 (m.flags() & SYNTHETIC) == 0) { |
|
1976 impl = m; |
|
1977 cache.put(origin, m); |
|
1978 return impl; |
|
1979 } |
|
1980 } |
|
1981 } |
|
1982 } |
|
1983 } |
|
1984 return impl; |
1947 } |
1985 } |
1948 |
1986 |
1949 /** |
1987 /** |
1950 * Does t have the same arguments as s? It is assumed that both |
1988 * Does t have the same arguments as s? It is assumed that both |
1951 * types are (possibly polymorphic) method types. Monomorphic |
1989 * types are (possibly polymorphic) method types. Monomorphic |