8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle

Thu, 11 Jul 2013 14:07:39 +0100

author
mcimadamore
date
Thu, 11 Jul 2013 14:07:39 +0100
changeset 1882
39ec5d8a691b
parent 1881
bdeef606be8e
child 1883
6d85acab769e
child 1907
e990e6bcecbe

8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
8020010: Move lambda bridge creation from metafactory and VM to compiler
Summary: langtools/javac component of the bridge support and MethodType vs. MethodHandle changes.
Reviewed-by: jjg, vromero, briangoetz, forax
Contributed-by: robert.field@oracle.com

src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/TransTypes.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/tree/JCTree.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/Names.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/Bridge.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/BridgeHarness.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/Bridges.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/bridge/TestMetafactoryBridges.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/lambdaExpression/LambdaTest6.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/methodReference/BridgeMethod.java file | annotate | diff | comparison | revisions
test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 11 10:13:57 2013 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 11 14:07:39 2013 +0100
     1.3 @@ -33,10 +33,15 @@
     1.4  import java.util.Set;
     1.5  import java.util.WeakHashMap;
     1.6  
     1.7 +import javax.tools.JavaFileObject;
     1.8 +
     1.9  import com.sun.tools.javac.code.Attribute.RetentionPolicy;
    1.10  import com.sun.tools.javac.code.Lint.LintCategory;
    1.11  import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
    1.12 +import com.sun.tools.javac.comp.AttrContext;
    1.13  import com.sun.tools.javac.comp.Check;
    1.14 +import com.sun.tools.javac.comp.Enter;
    1.15 +import com.sun.tools.javac.comp.Env;
    1.16  import com.sun.tools.javac.jvm.ClassReader;
    1.17  import com.sun.tools.javac.util.*;
    1.18  import static com.sun.tools.javac.code.BoundKind.*;
    1.19 @@ -83,6 +88,7 @@
    1.20      final boolean allowDefaultMethods;
    1.21      final ClassReader reader;
    1.22      final Check chk;
    1.23 +    final Enter enter;
    1.24      JCDiagnostic.Factory diags;
    1.25      List<Warner> warnStack = List.nil();
    1.26      final Name capturedName;
    1.27 @@ -109,6 +115,7 @@
    1.28          allowDefaultMethods = source.allowDefaultMethods();
    1.29          reader = ClassReader.instance(context);
    1.30          chk = Check.instance(context);
    1.31 +        enter = Enter.instance(context);
    1.32          capturedName = names.fromString("<captured wildcard>");
    1.33          messages = JavacMessages.instance(context);
    1.34          diags = JCDiagnostic.Factory.instance(context);
    1.35 @@ -605,6 +612,84 @@
    1.36              return site;
    1.37          }
    1.38      }
    1.39 +
    1.40 +    /**
    1.41 +     * Create a symbol for a class that implements a given functional interface
    1.42 +     * and overrides its functional descriptor. This routine is used for two
    1.43 +     * main purposes: (i) checking well-formedness of a functional interface;
    1.44 +     * (ii) perform functional interface bridge calculation.
    1.45 +     */
    1.46 +    public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) {
    1.47 +        Assert.check(targets.nonEmpty() && isFunctionalInterface(targets.head));
    1.48 +        Symbol descSym = findDescriptorSymbol(targets.head.tsym);
    1.49 +        Type descType = findDescriptorType(targets.head);
    1.50 +        ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
    1.51 +        csym.completer = null;
    1.52 +        csym.members_field = new Scope(csym);
    1.53 +        MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
    1.54 +        csym.members_field.enter(instDescSym);
    1.55 +        Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym);
    1.56 +        ctype.supertype_field = syms.objectType;
    1.57 +        ctype.interfaces_field = targets;
    1.58 +        csym.type = ctype;
    1.59 +        csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile;
    1.60 +        return csym;
    1.61 +    }
    1.62 +
    1.63 +    /**
    1.64 +     * Find the minimal set of methods that are overridden by the functional
    1.65 +     * descriptor in 'origin'. All returned methods are assumed to have different
    1.66 +     * erased signatures.
    1.67 +     */
    1.68 +    public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) {
    1.69 +        Assert.check(isFunctionalInterface(origin));
    1.70 +        Symbol descSym = findDescriptorSymbol(origin);
    1.71 +        CompoundScope members = membersClosure(origin.type, false);
    1.72 +        ListBuffer<Symbol> overridden = ListBuffer.lb();
    1.73 +        outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) {
    1.74 +            if (m2 == descSym) continue;
    1.75 +            else if (descSym.overrides(m2, origin, Types.this, false)) {
    1.76 +                for (Symbol m3 : overridden) {
    1.77 +                    if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
    1.78 +                            (m3.overrides(m2, origin, Types.this, false) &&
    1.79 +                            (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
    1.80 +                            (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
    1.81 +                        continue outer;
    1.82 +                    }
    1.83 +                }
    1.84 +                overridden.add(m2);
    1.85 +            }
    1.86 +        }
    1.87 +        return overridden.toList();
    1.88 +    }
    1.89 +    //where
    1.90 +        private Filter<Symbol> bridgeFilter = new Filter<Symbol>() {
    1.91 +            public boolean accepts(Symbol t) {
    1.92 +                return t.kind == Kinds.MTH &&
    1.93 +                        t.name != names.init &&
    1.94 +                        t.name != names.clinit &&
    1.95 +                        (t.flags() & SYNTHETIC) == 0;
    1.96 +            }
    1.97 +        };
    1.98 +        private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
    1.99 +            //a symbol will be completed from a classfile if (a) symbol has
   1.100 +            //an associated file object with CLASS kind and (b) the symbol has
   1.101 +            //not been entered
   1.102 +            if (origin.classfile != null &&
   1.103 +                    origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
   1.104 +                    enter.getEnv(origin) == null) {
   1.105 +                return false;
   1.106 +            }
   1.107 +            if (origin == s) {
   1.108 +                return true;
   1.109 +            }
   1.110 +            for (Type t : interfaces(origin.type)) {
   1.111 +                if (pendingBridges((ClassSymbol)t.tsym, s)) {
   1.112 +                    return true;
   1.113 +                }
   1.114 +            }
   1.115 +            return false;
   1.116 +        }
   1.117      // </editor-fold>
   1.118  
   1.119     /**
   1.120 @@ -2672,6 +2757,7 @@
   1.121                  public boolean accepts(Symbol s) {
   1.122                      return s.kind == Kinds.MTH &&
   1.123                              s.name == msym.name &&
   1.124 +                            (s.flags() & SYNTHETIC) == 0 &&
   1.125                              s.isInheritedIn(site.tsym, Types.this) &&
   1.126                              overrideEquivalent(memberType(site, s), memberType(site, msym));
   1.127                  }
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 11 10:13:57 2013 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 11 14:07:39 2013 +0100
     2.3 @@ -2334,13 +2334,12 @@
     2.4              if (pt() != Type.recoveryType) {
     2.5                  target = targetChecker.visit(target, that);
     2.6                  lambdaType = types.findDescriptorType(target);
     2.7 -                chk.checkFunctionalInterface(that, target);
     2.8              } else {
     2.9                  target = Type.recoveryType;
    2.10                  lambdaType = fallbackDescriptorType(that);
    2.11              }
    2.12  
    2.13 -            setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext());
    2.14 +            setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext);
    2.15  
    2.16              if (lambdaType.hasTag(FORALL)) {
    2.17                  //lambda expression target desc cannot be a generic method
    2.18 @@ -2682,13 +2681,12 @@
    2.19              if (pt() != Type.recoveryType) {
    2.20                  target = targetChecker.visit(pt(), that);
    2.21                  desc = types.findDescriptorType(target);
    2.22 -                chk.checkFunctionalInterface(that, target);
    2.23              } else {
    2.24                  target = Type.recoveryType;
    2.25                  desc = fallbackDescriptorType(that);
    2.26              }
    2.27  
    2.28 -            setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext());
    2.29 +            setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext);
    2.30              List<Type> argtypes = desc.getParameterTypes();
    2.31  
    2.32              Pair<Symbol, Resolve.ReferenceLookupHelper> refResult =
    2.33 @@ -2890,31 +2888,37 @@
    2.34       * might contain inference variables, we might need to register an hook in the
    2.35       * current inference context.
    2.36       */
    2.37 -    private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt,
    2.38 -            final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) {
    2.39 -        if (inferenceContext.free(descriptorType)) {
    2.40 -            inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
    2.41 +    private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr,
    2.42 +            final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) {
    2.43 +        if (checkContext.inferenceContext().free(descriptorType)) {
    2.44 +            checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
    2.45                  public void typesInferred(InferenceContext inferenceContext) {
    2.46 -                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType),
    2.47 -                            inferenceContext.asInstType(primaryTarget), inferenceContext);
    2.48 +                    setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType),
    2.49 +                            inferenceContext.asInstType(primaryTarget), checkContext);
    2.50                  }
    2.51              });
    2.52          } else {
    2.53 -            ListBuffer<TypeSymbol> targets = ListBuffer.lb();
    2.54 +            ListBuffer<Type> targets = ListBuffer.lb();
    2.55              if (pt.hasTag(CLASS)) {
    2.56                  if (pt.isCompound()) {
    2.57 -                    targets.append(primaryTarget.tsym); //this goes first
    2.58 +                    targets.append(types.removeWildcards(primaryTarget)); //this goes first
    2.59                      for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
    2.60                          if (t != primaryTarget) {
    2.61 -                            targets.append(t.tsym);
    2.62 +                            targets.append(types.removeWildcards(t));
    2.63                          }
    2.64                      }
    2.65                  } else {
    2.66 -                    targets.append(pt.tsym);
    2.67 +                    targets.append(types.removeWildcards(primaryTarget));
    2.68                  }
    2.69              }
    2.70              fExpr.targets = targets.toList();
    2.71 -            fExpr.descriptorType = descriptorType;
    2.72 +            if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
    2.73 +                    pt != Type.recoveryType) {
    2.74 +                //check that functional interface class is well-formed
    2.75 +                ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
    2.76 +                        names.empty, List.of(fExpr.targets.head), ABSTRACT);
    2.77 +                chk.checkImplementations(env.tree, csym, csym);
    2.78 +            }
    2.79          }
    2.80      }
    2.81  
    2.82 @@ -4579,9 +4583,6 @@
    2.83          @Override
    2.84          public void visitLambda(JCLambda that) {
    2.85              super.visitLambda(that);
    2.86 -            if (that.descriptorType == null) {
    2.87 -                that.descriptorType = syms.unknownType;
    2.88 -            }
    2.89              if (that.targets == null) {
    2.90                  that.targets = List.nil();
    2.91              }
    2.92 @@ -4593,9 +4594,6 @@
    2.93              if (that.sym == null) {
    2.94                  that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol);
    2.95              }
    2.96 -            if (that.descriptorType == null) {
    2.97 -                that.descriptorType = syms.unknownType;
    2.98 -            }
    2.99              if (that.targets == null) {
   2.100                  that.targets = List.nil();
   2.101              }
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 11 10:13:57 2013 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 11 14:07:39 2013 +0100
     3.3 @@ -2275,24 +2275,6 @@
     3.4          c.flags_field |= ACYCLIC;
     3.5      }
     3.6  
     3.7 -    /**
     3.8 -     * Check that functional interface methods would make sense when seen
     3.9 -     * from the perspective of the implementing class
    3.10 -     */
    3.11 -    void checkFunctionalInterface(JCTree tree, Type funcInterface) {
    3.12 -        ClassType c = new ClassType(Type.noType, List.<Type>nil(), null);
    3.13 -        ClassSymbol csym = new ClassSymbol(0, names.empty, c, syms.noSymbol);
    3.14 -        c.interfaces_field = List.of(types.removeWildcards(funcInterface));
    3.15 -        c.supertype_field = syms.objectType;
    3.16 -        c.tsym = csym;
    3.17 -        csym.members_field = new Scope(csym);
    3.18 -        Symbol descSym = types.findDescriptorSymbol(funcInterface.tsym);
    3.19 -        Type descType = types.findDescriptorType(funcInterface);
    3.20 -        csym.members_field.enter(new MethodSymbol(PUBLIC, descSym.name, descType, csym));
    3.21 -        csym.completer = null;
    3.22 -        checkImplementations(tree, csym, csym);
    3.23 -    }
    3.24 -
    3.25      /** Check that all methods which implement some
    3.26       *  method conform to the method they implement.
    3.27       *  @param tree         The class definition whose members are checked.
     4.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Jul 11 10:13:57 2013 -0700
     4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Jul 11 14:07:39 2013 +0100
     4.3 @@ -100,6 +100,9 @@
     4.4      /** Flag for alternate metafactories indicating the lambda object has multiple targets */
     4.5      public static final int FLAG_MARKERS = 1 << 1;
     4.6  
     4.7 +    /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */
     4.8 +    public static final int FLAG_BRIDGES = 1 << 2;
     4.9 +
    4.10      private class KlassInfo {
    4.11  
    4.12          /**
    4.13 @@ -321,7 +324,7 @@
    4.14          int refKind = referenceKind(sym);
    4.15  
    4.16          //convert to an invokedynamic call
    4.17 -        result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args);
    4.18 +        result = makeMetafactoryIndyCall(context, refKind, sym, indy_args);
    4.19      }
    4.20  
    4.21      private JCIdent makeThis(Type type, Symbol owner) {
    4.22 @@ -382,7 +385,7 @@
    4.23  
    4.24  
    4.25          //build a sam instance using an indy call to the meta-factory
    4.26 -        result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args);
    4.27 +        result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args);
    4.28      }
    4.29  
    4.30      /**
    4.31 @@ -606,8 +609,8 @@
    4.32                  make.Return(makeIndyCall(
    4.33                      pos,
    4.34                      syms.lambdaMetafactory,
    4.35 -                    names.altMetaFactory,
    4.36 -                    staticArgs, indyType, serArgs.toList())),
    4.37 +                    names.altMetafactory,
    4.38 +                    staticArgs, indyType, serArgs.toList(), samSym.name)),
    4.39                  null);
    4.40          ListBuffer<JCStatement> stmts = kInfo.deserializeCases.get(implMethodName);
    4.41          if (stmts == null) {
    4.42 @@ -905,22 +908,26 @@
    4.43          kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge());
    4.44      }
    4.45  
    4.46 +    private MethodType typeToMethodType(Type mt) {
    4.47 +        Type type = types.erasure(mt);
    4.48 +        return new MethodType(type.getParameterTypes(),
    4.49 +                        type.getReturnType(),
    4.50 +                        type.getThrownTypes(),
    4.51 +                        syms.methodClass);
    4.52 +    }
    4.53 +
    4.54      /**
    4.55       * Generate an indy method call to the meta factory
    4.56       */
    4.57 -    private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory,
    4.58 -            boolean isSerializable, int refKind, Symbol refSym, List<JCExpression> indy_args) {
    4.59 +    private JCExpression makeMetafactoryIndyCall(TranslationContext<?> context,
    4.60 +            int refKind, Symbol refSym, List<JCExpression> indy_args) {
    4.61 +        JCFunctionalExpression tree = context.tree;
    4.62          //determine the static bsm args
    4.63 -        Type mtype = types.erasure(tree.descriptorType);
    4.64          MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
    4.65          List<Object> staticArgs = List.<Object>of(
    4.66 -                new Pool.MethodHandle(ClassFile.REF_invokeInterface,
    4.67 -                    types.findDescriptorSymbol(tree.type.tsym), types),
    4.68 +                typeToMethodType(samSym.type),
    4.69                  new Pool.MethodHandle(refKind, refSym, types),
    4.70 -                new MethodType(mtype.getParameterTypes(),
    4.71 -                        mtype.getReturnType(),
    4.72 -                        mtype.getThrownTypes(),
    4.73 -                        syms.methodClass));
    4.74 +                typeToMethodType(tree.getDescriptorType(types)));
    4.75  
    4.76          //computed indy arg types
    4.77          ListBuffer<Type> indy_args_types = ListBuffer.lb();
    4.78 @@ -934,31 +941,46 @@
    4.79                  List.<Type>nil(),
    4.80                  syms.methodClass);
    4.81  
    4.82 -        Name metafactoryName = needsAltMetafactory ?
    4.83 -                names.altMetaFactory : names.metaFactory;
    4.84 +        Name metafactoryName = context.needsAltMetafactory() ?
    4.85 +                names.altMetafactory : names.metafactory;
    4.86  
    4.87 -        if (needsAltMetafactory) {
    4.88 +        if (context.needsAltMetafactory()) {
    4.89              ListBuffer<Object> markers = ListBuffer.lb();
    4.90 -            for (Symbol t : tree.targets.tail) {
    4.91 -                if (t != syms.serializableType.tsym) {
    4.92 -                    markers.append(t);
    4.93 +            for (Type t : tree.targets.tail) {
    4.94 +                if (t.tsym != syms.serializableType.tsym) {
    4.95 +                    markers.append(t.tsym);
    4.96                  }
    4.97              }
    4.98 -            int flags = isSerializable? FLAG_SERIALIZABLE : 0;
    4.99 +            int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
   4.100              boolean hasMarkers = markers.nonEmpty();
   4.101 -            flags |= hasMarkers ? FLAG_MARKERS : 0;
   4.102 +            boolean hasBridges = context.bridges.nonEmpty();
   4.103 +            if (hasMarkers) {
   4.104 +                flags |= FLAG_MARKERS;
   4.105 +            }
   4.106 +            if (hasBridges) {
   4.107 +                flags |= FLAG_BRIDGES;
   4.108 +            }
   4.109              staticArgs = staticArgs.append(flags);
   4.110              if (hasMarkers) {
   4.111                  staticArgs = staticArgs.append(markers.length());
   4.112                  staticArgs = staticArgs.appendList(markers.toList());
   4.113              }
   4.114 -            if (isSerializable) {
   4.115 +            if (hasBridges) {
   4.116 +                staticArgs = staticArgs.append(context.bridges.length() - 1);
   4.117 +                for (Symbol s : context.bridges) {
   4.118 +                    Type s_erasure = s.erasure(types);
   4.119 +                    if (!types.isSameType(s_erasure, samSym.erasure(types))) {
   4.120 +                        staticArgs = staticArgs.append(s.erasure(types));
   4.121 +                    }
   4.122 +                }
   4.123 +            }
   4.124 +            if (context.isSerializable()) {
   4.125                  addDeserializationCase(refKind, refSym, tree.type, samSym,
   4.126                          tree, staticArgs, indyType);
   4.127              }
   4.128          }
   4.129  
   4.130 -        return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args);
   4.131 +        return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name);
   4.132      }
   4.133  
   4.134      /**
   4.135 @@ -966,7 +988,8 @@
   4.136       * arguments types
   4.137       */
   4.138      private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName,
   4.139 -            List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs) {
   4.140 +            List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs,
   4.141 +            Name methName) {
   4.142          int prevPos = make.pos;
   4.143          try {
   4.144              make.at(pos);
   4.145 @@ -978,7 +1001,7 @@
   4.146                      bsmName, bsm_staticArgs, List.<Type>nil());
   4.147  
   4.148              DynamicMethodSymbol dynSym =
   4.149 -                    new DynamicMethodSymbol(names.lambda,
   4.150 +                    new DynamicMethodSymbol(methName,
   4.151                                              syms.noSymbol,
   4.152                                              bsm.isStatic() ?
   4.153                                                  ClassFile.REF_invokeStatic :
   4.154 @@ -1299,7 +1322,6 @@
   4.155  
   4.156                  // Make lambda holding the new-class call
   4.157                  JCLambda slam = make.Lambda(params, nc);
   4.158 -                slam.descriptorType = tree.descriptorType;
   4.159                  slam.targets = tree.targets;
   4.160                  slam.type = tree.type;
   4.161                  slam.pos = tree.pos;
   4.162 @@ -1634,23 +1656,30 @@
   4.163              /** the enclosing translation context (set for nested lambdas/mref) */
   4.164              TranslationContext<?> prev;
   4.165  
   4.166 +            /** list of methods to be bridged by the meta-factory */
   4.167 +            List<Symbol> bridges;
   4.168 +
   4.169              TranslationContext(T tree) {
   4.170                  this.tree = tree;
   4.171                  this.owner = owner();
   4.172                  this.depth = frameStack.size() - 1;
   4.173                  this.prev = context();
   4.174 +                ClassSymbol csym =
   4.175 +                        types.makeFunctionalInterfaceClass(attrEnv, names.empty, tree.targets, ABSTRACT | INTERFACE);
   4.176 +                this.bridges = types.functionalInterfaceBridges(csym);
   4.177              }
   4.178  
   4.179              /** does this functional expression need to be created using alternate metafactory? */
   4.180              boolean needsAltMetafactory() {
   4.181 -                return (tree.targets.length() > 1 ||
   4.182 -                        isSerializable());
   4.183 +                return tree.targets.length() > 1 ||
   4.184 +                        isSerializable() ||
   4.185 +                        bridges.length() > 1;
   4.186              }
   4.187  
   4.188              /** does this functional expression require serialization support? */
   4.189              boolean isSerializable() {
   4.190 -                for (Symbol target : tree.targets) {
   4.191 -                    if (types.asSuper(target.type, syms.serializableType.tsym) != null) {
   4.192 +                for (Type target : tree.targets) {
   4.193 +                    if (types.asSuper(target, syms.serializableType.tsym) != null) {
   4.194                          return true;
   4.195                      }
   4.196                  }
   4.197 @@ -1833,7 +1862,7 @@
   4.198              }
   4.199  
   4.200              Type generatedLambdaSig() {
   4.201 -                return types.erasure(tree.descriptorType);
   4.202 +                return types.erasure(tree.getDescriptorType(types));
   4.203              }
   4.204          }
   4.205  
   4.206 @@ -1909,7 +1938,7 @@
   4.207              }
   4.208  
   4.209              Type bridgedRefSig() {
   4.210 -                return types.erasure(types.findDescriptorSymbol(tree.targets.head).type);
   4.211 +                return types.erasure(types.findDescriptorSymbol(tree.targets.head.tsym).type);
   4.212              }
   4.213          }
   4.214      }
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Jul 11 10:13:57 2013 -0700
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Jul 11 14:07:39 2013 +0100
     5.3 @@ -68,6 +68,7 @@
     5.4      private TreeMaker make;
     5.5      private Enter enter;
     5.6      private boolean allowEnums;
     5.7 +    private boolean allowInterfaceBridges;
     5.8      private Types types;
     5.9      private final Resolve resolve;
    5.10  
    5.11 @@ -91,6 +92,7 @@
    5.12          Source source = Source.instance(context);
    5.13          allowEnums = source.allowEnums();
    5.14          addBridges = source.addBridges();
    5.15 +        allowInterfaceBridges = source.allowDefaultMethods();
    5.16          types = Types.instance(context);
    5.17          make = TreeMaker.instance(context);
    5.18          resolve = Resolve.instance(context);
    5.19 @@ -252,7 +254,8 @@
    5.20  
    5.21          // Create a bridge method symbol and a bridge definition without a body.
    5.22          Type bridgeType = meth.erasure(types);
    5.23 -        long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE;
    5.24 +        long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE |
    5.25 +                (origin.isInterface() ? DEFAULT : 0);
    5.26          if (hypothetical) flags |= HYPOTHETICAL;
    5.27          MethodSymbol bridge = new MethodSymbol(flags,
    5.28                                                 meth.name,
    5.29 @@ -387,11 +390,12 @@
    5.30          }
    5.31      }
    5.32      // where
    5.33 -        Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() {
    5.34 +        private Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() {
    5.35              public boolean accepts(Symbol s) {
    5.36                  return (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC;
    5.37              }
    5.38          };
    5.39 +
    5.40          /**
    5.41           * @param method The symbol for which a bridge might have to be added
    5.42           * @param impl The implementation of method
    5.43 @@ -999,8 +1003,9 @@
    5.44                      ListBuffer<JCTree> bridges = new ListBuffer<JCTree>();
    5.45                      if (false) //see CR: 6996415
    5.46                          bridges.appendList(addOverrideBridgesIfNeeded(tree, c));
    5.47 -                    if ((tree.sym.flags() & INTERFACE) == 0)
    5.48 -                        addBridges(tree.pos(), tree.sym, bridges);
    5.49 +                    if (allowInterfaceBridges || (tree.sym.flags() & INTERFACE) == 0) {
    5.50 +                        addBridges(tree.pos(), c, bridges);
    5.51 +                    }
    5.52                      tree.defs = bridges.toList().prependList(tree.defs);
    5.53                  }
    5.54                  tree.type = erasure(tree.type);
     6.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Jul 11 10:13:57 2013 -0700
     6.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Jul 11 14:07:39 2013 +0100
     6.3 @@ -641,10 +641,12 @@
     6.4              polyKind = PolyKind.POLY;
     6.5          }
     6.6  
     6.7 -        /** target descriptor inferred for this functional expression. */
     6.8 -        public Type descriptorType;
     6.9          /** list of target types inferred for this functional expression. */
    6.10 -        public List<TypeSymbol> targets;
    6.11 +        public List<Type> targets;
    6.12 +
    6.13 +        public Type getDescriptorType(Types types) {
    6.14 +            return types.findDescriptorType(targets.head);
    6.15 +        }
    6.16      }
    6.17  
    6.18      /**
     7.1 --- a/src/share/classes/com/sun/tools/javac/util/Names.java	Thu Jul 11 10:13:57 2013 -0700
     7.2 +++ b/src/share/classes/com/sun/tools/javac/util/Names.java	Thu Jul 11 14:07:39 2013 +0100
     7.3 @@ -174,8 +174,8 @@
     7.4  
     7.5      //lambda-related
     7.6      public final Name lambda;
     7.7 -    public final Name metaFactory;
     7.8 -    public final Name altMetaFactory;
     7.9 +    public final Name metafactory;
    7.10 +    public final Name altMetafactory;
    7.11  
    7.12      public final Name.Table table;
    7.13  
    7.14 @@ -310,8 +310,8 @@
    7.15  
    7.16          //lambda-related
    7.17          lambda = fromString("lambda$");
    7.18 -        metaFactory = fromString("metaFactory");
    7.19 -        altMetaFactory = fromString("altMetaFactory");
    7.20 +        metafactory = fromString("metafactory");
    7.21 +        altMetafactory = fromString("altMetafactory");
    7.22      }
    7.23  
    7.24      protected Name.Table createTable(Options options) {
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/tools/javac/generics/bridges/Bridge.java	Thu Jul 11 14:07:39 2013 +0100
     8.3 @@ -0,0 +1,28 @@
     8.4 +/*
     8.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + */
    8.26 +import java.lang.annotation.Repeatable;
    8.27 +
    8.28 +@Repeatable(Bridges.class)
    8.29 +@interface Bridge {
    8.30 +    String value();
    8.31 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/tools/javac/generics/bridges/BridgeHarness.java	Thu Jul 11 14:07:39 2013 +0100
     9.3 @@ -0,0 +1,218 @@
     9.4 +/*
     9.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + * @bug 8013789
    9.30 + * @summary Compiler should emit bridges in interfaces
    9.31 + * @library /tools/javac/lib
    9.32 + * @build JavacTestingAbstractProcessor BridgeHarness
    9.33 + * @run main BridgeHarness
    9.34 + */
    9.35 +
    9.36 +import com.sun.source.util.JavacTask;
    9.37 +import com.sun.tools.classfile.AccessFlags;
    9.38 +import com.sun.tools.classfile.ClassFile;
    9.39 +import com.sun.tools.classfile.ConstantPool;
    9.40 +import com.sun.tools.classfile.ConstantPoolException;
    9.41 +import com.sun.tools.classfile.Method;
    9.42 +import com.sun.tools.javac.code.Symbol.ClassSymbol;
    9.43 +import com.sun.tools.javac.util.List;
    9.44 +
    9.45 +import java.io.File;
    9.46 +import java.util.Arrays;
    9.47 +import java.util.Collections;
    9.48 +import java.util.HashMap;
    9.49 +import java.util.Map;
    9.50 +import java.util.Set;
    9.51 +
    9.52 +import javax.annotation.processing.RoundEnvironment;
    9.53 +import javax.annotation.processing.SupportedAnnotationTypes;
    9.54 +import javax.lang.model.element.Element;
    9.55 +import javax.lang.model.element.TypeElement;
    9.56 +import javax.tools.JavaCompiler;
    9.57 +import javax.tools.JavaFileObject;
    9.58 +import javax.tools.StandardJavaFileManager;
    9.59 +import javax.tools.ToolProvider;
    9.60 +
    9.61 +import static javax.tools.StandardLocation.*;
    9.62 +
    9.63 +public class BridgeHarness {
    9.64 +
    9.65 +    /** number of errors found (must be zero for the test to pass) */
    9.66 +    static int nerrors = 0;
    9.67 +
    9.68 +    /** the (shared) Java compiler used for compiling the tests */
    9.69 +    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
    9.70 +
    9.71 +    /** the (shared) file manager used by the compiler */
    9.72 +    static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
    9.73 +
    9.74 +    public static void main(String[] args) throws Exception {
    9.75 +        //set sourcepath
    9.76 +        fm.setLocation(SOURCE_PATH,
    9.77 +                Arrays.asList(new File(System.getProperty("test.src"), "tests")));
    9.78 +        //set output (-d)
    9.79 +        fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT,
    9.80 +                Arrays.asList(new File(System.getProperty("user.dir"))));
    9.81 +        for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
    9.82 +            //for each source, compile and check against annotations
    9.83 +            new BridgeHarness(jfo).compileAndCheck();
    9.84 +        }
    9.85 +        //if there were errors, fail
    9.86 +        if (nerrors > 0) {
    9.87 +            throw new AssertionError("Errors were found");
    9.88 +        }
    9.89 +    }
    9.90 +
    9.91 +    /* utility methods */
    9.92 +
    9.93 +    /**
    9.94 +     * Remove an element from a list
    9.95 +     */
    9.96 +    static <Z> List<Z> drop(List<Z> lz, Z z) {
    9.97 +        if (lz.head == z) {
    9.98 +            return drop(lz.tail, z);
    9.99 +        } else if (lz.isEmpty()) {
   9.100 +            return lz;
   9.101 +        } else {
   9.102 +            return drop(lz.tail, z).prepend(lz.head);
   9.103 +        }
   9.104 +    }
   9.105 +
   9.106 +    /**
   9.107 +     * return a string representation of a bytecode method
   9.108 +     */
   9.109 +    static String descriptor(Method m, ConstantPool cp) throws ConstantPoolException {
   9.110 +        return m.getName(cp) + m.descriptor.getValue(cp);
   9.111 +    }
   9.112 +
   9.113 +    /* test harness */
   9.114 +
   9.115 +    /** Test file to be compiled */
   9.116 +    JavaFileObject jfo;
   9.117 +
   9.118 +    /** Mapping between class name and list of bridges in class with that name */
   9.119 +    Map<String, List<Bridge>> bridgesMap = new HashMap<String, List<Bridge>>();
   9.120 +
   9.121 +    protected BridgeHarness(JavaFileObject jfo) {
   9.122 +        this.jfo = jfo;
   9.123 +    }
   9.124 +
   9.125 +    /**
   9.126 +     * Compile a test using a custom annotation processor and check the generated
   9.127 +     * bytecode against discovered annotations.
   9.128 +     */
   9.129 +    protected void compileAndCheck() throws Exception {
   9.130 +        JavacTask ct = (JavacTask)comp.getTask(null, fm, null, null, null, Arrays.asList(jfo));
   9.131 +        ct.setProcessors(Collections.singleton(new BridgeFinder()));
   9.132 +
   9.133 +        for (JavaFileObject jfo : ct.generate()) {
   9.134 +            checkBridges(jfo);
   9.135 +        }
   9.136 +    }
   9.137 +
   9.138 +    /**
   9.139 +     * Check that every bridge in the generated classfile has a matching bridge
   9.140 +     * annotation in the bridge map
   9.141 +     */
   9.142 +    protected void checkBridges(JavaFileObject jfo) {
   9.143 +        try {
   9.144 +            ClassFile cf = ClassFile.read(jfo.openInputStream());
   9.145 +            System.err.println("checking: " + cf.getName());
   9.146 +
   9.147 +            List<Bridge> bridgeList = bridgesMap.get(cf.getName());
   9.148 +            if (bridgeList == null) {
   9.149 +                //no bridges - nothing to check;
   9.150 +                bridgeList = List.nil();
   9.151 +            }
   9.152 +
   9.153 +            for (Method m : cf.methods) {
   9.154 +                if (m.access_flags.is(AccessFlags.ACC_SYNTHETIC | AccessFlags.ACC_BRIDGE)) {
   9.155 +                    //this is a bridge - see if there's a match in the bridge list
   9.156 +                    Bridge match = null;
   9.157 +                    for (Bridge b : bridgeList) {
   9.158 +                        if (b.value().equals(descriptor(m, cf.constant_pool))) {
   9.159 +                            match = b;
   9.160 +                            break;
   9.161 +                        }
   9.162 +                    }
   9.163 +                    if (match == null) {
   9.164 +                        error("No annotation for bridge method: " + descriptor(m, cf.constant_pool));
   9.165 +                    } else {
   9.166 +                        bridgeList = drop(bridgeList, match);
   9.167 +                    }
   9.168 +                }
   9.169 +            }
   9.170 +            if (bridgeList.nonEmpty()) {
   9.171 +                error("Redundant bridge annotation found: " + bridgeList.head.value());
   9.172 +            }
   9.173 +        } catch (Exception e) {
   9.174 +            e.printStackTrace();
   9.175 +            throw new Error("error reading " + jfo.toUri() +": " + e);
   9.176 +        }
   9.177 +    }
   9.178 +
   9.179 +    /**
   9.180 +     * Log an error
   9.181 +     */
   9.182 +    protected void error(String msg) {
   9.183 +        nerrors++;
   9.184 +        System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg);
   9.185 +    }
   9.186 +
   9.187 +    /**
   9.188 +     * This annotation processor is used to populate the bridge map with the
   9.189 +     * contents of the annotations that are found on the tests being compiled
   9.190 +     */
   9.191 +    @SupportedAnnotationTypes({"Bridges","Bridge"})
   9.192 +    class BridgeFinder extends JavacTestingAbstractProcessor {
   9.193 +        @Override
   9.194 +        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   9.195 +            if (roundEnv.processingOver())
   9.196 +                return true;
   9.197 +
   9.198 +            TypeElement bridgeAnno = elements.getTypeElement("Bridge");
   9.199 +            TypeElement bridgesAnno = elements.getTypeElement("Bridges");
   9.200 +
   9.201 +            //see if there are repeated annos
   9.202 +            for (Element elem: roundEnv.getElementsAnnotatedWith(bridgesAnno)) {
   9.203 +                List<Bridge> bridgeList = List.nil();
   9.204 +                Bridges bridges = elem.getAnnotation(Bridges.class);
   9.205 +                for (Bridge bridge : bridges.value()) {
   9.206 +                    bridgeList = bridgeList.prepend(bridge);
   9.207 +                }
   9.208 +                bridgesMap.put(((ClassSymbol)elem).flatname.toString(), bridgeList);
   9.209 +            }
   9.210 +
   9.211 +            //see if there are non-repeated annos
   9.212 +            for (Element elem: roundEnv.getElementsAnnotatedWith(bridgeAnno)) {
   9.213 +                Bridge bridge = elem.getAnnotation(Bridge.class);
   9.214 +                bridgesMap.put(((ClassSymbol)elem).flatname.toString(),
   9.215 +                        List.of(bridge));
   9.216 +            }
   9.217 +
   9.218 +            return true;
   9.219 +        }
   9.220 +    }
   9.221 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/tools/javac/generics/bridges/Bridges.java	Thu Jul 11 14:07:39 2013 +0100
    10.3 @@ -0,0 +1,25 @@
    10.4 +/*
    10.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.
   10.11 + *
   10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.15 + * version 2 for more details (a copy is included in the LICENSE file that
   10.16 + * accompanied this code).
   10.17 + *
   10.18 + * You should have received a copy of the GNU General Public License version
   10.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.21 + *
   10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.23 + * or visit www.oracle.com if you need additional information or have any
   10.24 + * questions.
   10.25 + */
   10.26 +@interface Bridges {
   10.27 +    Bridge[] value();
   10.28 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java	Thu Jul 11 14:07:39 2013 +0100
    11.3 @@ -0,0 +1,31 @@
    11.4 +/*
    11.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +class TestBridgeWithDefault {
   11.27 +    interface A { Object m(int x); }
   11.28 +
   11.29 +    @Bridge("m(I)Ljava/lang/Object;")
   11.30 +    interface B extends A {
   11.31 +        String m(int x);
   11.32 +        default Integer m(long x) { return null; }
   11.33 +    }
   11.34 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java	Thu Jul 11 14:07:39 2013 +0100
    12.3 @@ -0,0 +1,45 @@
    12.4 +/*
    12.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.23 + * or visit www.oracle.com if you need additional information or have any
   12.24 + * questions.
   12.25 + */
   12.26 +class TestClassAndInterfaceBridgeIdentical01 {
   12.27 +
   12.28 +    interface A { Object m(); }
   12.29 +    interface B { Number m(); }
   12.30 +
   12.31 +    @Bridge("m()Ljava/lang/Object;")
   12.32 +    @Bridge("m()Ljava/lang/Number;")
   12.33 +    interface C extends A, B {
   12.34 +        Integer m();
   12.35 +    }
   12.36 +
   12.37 +    @Bridge("m()Ljava/lang/Object;")
   12.38 +    @Bridge("m()Ljava/lang/Number;")
   12.39 +    static abstract class D implements A, B {
   12.40 +        public abstract Integer m();
   12.41 +    }
   12.42 +
   12.43 +    @Bridge("m()Ljava/lang/Object;")
   12.44 +    @Bridge("m()Ljava/lang/Number;")
   12.45 +    static class E implements A, B {
   12.46 +        public Integer m() { return 1; }
   12.47 +    }
   12.48 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java	Thu Jul 11 14:07:39 2013 +0100
    13.3 @@ -0,0 +1,45 @@
    13.4 +/*
    13.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.23 + * or visit www.oracle.com if you need additional information or have any
   13.24 + * questions.
   13.25 + */
   13.26 +class TestClassAndInterfaceBridgeIdentical02 {
   13.27 +
   13.28 +    interface A<X extends Object> { void m(X x); }
   13.29 +    interface B<X extends Number> { void m(X x); }
   13.30 +
   13.31 +    @Bridge("m(Ljava/lang/Object;)V")
   13.32 +    @Bridge("m(Ljava/lang/Number;)V")
   13.33 +    interface C extends A<Integer>, B<Integer> {
   13.34 +        void m(Integer i);
   13.35 +    }
   13.36 +
   13.37 +    @Bridge("m(Ljava/lang/Object;)V")
   13.38 +    @Bridge("m(Ljava/lang/Number;)V")
   13.39 +    static abstract class D implements A<Integer>, B<Integer> {
   13.40 +        public abstract void m(Integer i);
   13.41 +    }
   13.42 +
   13.43 +    @Bridge("m(Ljava/lang/Object;)V")
   13.44 +    @Bridge("m(Ljava/lang/Number;)V")
   13.45 +    static class E implements A<Integer>, B<Integer> {
   13.46 +        public void m(Integer i) { }
   13.47 +    }
   13.48 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java	Thu Jul 11 14:07:39 2013 +0100
    14.3 @@ -0,0 +1,34 @@
    14.4 +/*
    14.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 + * or visit www.oracle.com if you need additional information or have any
   14.24 + * questions.
   14.25 + */
   14.26 +class TestNoBridgeInSiblingSuper {
   14.27 +    interface A { Object m(); }
   14.28 +    interface B { String m(); }
   14.29 +    //no bridge here!
   14.30 +    interface C extends A, B { }
   14.31 +
   14.32 +    @Bridge("m()Ljava/lang/Object;")
   14.33 +    interface D extends C {
   14.34 +        String m();
   14.35 +    }
   14.36 +}
   14.37 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java	Thu Jul 11 14:07:39 2013 +0100
    15.3 @@ -0,0 +1,29 @@
    15.4 +/*
    15.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + *
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + *
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + *
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +class TestNoDuplicateBridges01 {
   15.27 +    interface A1 { Object m(); }
   15.28 +    interface A2 { Object m(); }
   15.29 +
   15.30 +    @Bridge("m()Ljava/lang/Object;")
   15.31 +    interface B extends A1, A2 { B m(); }
   15.32 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java	Thu Jul 11 14:07:39 2013 +0100
    16.3 @@ -0,0 +1,38 @@
    16.4 +/*
    16.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +class TestNoDuplicateBridges02 {
   16.27 +    interface A<T> {
   16.28 +        A<T> get();
   16.29 +    }
   16.30 +
   16.31 +    @Bridge("get()LTestNoDuplicateBridges02$A;")
   16.32 +    interface B<T> extends A<T> {
   16.33 +        B<T> get();
   16.34 +    }
   16.35 +
   16.36 +    @Bridge("get()LTestNoDuplicateBridges02$A;")
   16.37 +    @Bridge("get()LTestNoDuplicateBridges02$B;")
   16.38 +    interface C<T> extends A<T>, B<T> {
   16.39 +        C<T> get();
   16.40 +    }
   16.41 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/tools/javac/lambda/bridge/TestMetafactoryBridges.java	Thu Jul 11 14:07:39 2013 +0100
    17.3 @@ -0,0 +1,359 @@
    17.4 +/*
    17.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.
   17.11 + *
   17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.15 + * version 2 for more details (a copy is included in the LICENSE file that
   17.16 + * accompanied this code).
   17.17 + *
   17.18 + * You should have received a copy of the GNU General Public License version
   17.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.21 + *
   17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.23 + * or visit www.oracle.com if you need additional information or have any
   17.24 + * questions.
   17.25 + */
   17.26 +
   17.27 +/*
   17.28 + * @test
   17.29 + * @bug 8013789
   17.30 + * @summary Compiler should emit bridges in interfaces
   17.31 + */
   17.32 +
   17.33 +import com.sun.source.util.JavacTask;
   17.34 +import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
   17.35 +import com.sun.tools.javac.code.Symbol;
   17.36 +import com.sun.tools.javac.util.JCDiagnostic;
   17.37 +
   17.38 +import java.io.File;
   17.39 +import java.io.PrintWriter;
   17.40 +import java.net.URI;
   17.41 +import java.util.ArrayList;
   17.42 +import java.util.Arrays;
   17.43 +import java.util.EnumSet;
   17.44 +import java.util.List;
   17.45 +import java.util.Set;
   17.46 +
   17.47 +import javax.tools.Diagnostic;
   17.48 +import javax.tools.Diagnostic.Kind;
   17.49 +import javax.tools.JavaCompiler;
   17.50 +import javax.tools.JavaFileObject;
   17.51 +import javax.tools.SimpleJavaFileObject;
   17.52 +import javax.tools.ToolProvider;
   17.53 +
   17.54 +public class TestMetafactoryBridges {
   17.55 +
   17.56 +    static int checkCount = 0;
   17.57 +
   17.58 +    enum ClasspathKind {
   17.59 +        NONE(),
   17.60 +        B7(7, ClassKind.B),
   17.61 +        A7(7, ClassKind.A),
   17.62 +        B8(8, ClassKind.B),
   17.63 +        A8(8, ClassKind.A);
   17.64 +
   17.65 +        int version;
   17.66 +        ClassKind ck;
   17.67 +
   17.68 +        ClasspathKind() {
   17.69 +            this(-1, null);
   17.70 +        }
   17.71 +
   17.72 +        ClasspathKind(int version, ClassKind ck) {
   17.73 +            this.version = version;
   17.74 +            this.ck = ck;
   17.75 +        }
   17.76 +    }
   17.77 +
   17.78 +    enum PreferPolicy {
   17.79 +        SOURCE("-Xprefer:source"),
   17.80 +        NEWER("-Xprefer:newer");
   17.81 +
   17.82 +        String preferOpt;
   17.83 +
   17.84 +        PreferPolicy(String preferOpt) {
   17.85 +            this.preferOpt = preferOpt;
   17.86 +        }
   17.87 +    }
   17.88 +
   17.89 +    enum SourcepathKind {
   17.90 +        NONE,
   17.91 +        A(ClassKind.A),
   17.92 +        B(ClassKind.B),
   17.93 +        C(ClassKind.C),
   17.94 +        AB(ClassKind.A, ClassKind.B),
   17.95 +        BC(ClassKind.B, ClassKind.C),
   17.96 +        AC(ClassKind.A, ClassKind.C),
   17.97 +        ABC(ClassKind.A, ClassKind.B, ClassKind.C);
   17.98 +
   17.99 +        List<ClassKind> sources;
  17.100 +
  17.101 +        SourcepathKind(ClassKind... sources) {
  17.102 +            this.sources = Arrays.asList(sources);
  17.103 +        }
  17.104 +    }
  17.105 +
  17.106 +    enum SourceSet {
  17.107 +        ALL() {
  17.108 +            @Override
  17.109 +            List<List<ClassKind>> permutations() {
  17.110 +                return Arrays.asList(
  17.111 +                    Arrays.asList(ClassKind.A, ClassKind.B, ClassKind.C),
  17.112 +                    Arrays.asList(ClassKind.A, ClassKind.B, ClassKind.C),
  17.113 +                    Arrays.asList(ClassKind.B, ClassKind.A, ClassKind.C),
  17.114 +                    Arrays.asList(ClassKind.B, ClassKind.C, ClassKind.A),
  17.115 +                    Arrays.asList(ClassKind.C, ClassKind.A, ClassKind.B),
  17.116 +                    Arrays.asList(ClassKind.C, ClassKind.B, ClassKind.A)
  17.117 +                );
  17.118 +            }
  17.119 +        },
  17.120 +        AC() {
  17.121 +            @Override
  17.122 +            List<List<ClassKind>> permutations() {
  17.123 +                return Arrays.asList(
  17.124 +                    Arrays.asList(ClassKind.A, ClassKind.C),
  17.125 +                    Arrays.asList(ClassKind.C, ClassKind.A)
  17.126 +                );
  17.127 +            }
  17.128 +        },
  17.129 +        C() {
  17.130 +            @Override
  17.131 +            List<List<ClassKind>> permutations() {
  17.132 +                return Arrays.asList(Arrays.asList(ClassKind.C));
  17.133 +            }
  17.134 +        };
  17.135 +
  17.136 +        abstract List<List<ClassKind>> permutations();
  17.137 +    }
  17.138 +
  17.139 +    enum ClassKind {
  17.140 +        A("A", "interface A { Object m(); }"),
  17.141 +        B("B", "interface B extends A { Integer m(); }", A),
  17.142 +        C("C", "class C { B b = ()->42; }", A, B);
  17.143 +
  17.144 +        String name;
  17.145 +        String source;
  17.146 +        ClassKind[] deps;
  17.147 +
  17.148 +        ClassKind(String name, String source, ClassKind... deps) {
  17.149 +            this.name = name;
  17.150 +            this.source = source;
  17.151 +            this.deps = deps;
  17.152 +        }
  17.153 +    }
  17.154 +
  17.155 +    public static void main(String... args) throws Exception {
  17.156 +        String SCRATCH_DIR = System.getProperty("user.dir");
  17.157 +        //create default shared JavaCompiler - reused across multiple compilations
  17.158 +        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
  17.159 +
  17.160 +        int n = 0;
  17.161 +        for (SourceSet ss : SourceSet.values()) {
  17.162 +            for (List<ClassKind> sources : ss.permutations()) {
  17.163 +                for (SourcepathKind spKind : SourcepathKind.values()) {
  17.164 +                    for (ClasspathKind cpKind : ClasspathKind.values()) {
  17.165 +                        for (PreferPolicy pp : PreferPolicy.values()) {
  17.166 +                            Set<ClassKind> deps = EnumSet.noneOf(ClassKind.class);
  17.167 +                            if (cpKind.ck != null) {
  17.168 +                                deps.add(cpKind.ck);
  17.169 +                            }
  17.170 +                            deps.addAll(sources);
  17.171 +                            if (deps.size() < 3) continue;
  17.172 +                            File testDir = new File(SCRATCH_DIR, "test" + n);
  17.173 +                            testDir.mkdir();
  17.174 +                            try (PrintWriter debugWriter = new PrintWriter(new File(testDir, "debug.txt"))) {
  17.175 +                                new TestMetafactoryBridges(testDir, sources, spKind, cpKind, pp, debugWriter).run(comp);
  17.176 +                                n++;
  17.177 +                            }
  17.178 +                        }
  17.179 +                    }
  17.180 +                }
  17.181 +            }
  17.182 +        }
  17.183 +        System.out.println("Total check executed: " + checkCount);
  17.184 +    }
  17.185 +
  17.186 +    File testDir;
  17.187 +    List<ClassKind> sources;
  17.188 +    SourcepathKind spKind;
  17.189 +    ClasspathKind cpKind;
  17.190 +    PreferPolicy pp;
  17.191 +    PrintWriter debugWriter;
  17.192 +    DiagnosticChecker diagChecker;
  17.193 +
  17.194 +    TestMetafactoryBridges(File testDir, List<ClassKind>sources, SourcepathKind spKind,
  17.195 +            ClasspathKind cpKind, PreferPolicy pp, PrintWriter debugWriter) {
  17.196 +        this.testDir = testDir;
  17.197 +        this.sources = sources;
  17.198 +        this.spKind = spKind;
  17.199 +        this.cpKind = cpKind;
  17.200 +        this.pp = pp;
  17.201 +        this.debugWriter = debugWriter;
  17.202 +        this.diagChecker = new DiagnosticChecker();
  17.203 +    }
  17.204 +
  17.205 +    class JavaSource extends SimpleJavaFileObject {
  17.206 +
  17.207 +        final String source;
  17.208 +
  17.209 +        public JavaSource(ClassKind ck) {
  17.210 +            super(URI.create(String.format("myfo:/%s.java", ck.name)), JavaFileObject.Kind.SOURCE);
  17.211 +            this.source = ck.source;
  17.212 +        }
  17.213 +
  17.214 +        @Override
  17.215 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
  17.216 +            return source;
  17.217 +        }
  17.218 +    }
  17.219 +
  17.220 +    void run(JavaCompiler tool) throws Exception {
  17.221 +        File classesDir = new File(testDir, "classes");
  17.222 +        File outDir = new File(testDir, "out");
  17.223 +        File srcDir = new File(testDir, "src");
  17.224 +        classesDir.mkdir();
  17.225 +        outDir.mkdir();
  17.226 +        srcDir.mkdir();
  17.227 +
  17.228 +        debugWriter.append(testDir.getName() + "\n");
  17.229 +        debugWriter.append("sources = " + sources + "\n");
  17.230 +        debugWriter.append("spKind = " + spKind  + "\n");
  17.231 +        debugWriter.append("cpKind = " + cpKind + "\n");
  17.232 +        debugWriter.append("preferPolicy = " + pp.preferOpt + "\n");
  17.233 +
  17.234 +        //step 1 - prepare sources (older!!)
  17.235 +        debugWriter.append("Preparing sources\n");
  17.236 +        for (ClassKind ck : spKind.sources) {
  17.237 +            //skip sources explicitly provided on command line
  17.238 +            if (!sources.contains(ck)) {
  17.239 +                debugWriter.append("Copy " + ck.name + ".java to" + srcDir.getAbsolutePath() + "\n");
  17.240 +                File dest = new File(srcDir, ck.name + ".java");
  17.241 +                PrintWriter pw = new PrintWriter(dest);
  17.242 +                pw.append(ck.source);
  17.243 +                pw.close();
  17.244 +            }
  17.245 +        }
  17.246 +
  17.247 +        //step 2 - prepare classes
  17.248 +        debugWriter.append("Preparing classes\n");
  17.249 +        if (cpKind != ClasspathKind.NONE) {
  17.250 +            List<JavaSource> sources = new ArrayList<>();
  17.251 +            ClassKind toRemove = null;
  17.252 +            sources.add(new JavaSource(cpKind.ck));
  17.253 +            if (cpKind.ck.deps.length != 0) {
  17.254 +                //at most only one dependency
  17.255 +                toRemove = cpKind.ck.deps[0];
  17.256 +                sources.add(new JavaSource(toRemove));
  17.257 +            }
  17.258 +            JavacTask ct = (JavacTask)tool.getTask(debugWriter, null, null,
  17.259 +                    Arrays.asList("-d", classesDir.getAbsolutePath(), "-source", String.valueOf(cpKind.version)), null, sources);
  17.260 +            try {
  17.261 +                ct.generate();
  17.262 +                if (toRemove != null) {
  17.263 +                    debugWriter.append("Remove " + toRemove.name + ".class from" + classesDir.getAbsolutePath() + "\n");
  17.264 +                    File fileToRemove = new File(classesDir, toRemove.name + ".class");
  17.265 +                    fileToRemove.delete();
  17.266 +                }
  17.267 +            } catch (Throwable ex) {
  17.268 +                throw new AssertionError("Error thrown when generating side-classes");
  17.269 +            }
  17.270 +        }
  17.271 +
  17.272 +        //step 3 - compile
  17.273 +        debugWriter.append("Compiling test\n");
  17.274 +        List<JavaSource> sourcefiles = new ArrayList<>();
  17.275 +        for (ClassKind ck : sources) {
  17.276 +            sourcefiles.add(new JavaSource(ck));
  17.277 +        }
  17.278 +        JavacTask ct = (JavacTask)tool.getTask(debugWriter, null, diagChecker,
  17.279 +                    Arrays.asList("-XDdumpLambdaToMethodStats", "-d", outDir.getAbsolutePath(),
  17.280 +                                  "-sourcepath", srcDir.getAbsolutePath(),
  17.281 +                                  "-classpath", classesDir.getAbsolutePath(),
  17.282 +                                  pp.preferOpt), null, sourcefiles);
  17.283 +        try {
  17.284 +            ct.generate();
  17.285 +        } catch (Throwable ex) {
  17.286 +            throw new AssertionError("Error thrown when compiling test case");
  17.287 +        }
  17.288 +        check();
  17.289 +    }
  17.290 +
  17.291 +    void check() {
  17.292 +        checkCount++;
  17.293 +        if (diagChecker.errorFound) {
  17.294 +            throw new AssertionError("Unexpected compilation failure");
  17.295 +        }
  17.296 +
  17.297 +        boolean altMetafactory =
  17.298 +                cpKind == ClasspathKind.B7 &&
  17.299 +                !sources.contains(ClassKind.B) &&
  17.300 +                (pp == PreferPolicy.NEWER || !spKind.sources.contains(ClassKind.B));
  17.301 +
  17.302 +        if (altMetafactory != diagChecker.altMetafactory) {
  17.303 +            throw new AssertionError("Bad metafactory detected - expected altMetafactory: " + altMetafactory +
  17.304 +                    "\ntest: " + testDir);
  17.305 +        }
  17.306 +    }
  17.307 +
  17.308 +    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
  17.309 +
  17.310 +        boolean altMetafactory = false;
  17.311 +        boolean errorFound = false;
  17.312 +
  17.313 +        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  17.314 +            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
  17.315 +                errorFound = true;
  17.316 +            } else if (statProcessor.matches(diagnostic)) {
  17.317 +                statProcessor.process(diagnostic);
  17.318 +            }
  17.319 +        }
  17.320 +
  17.321 +        abstract class DiagnosticProcessor {
  17.322 +
  17.323 +            List<String> codes;
  17.324 +            Diagnostic.Kind kind;
  17.325 +
  17.326 +            public DiagnosticProcessor(Kind kind, String... codes) {
  17.327 +                this.codes = Arrays.asList(codes);
  17.328 +                this.kind = kind;
  17.329 +            }
  17.330 +
  17.331 +            abstract void process(Diagnostic<? extends JavaFileObject> diagnostic);
  17.332 +
  17.333 +            boolean matches(Diagnostic<? extends JavaFileObject> diagnostic) {
  17.334 +                return (codes.isEmpty() || codes.contains(diagnostic.getCode())) &&
  17.335 +                        diagnostic.getKind() == kind;
  17.336 +            }
  17.337 +
  17.338 +            JCDiagnostic asJCDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic) {
  17.339 +                if (diagnostic instanceof JCDiagnostic) {
  17.340 +                    return (JCDiagnostic)diagnostic;
  17.341 +                } else if (diagnostic instanceof DiagnosticSourceUnwrapper) {
  17.342 +                    return ((DiagnosticSourceUnwrapper)diagnostic).d;
  17.343 +                } else {
  17.344 +                    throw new AssertionError("Cannot convert diagnostic to JCDiagnostic: " + diagnostic.getClass().getName());
  17.345 +                }
  17.346 +            }
  17.347 +        }
  17.348 +
  17.349 +        DiagnosticProcessor statProcessor = new DiagnosticProcessor(Kind.NOTE,
  17.350 +                "compiler.note.lambda.stat",
  17.351 +                "compiler.note.mref.stat",
  17.352 +                "compiler.note.mref.stat.1") {
  17.353 +            @Override
  17.354 +            void process(Diagnostic<? extends JavaFileObject> diagnostic) {
  17.355 +                JCDiagnostic diag = asJCDiagnostic(diagnostic);
  17.356 +                if ((Boolean)diag.getArgs()[0]) {
  17.357 +                    altMetafactory = true;
  17.358 +                }
  17.359 +            }
  17.360 +        };
  17.361 +    }
  17.362 +}
    18.1 --- a/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java	Thu Jul 11 10:13:57 2013 -0700
    18.2 +++ b/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java	Thu Jul 11 14:07:39 2013 +0100
    18.3 @@ -105,7 +105,7 @@
    18.4              Class returnType = m.getReturnType();
    18.5              assertTrue(types.remove(returnType.getName()));
    18.6          }
    18.7 -        assertTrue(types.isEmpty());
    18.8 +        assertTrue(types.size() == 1); //there's a bridge
    18.9      }
   18.10  
   18.11  
    19.1 --- a/test/tools/javac/lambda/methodReference/BridgeMethod.java	Thu Jul 11 10:13:57 2013 -0700
    19.2 +++ b/test/tools/javac/lambda/methodReference/BridgeMethod.java	Thu Jul 11 14:07:39 2013 +0100
    19.3 @@ -112,6 +112,6 @@
    19.4              Class<?> returnType = m.getReturnType();
    19.5              assertTrue(types.remove(returnType.getName()));
    19.6          }
    19.7 -        assertTrue(types.isEmpty());
    19.8 +        assertTrue(types.size() == 1); //there's a bridge
    19.9      }
   19.10  }
    20.1 --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java	Thu Jul 11 10:13:57 2013 -0700
    20.2 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java	Thu Jul 11 14:07:39 2013 +0100
    20.3 @@ -395,6 +395,7 @@
    20.4       * TEST: C c = new C(); c.m() == 88;
    20.5       * TEST: I i = new C(); i.m() == 88;
    20.6       */
    20.7 +    @Test(enabled=false)
    20.8      public void testSelfFill() {
    20.9          // This test ensures that a concrete method overrides a default method
   20.10          // that matches at the language-level, but has a different method
   20.11 @@ -484,6 +485,7 @@
   20.12       * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
   20.13       * TEST: K<String> k = new C(); k.m("A","B","C") == 88;
   20.14       */
   20.15 +    @Test(enabled=false)
   20.16      public void testBridges() {
   20.17          DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
   20.18              new MethodParameter("T", "t"), new MethodParameter("V", "v"),
   20.19 @@ -672,6 +674,7 @@
   20.20       * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
   20.21       * TEST: S s = new S(); s.foo() == new Integer(99)
   20.22       */
   20.23 +    @Test(enabled=false)
   20.24      public void testCovarBridge() {
   20.25          Interface I = new Interface("I", new DefaultMethod(
   20.26              "Integer", "m", "return new Integer(88);"));
   20.27 @@ -754,6 +757,7 @@
   20.28       * Test that a erased-signature-matching method does not implement
   20.29       * non-language-level matching methods
   20.30       */
   20.31 +    @Test(enabled=false)
   20.32      public void testNonConcreteFill() {
   20.33          AbstractMethod ipm = new AbstractMethod("int", "m",
   20.34              new MethodParameter("T", "t"),

mercurial