25 |
25 |
26 package com.sun.tools.javac.comp; |
26 package com.sun.tools.javac.comp; |
27 |
27 |
28 import com.sun.tools.javac.api.Formattable.LocalizedString; |
28 import com.sun.tools.javac.api.Formattable.LocalizedString; |
29 import com.sun.tools.javac.code.*; |
29 import com.sun.tools.javac.code.*; |
|
30 import com.sun.tools.javac.code.Symbol.*; |
30 import com.sun.tools.javac.code.Type.*; |
31 import com.sun.tools.javac.code.Type.*; |
31 import com.sun.tools.javac.code.Symbol.*; |
|
32 import com.sun.tools.javac.comp.Attr.ResultInfo; |
32 import com.sun.tools.javac.comp.Attr.ResultInfo; |
33 import com.sun.tools.javac.comp.Check.CheckContext; |
33 import com.sun.tools.javac.comp.Check.CheckContext; |
34 import com.sun.tools.javac.comp.Infer.InferenceContext; |
34 import com.sun.tools.javac.comp.Infer.InferenceContext; |
35 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; |
35 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; |
36 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; |
36 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; |
46 import java.util.Arrays; |
46 import java.util.Arrays; |
47 import java.util.Collection; |
47 import java.util.Collection; |
48 import java.util.EnumMap; |
48 import java.util.EnumMap; |
49 import java.util.EnumSet; |
49 import java.util.EnumSet; |
50 import java.util.HashSet; |
50 import java.util.HashSet; |
|
51 import java.util.Iterator; |
51 import java.util.Map; |
52 import java.util.Map; |
52 import java.util.Set; |
53 import java.util.Set; |
53 |
54 |
54 import javax.lang.model.element.ElementVisitor; |
55 import javax.lang.model.element.ElementVisitor; |
55 |
56 |
58 import static com.sun.tools.javac.code.Kinds.*; |
59 import static com.sun.tools.javac.code.Kinds.*; |
59 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; |
60 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; |
60 import static com.sun.tools.javac.code.TypeTags.*; |
61 import static com.sun.tools.javac.code.TypeTags.*; |
61 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; |
62 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; |
62 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
63 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
63 import java.util.Iterator; |
|
64 |
64 |
65 /** Helper class for name resolution, used mostly by the attribution phase. |
65 /** Helper class for name resolution, used mostly by the attribution phase. |
66 * |
66 * |
67 * <p><b>This is NOT part of any supported API. |
67 * <p><b>This is NOT part of any supported API. |
68 * If you write code that depends on this, you do so at your own risk. |
68 * If you write code that depends on this, you do so at your own risk. |
1198 boolean abstractOk = true; |
1198 boolean abstractOk = true; |
1199 List<Type> itypes = List.nil(); |
1199 List<Type> itypes = List.nil(); |
1200 for (TypeSymbol s : superclasses(intype)) { |
1200 for (TypeSymbol s : superclasses(intype)) { |
1201 bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes, |
1201 bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes, |
1202 s.members(), bestSoFar, allowBoxing, useVarargs, operator, true); |
1202 s.members(), bestSoFar, allowBoxing, useVarargs, operator, true); |
1203 abstractOk &= excludeAbstractsFilter.accepts(s); |
1203 //We should not look for abstract methods if receiver is a concrete class |
|
1204 //(as concrete classes are expected to implement all abstracts coming |
|
1205 //from superinterfaces) |
|
1206 abstractOk &= (s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0; |
1204 if (abstractOk) { |
1207 if (abstractOk) { |
1205 for (Type itype : types.interfaces(s.type)) { |
1208 for (Type itype : types.interfaces(s.type)) { |
1206 itypes = types.union(types.closure(itype), itypes); |
1209 itypes = types.union(types.closure(itype), itypes); |
1207 } |
1210 } |
1208 } |
1211 } |
1245 return new Iterable<TypeSymbol>() { |
1248 return new Iterable<TypeSymbol>() { |
1246 public Iterator<TypeSymbol> iterator() { |
1249 public Iterator<TypeSymbol> iterator() { |
1247 return new Iterator<TypeSymbol>() { |
1250 return new Iterator<TypeSymbol>() { |
1248 |
1251 |
1249 List<TypeSymbol> seen = List.nil(); |
1252 List<TypeSymbol> seen = List.nil(); |
1250 TypeSymbol currentSym = getSymbol(intype); |
1253 TypeSymbol currentSym = symbolFor(intype); |
|
1254 TypeSymbol prevSym = null; |
1251 |
1255 |
1252 public boolean hasNext() { |
1256 public boolean hasNext() { |
|
1257 if (currentSym == syms.noSymbol) { |
|
1258 currentSym = symbolFor(types.supertype(prevSym.type)); |
|
1259 } |
1253 return currentSym != null; |
1260 return currentSym != null; |
1254 } |
1261 } |
1255 |
1262 |
1256 public TypeSymbol next() { |
1263 public TypeSymbol next() { |
1257 TypeSymbol prevSym = currentSym; |
1264 prevSym = currentSym; |
1258 currentSym = getSymbol(types.supertype(currentSym.type)); |
1265 currentSym = syms.noSymbol; |
|
1266 Assert.check(prevSym != null || prevSym != syms.noSymbol); |
1259 return prevSym; |
1267 return prevSym; |
1260 } |
1268 } |
1261 |
1269 |
1262 public void remove() { |
1270 public void remove() { |
1263 throw new UnsupportedOperationException("Not supported yet."); |
1271 throw new UnsupportedOperationException(); |
1264 } |
1272 } |
1265 |
1273 |
1266 TypeSymbol getSymbol(Type intype) { |
1274 TypeSymbol symbolFor(Type t) { |
1267 if (intype.tag != CLASS && |
1275 if (t.tag != CLASS && |
1268 intype.tag != TYPEVAR) { |
1276 t.tag != TYPEVAR) { |
1269 return null; |
1277 return null; |
1270 } |
1278 } |
1271 while (intype.tag == TYPEVAR) |
1279 while (t.tag == TYPEVAR) |
1272 intype = intype.getUpperBound(); |
1280 t = t.getUpperBound(); |
1273 if (seen.contains(intype.tsym)) { |
1281 if (seen.contains(t.tsym)) { |
1274 //degenerate case in which we have a circular |
1282 //degenerate case in which we have a circular |
1275 //class hierarchy - because of ill-formed classfiles |
1283 //class hierarchy - because of ill-formed classfiles |
1276 return null; |
1284 return null; |
1277 } |
1285 } |
1278 seen = seen.prepend(intype.tsym); |
1286 seen = seen.prepend(t.tsym); |
1279 return intype.tsym; |
1287 return t.tsym; |
1280 } |
1288 } |
1281 }; |
1289 }; |
1282 } |
1290 } |
1283 }; |
1291 }; |
1284 } |
1292 } |
1285 |
|
1286 /** |
|
1287 * We should not look for abstract methods if receiver is a concrete class |
|
1288 * (as concrete classes are expected to implement all abstracts coming |
|
1289 * from superinterfaces) |
|
1290 */ |
|
1291 Filter<Symbol> excludeAbstractsFilter = new Filter<Symbol>() { |
|
1292 public boolean accepts(Symbol s) { |
|
1293 return (s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0; |
|
1294 } |
|
1295 }; |
|
1296 |
1293 |
1297 /** |
1294 /** |
1298 * Lookup a method with given name and argument types in a given scope |
1295 * Lookup a method with given name and argument types in a given scope |
1299 */ |
1296 */ |
1300 Symbol lookupMethod(Env<AttrContext> env, |
1297 Symbol lookupMethod(Env<AttrContext> env, |