langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
changeset 5736 ee0850472ca1
parent 5321 c8efe769cb3b
child 5738 c24b113fe4ac
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 17:11:12 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sat May 01 15:05:39 2010 -0700
@@ -67,7 +67,7 @@
     JCDiagnostic.Factory diags;
     public final boolean boxingEnabled; // = source.allowBoxing();
     public final boolean varargsEnabled; // = source.allowVarargs();
-    public final boolean allowInvokedynamic; // = options.get("invokedynamic");
+    public final boolean allowPolymorphicSignature;
     private final boolean debugResolve;
 
     public static Resolve instance(Context context) {
@@ -105,7 +105,7 @@
         varargsEnabled = source.allowVarargs();
         Options options = Options.instance(context);
         debugResolve = options.get("debugresolve") != null;
-        allowInvokedynamic = options.get("invokedynamic") != null;
+        allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
     }
 
     /** error symbols, which are returned when resolution fails
@@ -301,6 +301,7 @@
                         boolean useVarargs,
                         Warner warn)
         throws Infer.InferenceException {
+        assert ((m.flags() & (POLYMORPHIC_SIGNATURE|HYPOTHETICAL)) != POLYMORPHIC_SIGNATURE);
         if (useVarargs && (m.flags() & VARARGS) == 0) return null;
         Type mt = types.memberType(site, m);
 
@@ -575,6 +576,14 @@
         if (sym.kind == ERR) return bestSoFar;
         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
         assert sym.kind < AMBIGUOUS;
+        if ((sym.flags() & POLYMORPHIC_SIGNATURE) != 0 && allowPolymorphicSignature) {
+            assert(site.tag == CLASS);
+            // Never match a MethodHandle.invoke directly.
+            if (useVarargs | allowBoxing | operator)
+                return bestSoFar;
+            // Supply an exactly-typed implicit method instead.
+            sym = findPolymorphicSignatureInstance(env, sym.owner.type, sym.name, (MethodSymbol) sym, argtypes, typeargtypes);
+        }
         try {
             if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
                                allowBoxing, useVarargs, Warner.noWarnings) == null) {
@@ -745,6 +754,14 @@
                       boolean allowBoxing,
                       boolean useVarargs,
                       boolean operator) {
+        Symbol bestSoFar = methodNotFound;
+        if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 &&
+            allowPolymorphicSignature &&
+            site.tag == CLASS &&
+            !(useVarargs | allowBoxing | operator)) {
+            // supply an exactly-typed implicit method in java.dyn.InvokeDynamic
+            bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes);
+        }
         return findMethod(env,
                           site,
                           name,
@@ -752,7 +769,7 @@
                           typeargtypes,
                           site.tsym.type,
                           true,
-                          methodNotFound,
+                          bestSoFar,
                           allowBoxing,
                           useVarargs,
                           operator);
@@ -896,13 +913,14 @@
      *  @param argtypes  The method's value arguments.
      *  @param typeargtypes The method's type arguments
      */
-    Symbol findImplicitMethod(Env<AttrContext> env,
-                              Type site,
-                              Name name,
-                              List<Type> argtypes,
-                              List<Type> typeargtypes) {
-        assert allowInvokedynamic;
-        assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke);
+    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
+                                            Type site,
+                                            Name name,
+                                            MethodSymbol spMethod,  // sig. poly. method or null if none
+                                            List<Type> argtypes,
+                                            List<Type> typeargtypes) {
+        assert allowPolymorphicSignature;
+        //assert site == syms.invokeDynamicType || site == syms.methodHandleType : site;
         ClassSymbol c = (ClassSymbol) site.tsym;
         Scope implicit = c.members().next;
         if (implicit == null) {
@@ -917,12 +935,22 @@
                 return methodNotFound;
         }
         List<Type> paramtypes = Type.map(argtypes, implicitArgType);
+        long flags;
+        List<Type> exType;
+        if (spMethod != null) {
+            exType = spMethod.getThrownTypes();
+            flags = spMethod.flags() & AccessFlags;
+        } else {
+            // make it throw all exceptions
+            //assert(site == syms.invokeDynamicType);
+            exType = List.of(syms.throwableType);
+            flags = PUBLIC | STATIC;
+        }
         MethodType mtype = new MethodType(paramtypes,
                                           restype,
-                                          List.<Type>nil(),
+                                          exType,
                                           syms.methodClass);
-        int flags = PUBLIC | ABSTRACT;
-        if (site == syms.invokeDynamicType)  flags |= STATIC;
+        flags |= ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE;
         Symbol m = null;
         for (Scope.Entry e = implicit.lookup(name);
              e.scope != null;
@@ -1337,14 +1365,6 @@
             methodResolutionCache.put(steps.head, sym);
             steps = steps.tail;
         }
-        if (sym.kind >= AMBIGUOUS &&
-            allowInvokedynamic &&
-            (site == syms.invokeDynamicType ||
-             site == syms.methodHandleType && name == names.invoke)) {
-            // lookup failed; supply an exactly-typed implicit method
-            sym = findImplicitMethod(env, site, name, argtypes, typeargtypes);
-            env.info.varArgs = false;
-        }
         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
             MethodResolutionPhase errPhase =
                     firstErroneousResolutionPhase();