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

changeset 160
a23e1dc02698
parent 156
db77bf6adb53
child 161
ddd75a295501
equal deleted inserted replaced
159:5e54a59bcee7 160:a23e1dc02698
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 }

mercurial