28 import com.sun.tools.javac.util.*; |
28 import com.sun.tools.javac.util.*; |
29 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
29 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
30 import com.sun.tools.javac.code.*; |
30 import com.sun.tools.javac.code.*; |
31 import com.sun.tools.javac.jvm.*; |
31 import com.sun.tools.javac.jvm.*; |
32 import com.sun.tools.javac.tree.*; |
32 import com.sun.tools.javac.tree.*; |
|
33 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; |
33 |
34 |
34 import com.sun.tools.javac.code.Type.*; |
35 import com.sun.tools.javac.code.Type.*; |
35 import com.sun.tools.javac.code.Symbol.*; |
36 import com.sun.tools.javac.code.Symbol.*; |
36 import com.sun.tools.javac.tree.JCTree.*; |
37 import com.sun.tools.javac.tree.JCTree.*; |
37 |
38 |
38 import static com.sun.tools.javac.code.Flags.*; |
39 import static com.sun.tools.javac.code.Flags.*; |
39 import static com.sun.tools.javac.code.Kinds.*; |
40 import static com.sun.tools.javac.code.Kinds.*; |
40 import static com.sun.tools.javac.code.TypeTags.*; |
41 import static com.sun.tools.javac.code.TypeTags.*; |
41 import javax.lang.model.element.ElementVisitor; |
42 import javax.lang.model.element.ElementVisitor; |
|
43 |
|
44 import java.util.Map; |
|
45 import java.util.HashMap; |
42 |
46 |
43 /** Helper class for name resolution, used mostly by the attribution phase. |
47 /** Helper class for name resolution, used mostly by the attribution phase. |
44 * |
48 * |
45 * <p><b>This is NOT part of any API supported by Sun Microsystems. If |
49 * <p><b>This is NOT part of any API supported by Sun Microsystems. If |
46 * you write code that depends on this, you do so at your own risk. |
50 * you write code that depends on this, you do so at your own risk. |
1190 Symbol resolveMethod(DiagnosticPosition pos, |
1194 Symbol resolveMethod(DiagnosticPosition pos, |
1191 Env<AttrContext> env, |
1195 Env<AttrContext> env, |
1192 Name name, |
1196 Name name, |
1193 List<Type> argtypes, |
1197 List<Type> argtypes, |
1194 List<Type> typeargtypes) { |
1198 List<Type> typeargtypes) { |
1195 Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false); |
1199 Symbol sym = methodNotFound; |
1196 if (varargsEnabled && sym.kind >= WRONG_MTHS) { |
1200 List<MethodResolutionPhase> steps = methodResolutionSteps; |
1197 sym = findFun(env, name, argtypes, typeargtypes, true, false); |
1201 while (steps.nonEmpty() && |
1198 if (sym.kind >= WRONG_MTHS) |
1202 steps.head.isApplicable(boxingEnabled, varargsEnabled) && |
1199 sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true); |
1203 sym.kind >= ERRONEOUS) { |
1200 } |
1204 sym = findFun(env, name, argtypes, typeargtypes, |
1201 if (sym.kind >= AMBIGUOUS) { |
1205 steps.head.isBoxingRequired, |
1202 sym = access( |
1206 env.info.varArgs = steps.head.isVarargsRequired); |
1203 sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); |
1207 methodResolutionCache.put(steps.head, sym); |
|
1208 steps = steps.tail; |
|
1209 } |
|
1210 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error |
|
1211 MethodResolutionPhase errPhase = |
|
1212 firstErroneousResolutionPhase(); |
|
1213 sym = access(methodResolutionCache.get(errPhase), |
|
1214 pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); |
|
1215 env.info.varArgs = errPhase.isVarargsRequired; |
1204 } |
1216 } |
1205 return sym; |
1217 return sym; |
1206 } |
1218 } |
1207 |
1219 |
1208 /** Resolve a qualified method identifier |
1220 /** Resolve a qualified method identifier |
1215 * @param typeargtypes The types of the invocation's type arguments. |
1227 * @param typeargtypes The types of the invocation's type arguments. |
1216 */ |
1228 */ |
1217 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, |
1229 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, |
1218 Type site, Name name, List<Type> argtypes, |
1230 Type site, Name name, List<Type> argtypes, |
1219 List<Type> typeargtypes) { |
1231 List<Type> typeargtypes) { |
1220 Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false, |
1232 Symbol sym = methodNotFound; |
1221 env.info.varArgs=false, false); |
1233 List<MethodResolutionPhase> steps = methodResolutionSteps; |
1222 if (varargsEnabled && sym.kind >= WRONG_MTHS) { |
1234 while (steps.nonEmpty() && |
1223 sym = findMethod(env, site, name, argtypes, typeargtypes, true, |
1235 steps.head.isApplicable(boxingEnabled, varargsEnabled) && |
1224 false, false); |
1236 sym.kind >= ERRONEOUS) { |
1225 if (sym.kind >= WRONG_MTHS) |
1237 sym = findMethod(env, site, name, argtypes, typeargtypes, |
1226 sym = findMethod(env, site, name, argtypes, typeargtypes, true, |
1238 steps.head.isBoxingRequired(), |
1227 env.info.varArgs=true, false); |
1239 env.info.varArgs = steps.head.isVarargsRequired(), false); |
1228 } |
1240 methodResolutionCache.put(steps.head, sym); |
1229 if (sym.kind >= AMBIGUOUS) { |
1241 steps = steps.tail; |
1230 sym = access(sym, pos, site, name, true, argtypes, typeargtypes); |
1242 } |
|
1243 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error |
|
1244 MethodResolutionPhase errPhase = |
|
1245 firstErroneousResolutionPhase(); |
|
1246 sym = access(methodResolutionCache.get(errPhase), |
|
1247 pos, site, name, true, argtypes, typeargtypes); |
|
1248 env.info.varArgs = errPhase.isVarargsRequired; |
1231 } |
1249 } |
1232 return sym; |
1250 return sym; |
1233 } |
1251 } |
1234 |
1252 |
1235 /** Resolve a qualified method identifier, throw a fatal error if not |
1253 /** Resolve a qualified method identifier, throw a fatal error if not |
1266 Symbol resolveConstructor(DiagnosticPosition pos, |
1284 Symbol resolveConstructor(DiagnosticPosition pos, |
1267 Env<AttrContext> env, |
1285 Env<AttrContext> env, |
1268 Type site, |
1286 Type site, |
1269 List<Type> argtypes, |
1287 List<Type> argtypes, |
1270 List<Type> typeargtypes) { |
1288 List<Type> typeargtypes) { |
1271 Symbol sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, false, env.info.varArgs=false); |
1289 Symbol sym = methodNotFound; |
1272 if (varargsEnabled && sym.kind >= WRONG_MTHS) { |
1290 List<MethodResolutionPhase> steps = methodResolutionSteps; |
1273 sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, false); |
1291 while (steps.nonEmpty() && |
1274 if (sym.kind >= WRONG_MTHS) |
1292 steps.head.isApplicable(boxingEnabled, varargsEnabled) && |
1275 sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, env.info.varArgs=true); |
1293 sym.kind >= ERRONEOUS) { |
1276 } |
1294 sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, |
1277 if (sym.kind >= AMBIGUOUS) { |
1295 steps.head.isBoxingRequired(), |
1278 sym = access(sym, pos, site, names.init, true, argtypes, typeargtypes); |
1296 env.info.varArgs = steps.head.isVarargsRequired()); |
|
1297 methodResolutionCache.put(steps.head, sym); |
|
1298 steps = steps.tail; |
|
1299 } |
|
1300 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error |
|
1301 MethodResolutionPhase errPhase = firstErroneousResolutionPhase(); |
|
1302 sym = access(methodResolutionCache.get(errPhase), |
|
1303 pos, site, names.init, true, argtypes, typeargtypes); |
|
1304 env.info.varArgs = errPhase.isVarargsRequired(); |
1279 } |
1305 } |
1280 return sym; |
1306 return sym; |
1281 } |
1307 } |
1282 |
1308 |
1283 /** Resolve constructor. |
1309 /** Resolve constructor. |
1731 kindName(pair.sym2), |
1757 kindName(pair.sym2), |
1732 pair.sym2, |
1758 pair.sym2, |
1733 pair.sym2.location(site, types)); |
1759 pair.sym2.location(site, types)); |
1734 } |
1760 } |
1735 } |
1761 } |
|
1762 |
|
1763 enum MethodResolutionPhase { |
|
1764 BASIC(false, false), |
|
1765 BOX(true, false), |
|
1766 VARARITY(true, true); |
|
1767 |
|
1768 boolean isBoxingRequired; |
|
1769 boolean isVarargsRequired; |
|
1770 |
|
1771 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { |
|
1772 this.isBoxingRequired = isBoxingRequired; |
|
1773 this.isVarargsRequired = isVarargsRequired; |
|
1774 } |
|
1775 |
|
1776 public boolean isBoxingRequired() { |
|
1777 return isBoxingRequired; |
|
1778 } |
|
1779 |
|
1780 public boolean isVarargsRequired() { |
|
1781 return isVarargsRequired; |
|
1782 } |
|
1783 |
|
1784 public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) { |
|
1785 return (varargsEnabled || !isVarargsRequired) && |
|
1786 (boxingEnabled || !isBoxingRequired); |
|
1787 } |
|
1788 } |
|
1789 |
|
1790 private Map<MethodResolutionPhase, Symbol> methodResolutionCache = |
|
1791 new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length); |
|
1792 |
|
1793 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); |
|
1794 |
|
1795 private MethodResolutionPhase firstErroneousResolutionPhase() { |
|
1796 MethodResolutionPhase bestSoFar = BASIC; |
|
1797 Symbol sym = methodNotFound; |
|
1798 List<MethodResolutionPhase> steps = methodResolutionSteps; |
|
1799 while (steps.nonEmpty() && |
|
1800 steps.head.isApplicable(boxingEnabled, varargsEnabled) && |
|
1801 sym.kind >= WRONG_MTHS) { |
|
1802 sym = methodResolutionCache.get(steps.head); |
|
1803 bestSoFar = steps.head; |
|
1804 steps = steps.tail; |
|
1805 } |
|
1806 return bestSoFar; |
|
1807 } |
1736 } |
1808 } |