65 TreeInfo treeinfo; |
65 TreeInfo treeinfo; |
66 Types types; |
66 Types types; |
67 JCDiagnostic.Factory diags; |
67 JCDiagnostic.Factory diags; |
68 public final boolean boxingEnabled; // = source.allowBoxing(); |
68 public final boolean boxingEnabled; // = source.allowBoxing(); |
69 public final boolean varargsEnabled; // = source.allowVarargs(); |
69 public final boolean varargsEnabled; // = source.allowVarargs(); |
|
70 public final boolean allowInvokedynamic; // = options.get("invokedynamic"); |
70 private final boolean debugResolve; |
71 private final boolean debugResolve; |
71 |
72 |
72 public static Resolve instance(Context context) { |
73 public static Resolve instance(Context context) { |
73 Resolve instance = context.get(resolveKey); |
74 Resolve instance = context.get(resolveKey); |
74 if (instance == null) |
75 if (instance == null) |
102 Source source = Source.instance(context); |
103 Source source = Source.instance(context); |
103 boxingEnabled = source.allowBoxing(); |
104 boxingEnabled = source.allowBoxing(); |
104 varargsEnabled = source.allowVarargs(); |
105 varargsEnabled = source.allowVarargs(); |
105 Options options = Options.instance(context); |
106 Options options = Options.instance(context); |
106 debugResolve = options.get("debugresolve") != null; |
107 debugResolve = options.get("debugresolve") != null; |
|
108 allowInvokedynamic = options.get("invokedynamic") != null; |
107 } |
109 } |
108 |
110 |
109 /** error symbols, which are returned when resolution fails |
111 /** error symbols, which are returned when resolution fails |
110 */ |
112 */ |
111 final ResolveError varNotFound; |
113 final ResolveError varNotFound; |
879 } |
881 } |
880 } |
882 } |
881 return bestSoFar; |
883 return bestSoFar; |
882 } |
884 } |
883 |
885 |
|
886 /** Find or create an implicit method of exactly the given type (after erasure). |
|
887 * Searches in a side table, not the main scope of the site. |
|
888 * This emulates the lookup process required by JSR 292 in JVM. |
|
889 * @param env The current environment. |
|
890 * @param site The original type from where the selection |
|
891 * takes place. |
|
892 * @param name The method's name. |
|
893 * @param argtypes The method's value arguments. |
|
894 * @param typeargtypes The method's type arguments |
|
895 */ |
|
896 Symbol findImplicitMethod(Env<AttrContext> env, |
|
897 Type site, |
|
898 Name name, |
|
899 List<Type> argtypes, |
|
900 List<Type> typeargtypes) { |
|
901 assert allowInvokedynamic; |
|
902 assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke); |
|
903 ClassSymbol c = (ClassSymbol) site.tsym; |
|
904 Scope implicit = c.members().next; |
|
905 if (implicit == null) { |
|
906 c.members().next = implicit = new Scope(c); |
|
907 } |
|
908 Type restype; |
|
909 if (typeargtypes.isEmpty()) { |
|
910 restype = syms.objectType; |
|
911 } else { |
|
912 restype = typeargtypes.head; |
|
913 if (!typeargtypes.tail.isEmpty()) |
|
914 return methodNotFound; |
|
915 } |
|
916 List<Type> paramtypes = Type.map(argtypes, implicitArgType); |
|
917 MethodType mtype = new MethodType(paramtypes, |
|
918 restype, |
|
919 List.<Type>nil(), |
|
920 syms.methodClass); |
|
921 int flags = PUBLIC | ABSTRACT; |
|
922 if (site == syms.invokeDynamicType) flags |= STATIC; |
|
923 Symbol m = null; |
|
924 for (Scope.Entry e = implicit.lookup(name); |
|
925 e.scope != null; |
|
926 e = e.next()) { |
|
927 Symbol sym = e.sym; |
|
928 assert sym.kind == MTH; |
|
929 if (types.isSameType(mtype, sym.type) |
|
930 && (sym.flags() & STATIC) == (flags & STATIC)) { |
|
931 m = sym; |
|
932 break; |
|
933 } |
|
934 } |
|
935 if (m == null) { |
|
936 // create the desired method |
|
937 m = new MethodSymbol(flags, name, mtype, c); |
|
938 implicit.enter(m); |
|
939 } |
|
940 assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(), |
|
941 false, false, Warner.noWarnings); |
|
942 assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings); |
|
943 return m; |
|
944 } |
|
945 //where |
|
946 Mapping implicitArgType = new Mapping ("implicitArgType") { |
|
947 public Type apply(Type t) { return implicitArgType(t); } |
|
948 }; |
|
949 Type implicitArgType(Type argType) { |
|
950 argType = types.erasure(argType); |
|
951 if (argType.tag == BOT) |
|
952 // nulls type as the marker type Null (which has no instances) |
|
953 // TO DO: figure out how to access java.lang.Null safely, else throw nice error |
|
954 //argType = types.boxedClass(syms.botType).type; |
|
955 argType = types.boxedClass(syms.voidType).type; // REMOVE |
|
956 return argType; |
|
957 } |
|
958 |
884 /** Load toplevel or member class with given fully qualified name and |
959 /** Load toplevel or member class with given fully qualified name and |
885 * verify that it is accessible. |
960 * verify that it is accessible. |
886 * @param env The current environment. |
961 * @param env The current environment. |
887 * @param name The fully qualified name of the class to be loaded. |
962 * @param name The fully qualified name of the class to be loaded. |
888 */ |
963 */ |
1262 sym = findMethod(env, site, name, argtypes, typeargtypes, |
1337 sym = findMethod(env, site, name, argtypes, typeargtypes, |
1263 steps.head.isBoxingRequired(), |
1338 steps.head.isBoxingRequired(), |
1264 env.info.varArgs = steps.head.isVarargsRequired(), false); |
1339 env.info.varArgs = steps.head.isVarargsRequired(), false); |
1265 methodResolutionCache.put(steps.head, sym); |
1340 methodResolutionCache.put(steps.head, sym); |
1266 steps = steps.tail; |
1341 steps = steps.tail; |
|
1342 } |
|
1343 if (sym.kind >= AMBIGUOUS && |
|
1344 allowInvokedynamic && |
|
1345 (site == syms.invokeDynamicType || |
|
1346 site == syms.methodHandleType && name == names.invoke)) { |
|
1347 // lookup failed; supply an exactly-typed implicit method |
|
1348 sym = findImplicitMethod(env, site, name, argtypes, typeargtypes); |
|
1349 env.info.varArgs = false; |
1267 } |
1350 } |
1268 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error |
1351 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error |
1269 MethodResolutionPhase errPhase = |
1352 MethodResolutionPhase errPhase = |
1270 firstErroneousResolutionPhase(); |
1353 firstErroneousResolutionPhase(); |
1271 sym = access(methodResolutionCache.get(errPhase), |
1354 sym = access(methodResolutionCache.get(errPhase), |