src/share/classes/com/sun/tools/javac/comp/Resolve.java

changeset 1342
1a65d6565b45
parent 1341
db36841709e4
child 1346
20e4a54b1629
equal deleted inserted replaced
1341:db36841709e4 1342:1a65d6565b45
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,

mercurial