6979327: method handle invocation should use casts instead of type parameters to specify return type
authormcimadamore
Tue, 07 Sep 2010 17:32:27 +0100
changeset 6592 dc56420a69bc
parent 6591 a953c8c6b85e
child 6593 4d13b5b812ef
6979327: method handle invocation should use casts instead of type parameters to specify return type Summary: infer return type for polymorphic signature calls according to updated JSR 292 draft Reviewed-by: jjg Contributed-by: john.r.rose@oracle.com
langtools/src/share/classes/com/sun/tools/javac/code/Source.java
langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
langtools/src/share/classes/com/sun/tools/javac/main/Main.java
langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/share/classes/com/sun/tools/javac/util/Names.java
langtools/test/tools/javac/diags/examples.not-yet.txt
langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java
langtools/test/tools/javac/diags/examples/UnsupportedExoticID.java
langtools/test/tools/javac/meth/InvokeDyn.java
langtools/test/tools/javac/meth/InvokeDynTrans.java
langtools/test/tools/javac/meth/InvokeDynTrans.out
langtools/test/tools/javac/meth/InvokeMH.java
langtools/test/tools/javac/meth/InvokeMHTrans.java
langtools/test/tools/javac/meth/InvokeMHTrans.out
langtools/test/tools/javac/meth/MakeNegTests.sh
langtools/test/tools/javac/quid/MakeNegTests.sh
langtools/test/tools/javac/quid/QuotedIdent.java
langtools/test/tools/javac/quid/QuotedIdent2.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Tue Sep 07 17:32:27 2010 +0100
@@ -171,11 +171,10 @@
     public boolean allowUnderscoresInLiterals() {
         return compareTo(JDK1_7) >= 0;
     }
-    public boolean allowStringsInSwitch() {
+    public boolean allowExoticIdentifiers() {
         return compareTo(JDK1_7) >= 0;
     }
-    // JSR 292: recognize @PolymorphicSignature on java/dyn names
-    public boolean allowPolymorphicSignature() {
+    public boolean allowStringsInSwitch() {
         return compareTo(JDK1_7) >= 0;
     }
     public static SourceVersion toSourceVersion(Source source) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Sep 07 17:32:27 2010 +0100
@@ -214,6 +214,16 @@
         return (flags() & INTERFACE) != 0;
     }
 
+    /** Recognize if this symbol was marked @PolymorphicSignature in the source. */
+    public boolean isPolymorphicSignatureGeneric() {
+        return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == POLYMORPHIC_SIGNATURE;
+    }
+
+    /** Recognize if this symbol was split from a @PolymorphicSignature symbol in the source. */
+    public boolean isPolymorphicSignatureInstance() {
+        return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == (POLYMORPHIC_SIGNATURE | HYPOTHETICAL);
+    }
+
     /** Is this symbol declared (directly or indirectly) local
      *  to a method or variable initializer?
      *  Also includes fields of inner classes which are in
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1185,7 +1185,10 @@
     }
 
     public void visitExec(JCExpressionStatement tree) {
-        attribExpr(tree.expr, env);
+        //a fresh environment is required for 292 inference to work properly ---
+        //see Infer.instantiatePolymorphicSignatureInstance()
+        Env<AttrContext> localEnv = env.dup(tree);
+        attribExpr(tree.expr, localEnv);
         result = null;
     }
 
@@ -1443,23 +1446,19 @@
                               restype.tsym);
             }
 
-            // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
-            // has type <T>, and T can be a primitive type.
-            if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
-              JCFieldAccess mfield = (JCFieldAccess) tree.meth;
-              if ((mfield.selected.type.tsym != null &&
-                   (mfield.selected.type.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0)
-                  ||
-                  (mfield.sym != null &&
-                   (mfield.sym.flags() & POLYMORPHIC_SIGNATURE) != 0)) {
-                  assert types.isSameType(restype, typeargtypes.head) : mtype;
-                  assert mfield.selected.type == syms.methodHandleType
-                      || mfield.selected.type == syms.invokeDynamicType;
-                  typeargtypesNonRefOK = true;
-              }
+            // Special case logic for JSR 292 types.
+            if (rs.allowTransitionalJSR292 &&
+                    tree.meth.getTag() == JCTree.SELECT &&
+                    !typeargtypes.isEmpty()) {
+                JCFieldAccess mfield = (JCFieldAccess) tree.meth;
+                // MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
+                // has type <T>, and T can be a primitive type.
+                if (mfield.sym != null &&
+                        mfield.sym.isPolymorphicSignatureInstance())
+                    typeargtypesNonRefOK = true;
             }
 
-            if (!typeargtypesNonRefOK) {
+            if (!(rs.allowTransitionalJSR292 && typeargtypesNonRefOK)) {
                 chk.checkRefTypes(tree.typeargs, typeargtypes);
             }
 
@@ -2023,7 +2022,10 @@
     public void visitTypeCast(JCTypeCast tree) {
         Type clazztype = attribType(tree.clazz, env);
         chk.validate(tree.clazz, env, false);
-        Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
+        //a fresh environment is required for 292 inference to work properly ---
+        //see Infer.instantiatePolymorphicSignatureInstance()
+        Env<AttrContext> localEnv = env.dup(tree);
+        Type exprtype = attribExpr(tree.expr, localEnv, Infer.anyPoly);
         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
         if (exprtype.constValue() != null)
             owntype = cfolder.coerce(exprtype, owntype);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Sep 07 17:32:27 2010 +0100
@@ -25,6 +25,8 @@
 
 package com.sun.tools.javac.comp;
 
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.code.*;
@@ -543,4 +545,56 @@
                                 args.head, bounds);
         }
     }
+
+    /**
+     * Compute a synthetic method type corresponding to the requested polymorphic
+     * method signature. If no explicit return type is supplied, a provisional
+     * return type is computed (just Object in case of non-transitional 292)
+     */
+    Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site,
+                                            Name name,
+                                            MethodSymbol spMethod,  // sig. poly. method or null if none
+                                            List<Type> argtypes,
+                                            List<Type> typeargtypes) {
+        final Type restype;
+        if (rs.allowTransitionalJSR292 && typeargtypes.nonEmpty()) {
+            restype = typeargtypes.head;
+        } else {
+            //The return type for a polymorphic signature call is computed from
+            //the enclosing tree E, as follows: if E is a cast, then use the
+            //target type of the cast expression as a return type; if E is an
+            //expression statement, the return type is 'void' - otherwise the
+            //return type is simply 'Object'.
+            switch (env.outer.tree.getTag()) {
+                case JCTree.TYPECAST:
+                    restype = ((JCTypeCast)env.outer.tree).clazz.type; break;
+                case JCTree.EXEC:
+                    restype = syms.voidType; break;
+                default:
+                    restype = syms.objectType;
+            }
+        }
+
+        List<Type> paramtypes = Type.map(argtypes, implicitArgType);
+        List<Type> exType = spMethod != null ?
+            spMethod.getThrownTypes() :
+            List.of(syms.throwableType); // make it throw all exceptions
+
+        MethodType mtype = new MethodType(paramtypes,
+                                          restype,
+                                          exType,
+                                          syms.methodClass);
+        return mtype;
+    }
+    //where
+        Mapping implicitArgType = new Mapping ("implicitArgType") {
+                public Type apply(Type t) {
+                    t = types.erasure(t);
+                    if (t.tag == BOT)
+                        // nulls type as the marker type Null (which has no instances)
+                        // infer as java.lang.Void for now
+                        t = types.boxedClass(syms.voidType).type;
+                    return t;
+                }
+        };
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Sep 07 17:32:27 2010 +0100
@@ -769,9 +769,17 @@
                 && types.isSameType(c.type, syms.deprecatedType))
                 s.flags_field |= Flags.DEPRECATED;
             // Internally to java.dyn, a @PolymorphicSignature annotation
-            // translates to a classfile attribute.
-            if (!c.type.isErroneous()
-                && types.isSameType(c.type, syms.polymorphicSignatureType)) {
+            // acts like a classfile attribute.
+            if (!c.type.isErroneous() &&
+                    types.isSameType(c.type, syms.polymorphicSignatureType)) {
+                if (!target.hasMethodHandles()) {
+                    // Somebody is compiling JDK7 source code to a JDK6 target.
+                    // Make it a strict warning, since it is unlikely but important.
+                    log.strictWarning(env.tree.pos(),
+                            "wrong.target.for.polymorphic.signature.definition",
+                            target.name);
+                }
+                // Pull the flag through for better diagnostics, even on a bad target.
                 s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
             }
             if (!annotated.add(a.type.tsym))
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 07 17:32:27 2010 +0100
@@ -69,9 +69,13 @@
     JCDiagnostic.Factory diags;
     public final boolean boxingEnabled; // = source.allowBoxing();
     public final boolean varargsEnabled; // = source.allowVarargs();
-    public final boolean allowPolymorphicSignature;
+    public final boolean allowMethodHandles;
+    public final boolean allowInvokeDynamic;
+    public final boolean allowTransitionalJSR292;
     private final boolean debugResolve;
 
+    Scope polymorphicSignatureScope;
+
     public static Resolve instance(Context context) {
         Resolve instance = context.get(resolveKey);
         if (instance == null)
@@ -107,7 +111,14 @@
         varargsEnabled = source.allowVarargs();
         Options options = Options.instance(context);
         debugResolve = options.get("debugresolve") != null;
-        allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
+        allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null;
+        Target target = Target.instance(context);
+        allowMethodHandles = allowTransitionalJSR292 ||
+                target.hasMethodHandles();
+        allowInvokeDynamic = (allowTransitionalJSR292 ||
+                target.hasInvokedynamic()) &&
+                options.get("invokedynamic") != null;
+        polymorphicSignatureScope = new Scope(syms.noSymbol);
     }
 
     /** error symbols, which are returned when resolution fails
@@ -246,7 +257,8 @@
     /* `sym' is accessible only if not overridden by
      * another symbol which is a member of `site'
      * (because, if it is overridden, `sym' is not strictly
-     * speaking a member of `site'.)
+     * speaking a member of `site'). A polymorphic signature method
+     * cannot be overridden (e.g. MH.invokeExact(Object[])).
      */
     private boolean notOverriddenIn(Type site, Symbol sym) {
         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
@@ -254,6 +266,7 @@
         else {
             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
             return (s2 == null || s2 == sym ||
+                    s2.isPolymorphicSignatureGeneric() ||
                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
         }
     }
@@ -303,7 +316,8 @@
                         boolean useVarargs,
                         Warner warn)
         throws Infer.InferenceException {
-        assert ((m.flags() & (POLYMORPHIC_SIGNATURE|HYPOTHETICAL)) != POLYMORPHIC_SIGNATURE);
+        boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) ||
+                                        isTransitionalDynamicCallSite(site, m);
         if (useVarargs && (m.flags() & VARARGS) == 0) return null;
         Type mt = types.memberType(site, m);
 
@@ -311,7 +325,10 @@
         // need to inferred.
         List<Type> tvars = env.info.tvars;
         if (typeargtypes == null) typeargtypes = List.nil();
-        if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
+        if (allowTransitionalJSR292 && polymorphicSignature && typeargtypes.nonEmpty()) {
+            //transitional 292 call sites might have wrong number of targs
+        }
+        else if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
             // This is not a polymorphic method, but typeargs are supplied
             // which is fine, see JLS3 15.12.2.1
         } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
@@ -339,7 +356,8 @@
         }
 
         // find out whether we need to go the slow route via infer
-        boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;
+        boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
+                polymorphicSignature;
         for (List<Type> l = argtypes;
              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
              l = l.tail) {
@@ -347,8 +365,9 @@
         }
 
         if (instNeeded)
-            return
-            infer.instantiateMethod(env,
+            return polymorphicSignature ?
+                infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes, typeargtypes) :
+                infer.instantiateMethod(env,
                                     tvars,
                                     (MethodType)mt,
                                     m,
@@ -363,6 +382,14 @@
             : null;
     }
 
+    boolean isTransitionalDynamicCallSite(Type site, Symbol sym) {
+        return allowTransitionalJSR292 &&  // old logic that doesn't use annotations
+                !sym.isPolymorphicSignatureInstance() &&
+                ((allowMethodHandles && site == syms.methodHandleType && // invokeExact, invokeGeneric, invoke
+                    (sym.name == names.invoke && sym.isPolymorphicSignatureGeneric())) ||
+                (site == syms.invokeDynamicType && allowInvokeDynamic)); // InvokeDynamic.XYZ
+    }
+
     /** Same but returns null instead throwing a NoInstanceException
      */
     Type instantiate(Env<AttrContext> env,
@@ -580,14 +607,6 @@
         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) {
@@ -759,13 +778,6 @@
                       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,
@@ -907,90 +919,6 @@
         return bestSoFar;
     }
 
-    /** Find or create an implicit method of exactly the given type (after erasure).
-     *  Searches in a side table, not the main scope of the site.
-     *  This emulates the lookup process required by JSR 292 in JVM.
-     *  @param env       The current environment.
-     *  @param site      The original type from where the selection
-     *                   takes place.
-     *  @param name      The method's name.
-     *  @param argtypes  The method's value arguments.
-     *  @param typeargtypes The method's type arguments
-     */
-    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) {
-            c.members().next = implicit = new Scope(c);
-        }
-        Type restype;
-        if (typeargtypes.isEmpty()) {
-            restype = syms.objectType;
-        } else {
-            restype = typeargtypes.head;
-            if (!typeargtypes.tail.isEmpty())
-                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,
-                                          exType,
-                                          syms.methodClass);
-        flags |= ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE;
-        Symbol m = null;
-        for (Scope.Entry e = implicit.lookup(name);
-             e.scope != null;
-             e = e.next()) {
-            Symbol sym = e.sym;
-            assert sym.kind == MTH;
-            if (types.isSameType(mtype, sym.type)
-                && (sym.flags() & STATIC) == (flags & STATIC)) {
-                m = sym;
-                break;
-            }
-        }
-        if (m == null) {
-            // create the desired method
-            m = new MethodSymbol(flags, name, mtype, c);
-            implicit.enter(m);
-        }
-        assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
-                                   false, false, Warner.noWarnings);
-        assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
-        return m;
-    }
-    //where
-        Mapping implicitArgType = new Mapping ("implicitArgType") {
-                public Type apply(Type t) { return implicitArgType(t); }
-            };
-        Type implicitArgType(Type argType) {
-            argType = types.erasure(argType);
-            if (argType.tag == BOT)
-                // nulls type as the marker type Null (which has no instances)
-                // TO DO: figure out how to access java.lang.Null safely, else throw nice error
-                //argType = types.boxedClass(syms.botType).type;
-                argType = types.boxedClass(syms.voidType).type;  // REMOVE
-            return argType;
-        }
-
     /** Load toplevel or member class with given fully qualified name and
      *  verify that it is accessible.
      *  @param env       The current environment.
@@ -1369,16 +1297,77 @@
             methodResolutionCache.put(steps.head, sym);
             steps = steps.tail;
         }
-        if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
-            MethodResolutionPhase errPhase =
-                    firstErroneousResolutionPhase();
-            sym = access(methodResolutionCache.get(errPhase),
-                    pos, site, name, true, argtypes, typeargtypes);
-            env.info.varArgs = errPhase.isVarargsRequired;
+        if (sym.kind >= AMBIGUOUS) {
+            if (site.tsym.isPolymorphicSignatureGeneric() ||
+                    isTransitionalDynamicCallSite(site, sym)) {
+                //polymorphic receiver - synthesize new method symbol
+                env.info.varArgs = false;
+                sym = findPolymorphicSignatureInstance(env,
+                        site, name, null, argtypes, typeargtypes);
+            }
+            else {
+                //if nothing is found return the 'first' error
+                MethodResolutionPhase errPhase =
+                        firstErroneousResolutionPhase();
+                sym = access(methodResolutionCache.get(errPhase),
+                        pos, site, name, true, argtypes, typeargtypes);
+                env.info.varArgs = errPhase.isVarargsRequired;
+            }
+        } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
+            //non-instantiated polymorphic signature - synthesize new method symbol
+            env.info.varArgs = false;
+            sym = findPolymorphicSignatureInstance(env,
+                    site, name, (MethodSymbol)sym, argtypes, typeargtypes);
         }
         return sym;
     }
 
+    /** Find or create an implicit method of exactly the given type (after erasure).
+     *  Searches in a side table, not the main scope of the site.
+     *  This emulates the lookup process required by JSR 292 in JVM.
+     *  @param env       Attribution environment
+     *  @param site      The original type from where the selection takes place.
+     *  @param name      The method's name.
+     *  @param spMethod  A template for the implicit method, or null.
+     *  @param argtypes  The required argument types.
+     *  @param typeargtypes  The required type arguments.
+     */
+    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
+                                            Name name,
+                                            MethodSymbol spMethod,  // sig. poly. method or null if none
+                                            List<Type> argtypes,
+                                            List<Type> typeargtypes) {
+        if (typeargtypes.nonEmpty() && (site.tsym.isPolymorphicSignatureGeneric() ||
+                (spMethod != null && spMethod.isPolymorphicSignatureGeneric()))) {
+            log.warning(env.tree.pos(), "type.parameter.on.polymorphic.signature");
+        }
+
+        Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
+                site, name, spMethod, argtypes, typeargtypes);
+        long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
+                    (spMethod != null ?
+                        spMethod.flags() & Flags.AccessFlags :
+                        Flags.PUBLIC | Flags.STATIC);
+        Symbol m = null;
+        for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
+             e.scope != null;
+             e = e.next()) {
+            Symbol sym = e.sym;
+            if (types.isSameType(mtype, sym.type) &&
+                (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
+                types.isSameType(sym.owner.type, site)) {
+               m = sym;
+               break;
+            }
+        }
+        if (m == null) {
+            // create the desired method
+            m = new MethodSymbol(flags, name, mtype, site.tsym);
+            polymorphicSignatureScope.enter(m);
+        }
+        return m;
+    }
+
     /** Resolve a qualified method identifier, throw a fatal error if not
      *  found.
      *  @param pos       The position to use for error reporting.
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1098,12 +1098,6 @@
                 }
             },
 
-            new AttributeReader(names.PolymorphicSignature, V45_3/*S.B.V51*/, CLASS_OR_MEMBER_ATTRIBUTE) {
-                void read(Symbol sym, int attrLen) {
-                    sym.flags_field |= POLYMORPHIC_SIGNATURE;
-                }
-            },
-
 
             // The following attributes for a Code attribute are not currently handled
             // StackMapTable
@@ -1289,6 +1283,9 @@
                     sym.flags_field |= PROPRIETARY;
                 else
                     proxies.append(proxy);
+                if (majorVersion >= V51.major && proxy.type.tsym == syms.polymorphicSignatureType.tsym) {
+                    sym.flags_field |= POLYMORPHIC_SIGNATURE;
+                }
             }
             annotate.later(new AnnotationCompleter(sym, proxies.toList()));
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 07 17:32:27 2010 +0100
@@ -652,13 +652,6 @@
             endAttr(alenIdx);
             acount++;
         }
-        if ((flags & POLYMORPHIC_SIGNATURE) != 0) {
-            if (target.majorVersion < 51)
-                throw new AssertionError("PolymorphicSignature attributes in java/dyn must be written with -target 7 (required major version is 51, current is"+target.majorVersion+")");
-            int alenIdx = writeAttr(names.PolymorphicSignature);
-            endAttr(alenIdx);
-            acount++;
-        }
         return acount;
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Tue Sep 07 17:32:27 2010 +0100
@@ -259,6 +259,14 @@
         return compareTo(JDK1_7) >= 0;
     }
 
+    /** Does the VM support polymorphic method handle invocation?
+     *  Affects the linkage information output to the classfile.
+     *  An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.
+     */
+    public boolean hasMethodHandles() {
+        return hasInvokedynamic();
+    }
+
     /** Although we may not have support for class literals, should we
      *  avoid initializing the class that the literal refers to?
      *  See 4468823
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Tue Sep 07 17:32:27 2010 +0100
@@ -282,6 +282,13 @@
             }
         }
 
+        // phase this out with JSR 292 PFD
+        if ("no".equals(options.get("allowTransitionalJSR292"))) {
+            options.put("allowTransitionalJSR292", null);
+        } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) {
+            options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
+        }
+
         // handle this here so it works even if no other options given
         String showClass = options.get("showClass");
         if (showClass != null) {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Tue Sep 07 17:32:27 2010 +0100
@@ -108,6 +108,10 @@
      */
     private boolean allowUnderscoresInLiterals;
 
+    /** Allow exotic identifiers.
+     */
+    private boolean allowExoticIdentifiers;
+
     /** The source language setting.
      */
     private Source source;
@@ -181,6 +185,7 @@
         allowBinaryLiterals = source.allowBinaryLiterals();
         allowHexFloats = source.allowHexFloats();
         allowUnderscoresInLiterals = source.allowBinaryLiterals();
+        allowExoticIdentifiers = source.allowExoticIdentifiers();  // for invokedynamic
     }
 
     private static final boolean hexFloatsWork = hexFloatsWork();
@@ -1010,6 +1015,10 @@
                 case '#':
                     scanChar();
                     if (ch == '\"') {
+                        if (!allowExoticIdentifiers) {
+                            lexError("unsupported.exotic.id", source.name);
+                            allowExoticIdentifiers = true;
+                        }
                         scanChar();
                         if (ch == '\"')
                             lexError(pos, "empty.bytecode.ident");
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 07 17:32:27 2010 +0100
@@ -128,6 +128,11 @@
 compiler.err.no.superclass=\
     {0} has no superclass
 
+compiler.warn.type.parameter.on.polymorphic.signature=\
+    change obsolete notation for MethodHandle invocations from x.<T>invoke(y) to (T)x.invoke(y)
+compiler.warn.wrong.target.for.polymorphic.signature.definition=\
+    MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
+
 compiler.err.concrete.inheritance.conflict=\
     methods {0} from {1} and {2} from {3} are inherited with the same signature
 
@@ -1242,6 +1247,10 @@
     underscores in literals are not supported in -source {0}\n\
 (use -source 7 or higher to enable underscores in literals)
 
+compiler.err.unsupported.exotic.id=\
+    exotic identifiers #"___" are not supported in -source {0}\n\
+(use -source 7 or higher to enable exotic identifiers)
+
 compiler.err.automatic.resource.management.not.supported.in.source=\
     automatic resource management is not supported in -source {0}\n\
 (use -source 7 or higher to enable automatic resource management)
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Tue Sep 07 17:32:27 2010 +0100
@@ -103,7 +103,6 @@
     public final Name RuntimeInvisibleTypeAnnotations;
     public final Name RuntimeVisibleParameterAnnotations;
     public final Name RuntimeInvisibleParameterAnnotations;
-    public final Name PolymorphicSignature;
     public final Name Value;
     public final Name EnclosingMethod;
     public final Name desiredAssertionStatus;
@@ -116,6 +115,7 @@
     public final Name value;
     public final Name getMessage;
     public final Name getClass;
+    public final Name invoke;  //allowTransitionalJSR292 only
     public final Name TYPE;
     public final Name TYPE_USE;
     public final Name TYPE_PARAMETER;
@@ -215,7 +215,6 @@
         RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
         RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
         RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
-        PolymorphicSignature = fromString("PolymorphicSignature");
         Value = fromString("Value");
         EnclosingMethod = fromString("EnclosingMethod");
 
@@ -230,6 +229,7 @@
         value = fromString("value");
         getMessage = fromString("getMessage");
         getClass = fromString("getClass");
+        invoke = fromString("invoke");  //allowTransitionalJSR292 only
 
         TYPE = fromString("TYPE");
         TYPE_USE = fromString("TYPE_USE");
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Tue Sep 07 17:32:27 2010 +0100
@@ -114,3 +114,4 @@
 compiler.warn.unchecked.assign                          # DEAD, replaced by compiler.misc.unchecked.assign
 compiler.warn.unchecked.cast.to.type                    # DEAD, replaced by compiler.misc.unchecked.cast.to.type
 compiler.warn.unexpected.archive.file                   # Paths: zip file with unknown extn
+compiler.warn.wrong.target.for.polymorphic.signature.definition     # Transitional 292
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypeParameterOnPolymorphicSignature.java	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.type.parameter.on.polymorphic.signature
+// key: compiler.err.unreported.exception.need.to.catch.or.throw
+
+import java.dyn.InvokeDynamic;
+
+class TypeParameterOnPolymorphicSignature {
+    { InvokeDynamic.<void>call("",123); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnsupportedExoticID.java	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.unsupported.exotic.id
+// options: -source 6
+
+class UnsupportedExoticID {
+    void m() {
+        Object #"Hello!" = null;
+    }
+}
--- a/langtools/test/tools/javac/meth/InvokeDyn.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/test/tools/javac/meth/InvokeDyn.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,12 @@
 
 /*
  * @test
- * @bug 6754038
+ * @bug 6754038 6979327
  * @summary Generate call sites for method handle
  * @author jrose
  *
  * @library ..
- * @compile -source 7 -target 7 InvokeDyn.java
+ * @compile -source 7 -target 7 -XDinvokedynamic -XDallowTransitionalJSR292=no InvokeDyn.java
  */
 //No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
 
@@ -44,16 +44,21 @@
 
 package meth;
 
-import java.dyn.InvokeDynamic;
+import java.dyn.*;
 
 public class InvokeDyn {
+    class CS extends CallSite {
+        CS(Object x, Object y, Object z) { throw new RuntimeException(); }
+    }
+    //@BootstrapMethod(CS.class)  //note: requires 6964498
     void test() throws Throwable {
         Object x = "hello";
-        InvokeDynamic.greet(x, "world", 123);
-        InvokeDynamic.greet(x, "mundus", 456);
-        InvokeDynamic.greet(x, "kosmos", 789);
-        InvokeDynamic.<String>cogitate(10.11121, 3.14);
-        InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
-        InvokeDynamic.<int>invoke("goodbye");
+        Object ojunk; int ijunk;
+        ojunk = InvokeDynamic.greet(x, "world", 123);
+        ojunk = InvokeDynamic.greet(x, "mundus", 456);
+        ojunk = InvokeDynamic.greet(x, "kosmos", 789);
+        ojunk = (String) InvokeDynamic.cogitate(10.11121, 3.14);
+        InvokeDynamic.#"yow: what I mean to say is, please treat this one specially"(null);
+        ijunk = (int) InvokeDynamic.invoke("goodbye");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/InvokeDynTrans.java	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008-2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6754038 6979327
+ * @summary Generate call sites for method handle
+ * @author jrose
+ *
+ * @library ..
+ * @compile/fail/ref=InvokeDynTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeDynTrans.java
+ */
+//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
+
+/*
+ * Standalone testing:
+ * <code>
+ * $ cd $MY_REPO_DIR/langtools
+ * $ (cd make; make)
+ * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java
+ * $ javap -c -classpath dist meth.InvokeDyn
+ * </code>
+ */
+
+package meth;
+
+import java.dyn.InvokeDynamic;
+
+public class InvokeDynTrans {
+    void test() throws Throwable {
+        Object x = "hello";
+        InvokeDynamic.greet(x, "world", 123);
+        InvokeDynamic.greet(x, "mundus", 456);
+        InvokeDynamic.greet(x, "kosmos", 789);
+        InvokeDynamic.<String>cogitate(10.11121, 3.14);
+        InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
+        InvokeDynamic.<int>invoke("goodbye");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/InvokeDynTrans.out	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,6 @@
+InvokeDynTrans.java:55:39: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeDynTrans.java:56:91: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeDynTrans.java:57:34: compiler.warn.type.parameter.on.polymorphic.signature
+- compiler.err.warnings.and.werror
+1 error
+3 warnings
--- a/langtools/test/tools/javac/meth/InvokeMH.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/test/tools/javac/meth/InvokeMH.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,11 @@
 
 /*
  * @test
- * @bug 6754038
+ * @bug 6754038 6979327
  * @summary Generate call sites for method handle
  * @author jrose
  *
- * @compile -source 7 -target 7 InvokeMH.java
+ * @compile -source 7 -target 7 -XDallowTransitionalJSR292=no InvokeMH.java
  */
 
 /*
@@ -57,20 +57,17 @@
         Object k = "kosmos";
         mh_SiO.invokeExact((String)k, 789);
         o = mh_SiO.invokeExact((String)null, 000);
-        o = mh_SiO.<Object>invokeExact("arda", -123);
+        o = (Object) mh_SiO.invokeExact("arda", -123);
 
         // sig = ()String
-        s = mh_vS.<String>invokeExact();
+        s = (String) mh_vS.invokeExact();
 
         // sig = ()int
-        i = mh_vi.<int>invokeExact();
-        o = mh_vi.<int>invokeExact();
-        //s = mh_vi.<int>invokeExact(); //BAD
-        mh_vi.<int>invokeExact();
+        i = (int) mh_vi.invokeExact();
+        o = (int) mh_vi.invokeExact();
 
         // sig = ()void
-        //o = mh_vv.<void>invokeExact(); //BAD
-        mh_vv.<void>invokeExact();
+        mh_vv.invokeExact();
     }
 
     void testGen(MethodHandle mh_SiO,
@@ -80,24 +77,23 @@
         Object o; String s; int i;  // for return type testing
 
         // next five must have sig = (*,*)*
-        mh_SiO.invokeGeneric((Object)"world", (Object)123);
-        mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
+        o = mh_SiO.invokeGeneric((Object)"world", (Object)123);
+        mh_SiO.invokeGeneric((Object)"mundus", (Object)456);
         Object k = "kosmos";
-        mh_SiO.invokeGeneric(k, 789);
+        o = mh_SiO.invokeGeneric(k, 789);
         o = mh_SiO.invokeGeneric(null, 000);
-        o = mh_SiO.<Object>invokeGeneric("arda", -123);
+        o = mh_SiO.invokeGeneric("arda", -123);
 
         // sig = ()String
         o = mh_vS.invokeGeneric();
 
         // sig = ()int
-        i = mh_vi.<int>invokeGeneric();
-        o = mh_vi.invokeGeneric();
-        //s = mh_vi.<int>invokeGeneric(); //BAD
-        mh_vi.<void>invokeGeneric();
+        i = (int) mh_vi.invokeGeneric();
+        o = (int) mh_vi.invokeGeneric();
+        mh_vi.invokeGeneric();
 
         // sig = ()void
-        //o = mh_vv.<void>invokeGeneric(); //BAD
+        mh_vv.invokeGeneric();
         o = mh_vv.invokeGeneric();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/InvokeMHTrans.java	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,102 @@
+/* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6754038 6979327
+ * @summary Generate call sites for method handle
+ * @author jrose
+ *
+ * @compile/fail/ref=InvokeMHTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeMHTrans.java
+ */
+
+/*
+ * Standalone testing:
+ * <code>
+ * $ cd $MY_REPO_DIR/langtools
+ * $ (cd make; make)
+ * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH.java
+ * $ javap -c -classpath dist meth.InvokeMH
+ * </code>
+ */
+
+package meth;
+
+import java.dyn.MethodHandle;
+
+public class InvokeMHTrans {
+    void test(MethodHandle mh_SiO,
+              MethodHandle mh_vS,
+              MethodHandle mh_vi,
+              MethodHandle mh_vv) throws Throwable {
+        Object o; String s; int i;  // for return type testing
+
+        // next five must have sig = (String,int)Object
+        mh_SiO.invokeExact("world", 123);
+        mh_SiO.invokeExact("mundus", 456);
+        Object k = "kosmos";
+        mh_SiO.invokeExact((String)k, 789);
+        o = mh_SiO.invokeExact((String)null, 000);
+        o = mh_SiO.<Object>invokeExact("arda", -123);
+
+        // sig = ()String
+        s = mh_vS.<String>invokeExact();
+
+        // sig = ()int
+        i = mh_vi.<int>invokeExact();
+        o = mh_vi.<int>invokeExact();
+        //s = mh_vi.<int>invokeExact(); //BAD
+        mh_vi.<int>invokeExact();
+
+        // sig = ()void
+        //o = mh_vv.<void>invokeExact(); //BAD
+        mh_vv.<void>invokeExact();
+    }
+
+    void testGen(MethodHandle mh_SiO,
+                 MethodHandle mh_vS,
+                 MethodHandle mh_vi,
+                 MethodHandle mh_vv) throws Throwable {
+        Object o; String s; int i;  // for return type testing
+
+        // next five must have sig = (*,*)*
+        mh_SiO.invokeGeneric((Object)"world", (Object)123);
+        mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
+        Object k = "kosmos";
+        mh_SiO.invokeGeneric(k, 789);
+        o = mh_SiO.invokeGeneric(null, 000);
+        o = mh_SiO.<Object>invokeGeneric("arda", -123);
+
+        // sig = ()String
+        o = mh_vS.invokeGeneric();
+
+        // sig = ()int
+        i = mh_vi.<int>invokeGeneric();
+        o = mh_vi.invokeGeneric();
+        //s = mh_vi.<int>invokeGeneric(); //BAD
+        mh_vi.<void>invokeGeneric();
+
+        // sig = ()void
+        //o = mh_vv.<void>invokeGeneric(); //BAD
+        o = mh_vv.invokeGeneric();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/InvokeMHTrans.out	Tue Sep 07 17:32:27 2010 +0100
@@ -0,0 +1,13 @@
+InvokeMHTrans.java:59:39: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:62:38: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:65:35: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:66:35: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:68:31: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:72:32: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:83:35: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:87:41: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:93:37: compiler.warn.type.parameter.on.polymorphic.signature
+InvokeMHTrans.java:96:34: compiler.warn.type.parameter.on.polymorphic.signature
+- compiler.err.warnings.and.werror
+1 error
+10 warnings
--- a/langtools/test/tools/javac/meth/MakeNegTests.sh	Tue Sep 07 17:31:54 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6754038
-# @summary Verify correct rejection of strongly typed return values
-# @run shell MakeNegTests.sh
-
-default_template=InvokeMH.java
-javacflags='-source 7 -target 7'
-# the rest of this file is a generic "//BAD"-line tester
-
-: ${TESTSRC=.} ${TESTCLASSES=.}
-javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
-
-verbose=false quiet=false
-
-main() {
-  case "${@-}" in
-  *.java*)
-    for template in "$@"; do
-      expand_and_test "$template"
-    done;;
-  *) expand_and_test "${TESTSRC}/$default_template";;
-  esac
-}
-
-expand_and_test() {
-  template=$1
-  expand "$@"
-  testneg "$@"
-}
-
-expand() {
-  template=$1
-  badlines=` grep -n < "$template" '//BAD' `
-  badcount=` echo "$badlines" | wc -l `
-  [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
-  $quiet || echo "Expanding $badcount negative test cases from $template:"
-  $quiet || echo "$badlines"
-  badnums=` echo "$badlines" | sed 's/:.*//' `
-  casestem=` getcasestem "$template" `
-  tclassname=` basename "$template" .java `
-  rm -f "$casestem"*.java
-  for badnum in $badnums; do
-    casefile="$casestem"${badnum}.java
-    cclassname=` basename "$casefile" .java `
-    sed < "$template" > "$casefile" "
-      s|@compile|@compile/fail|
-      / @[a-z]/s|@|##|
-      ${badnum}s:^ *[/*]*:    :
-      s/${tclassname}/${cclassname}/g
-    "
-    $verbose && diff -u "$template" "$casefile"
-  done
-}
-
-getcasestem() {
-  echo `basename $1` | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
-}
-
-testneg() {
-  template=$1
-  for casefile in ` getcasestem "$template" `*.java; do
-    $quiet || echo -------- $javac $javacflags "$casefile"
-    $javac $javacflags "$casefile" > "$casefile".errlog 2>&1 && {
-      echo "*** Compilation unexpectedly succeeded:  $casefile"
-      exit 1
-    }
-    $quiet || echo "Compilation failed as expected"
-    $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
-    rm "$casefile".errlog
-  done
-}
-
-main "$@"
--- a/langtools/test/tools/javac/quid/MakeNegTests.sh	Tue Sep 07 17:31:54 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6746458
-# @summary Verify correct rejection of illegal quoted identifiers.
-# @run shell MakeNegTests.sh
-
-default_template=QuotedIdent.java
-# the rest of this file is a generic "//BAD"-line tester
-
-: ${TESTSRC=.} ${TESTCLASSES=.}
-javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
-
-verbose=false quiet=false
-
-main() {
-  case "${@-}" in
-  *.java*)
-    for template in "$@"; do
-      expand_and_test "$template"
-    done;;
-  *) expand_and_test "${TESTSRC}/$default_template";;
-  esac
-}
-
-expand_and_test() {
-  template=$1
-  expand "$@"
-  testneg "$@"
-}
-
-expand() {
-  template=$1
-  badlines=` grep -n < "$template" '//BAD' `
-  badcount=` echo "$badlines" | wc -l `
-  [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
-  $quiet || echo "Expanding $badcount negative test cases from $template:"
-  $quiet || echo "$badlines"
-  badnums=` echo "$badlines" | sed 's/:.*//' `
-  casestem=` getcasestem "$template" `
-  tclassname=` basename "$template" .java `
-  rm "$casestem"*.java
-  for badnum in $badnums; do
-    casefile="$casestem"${badnum}.java
-    cclassname=` basename "$casefile" .java `
-    sed < "$template" > "$casefile" "
-      s|@compile|@compile/fail|
-      / @[a-z]/s|@|##|
-      ${badnum}s:^ *[/*]*:    :
-      s/${tclassname}/${cclassname}/g
-    "
-    $verbose && diff -u "$template" "$casefile"
-  done
-}
-
-getcasestem() {
-  echo `basename $1` | sed 's/.*\///;s/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
-}
-
-testneg() {
-  template=$1
-  for casefile in ` getcasestem "$template" `*.java; do
-    $quiet || echo -------- $javac "$casefile"
-    $javac "$casefile" > "$casefile".errlog 2>&1 && {
-      echo "*** Compilation unexpectedly succeeded:  $casefile"
-      exit 1
-    }
-    $quiet || echo "Compilation failed as expected"
-    $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
-    rm "$casefile".errlog
-  done
-}
-
-main "$@"
--- a/langtools/test/tools/javac/quid/QuotedIdent.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/test/tools/javac/quid/QuotedIdent.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
  *      (The filename, directory name, or volume label syntax is incorrect)
  *
  * @library ..
+ * @compile -source 7 -target 7 -XDinvokedynamic QuotedIdent.java
  * @run main quid.QuotedIdent
  */
 
@@ -119,7 +120,7 @@
         s = #"int".class.getName();
         check(31, s, QuotedIdent.class.getName()+"$int");
 
-        Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
+        Class<?> x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
         if (x86 != #"*86".class)
             check(32, "reflected "+x86, "static "+#"*86".class);
 
--- a/langtools/test/tools/javac/quid/QuotedIdent2.java	Tue Sep 07 17:31:54 2010 +0100
+++ b/langtools/test/tools/javac/quid/QuotedIdent2.java	Tue Sep 07 17:32:27 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
  *      (The filename, directory name, or volume label syntax is incorrect)
  *
  * @library ..
+ * @compile -source 7 -target 7 -XDinvokedynamic QuotedIdent.java
  * @run main quid.QuotedIdent2
  */
 /*
@@ -72,7 +73,7 @@
         s = QuotedIdent.#"int".class.getName();
         check(31, s, QuotedIdent.class.getName()+"$int");
 
-        Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
+        Class<?> x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
         if (x86 != #"*86".class)
             check(32, "reflected "+x86, "static "+#"*86".class);