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

changeset 2607
10e9228e77b0
parent 2590
ffed5df6bec9
child 2614
b5c8adb2206a
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Nov 14 20:27:08 2014 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Nov 14 21:10:58 2014 -0800
     1.3 @@ -321,7 +321,9 @@
     1.4  
     1.5          ListBuffer<JCExpression> syntheticInits = new ListBuffer<>();
     1.6  
     1.7 -        if (!sym.isStatic()) {
     1.8 +        if (localContext.methodReferenceReceiver != null) {
     1.9 +            syntheticInits.append(localContext.methodReferenceReceiver);
    1.10 +        } else if (!sym.isStatic()) {
    1.11              syntheticInits.append(makeThis(
    1.12                      sym.owner.enclClass().asType(),
    1.13                      localContext.owner.enclClass()));
    1.14 @@ -364,17 +366,10 @@
    1.15  
    1.16          //first determine the method symbol to be used to generate the sam instance
    1.17          //this is either the method reference symbol, or the bridged reference symbol
    1.18 -        Symbol refSym = localContext.needsBridge()
    1.19 -                ? localContext.bridgeSym
    1.20 -                : localContext.isSignaturePolymorphic()
    1.21 +        Symbol refSym = localContext.isSignaturePolymorphic()
    1.22                  ? localContext.sigPolySym
    1.23                  : tree.sym;
    1.24  
    1.25 -        //build the bridge method, if needed
    1.26 -        if (localContext.needsBridge()) {
    1.27 -            bridgeMemberReference(tree, localContext);
    1.28 -        }
    1.29 -
    1.30          //the qualifying expression is treated as a special captured arg
    1.31          JCExpression init;
    1.32          switch(tree.kind) {
    1.33 @@ -744,54 +739,51 @@
    1.34      // </editor-fold>
    1.35  
    1.36      /**
    1.37 -     * Generate an adapter method "bridge" for a method reference which cannot
    1.38 -     * be used directly.
    1.39 +     * Converts a method reference which cannot be used directly into a lambda
    1.40       */
    1.41 -    private class MemberReferenceBridger {
    1.42 +    private class MemberReferenceToLambda {
    1.43  
    1.44          private final JCMemberReference tree;
    1.45          private final ReferenceTranslationContext localContext;
    1.46 +        private final Symbol owner;
    1.47          private final ListBuffer<JCExpression> args = new ListBuffer<>();
    1.48          private final ListBuffer<JCVariableDecl> params = new ListBuffer<>();
    1.49  
    1.50 -        MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) {
    1.51 +        private JCExpression receiverExpression = null;
    1.52 +
    1.53 +        MemberReferenceToLambda(JCMemberReference tree, ReferenceTranslationContext localContext, Symbol owner) {
    1.54              this.tree = tree;
    1.55              this.localContext = localContext;
    1.56 +            this.owner = owner;
    1.57          }
    1.58  
    1.59 -        /**
    1.60 -         * Generate the bridge
    1.61 -         */
    1.62 -        JCMethodDecl bridge() {
    1.63 +        JCLambda lambda() {
    1.64              int prevPos = make.pos;
    1.65              try {
    1.66                  make.at(tree);
    1.67                  Type samDesc = localContext.bridgedRefSig();
    1.68                  List<Type> samPTypes = samDesc.getParameterTypes();
    1.69  
    1.70 -                //an extra argument is prepended to the signature of the bridge in case
    1.71 -                //the member reference is an instance method reference (in which case
    1.72 -                //the receiver expression is passed to the bridge itself).
    1.73 -                Type recType = null;
    1.74 +                // an extra argument is prepended in the case where the member
    1.75 +                // reference is an unbound instance method reference (in which
    1.76 +                // case the receiver expression in passed.
    1.77 +                VarSymbol rcvr;
    1.78                  switch (tree.kind) {
    1.79 -                    case IMPLICIT_INNER:
    1.80 -                        recType = tree.sym.owner.type.getEnclosingType();
    1.81 -                        break;
    1.82                      case BOUND:
    1.83 -                        recType = tree.getQualifierExpression().type;
    1.84 +                        rcvr = addParameter("rec$", tree.getQualifierExpression().type, false);
    1.85 +                        receiverExpression = attr.makeNullCheck(tree.getQualifierExpression());
    1.86                          break;
    1.87                      case UNBOUND:
    1.88 -                        recType = samPTypes.head;
    1.89 +                        rcvr = addParameter("rec$", samPTypes.head, false);
    1.90                          samPTypes = samPTypes.tail;
    1.91                          break;
    1.92 +                    default:
    1.93 +                        rcvr = null;
    1.94 +                        break;
    1.95                  }
    1.96  
    1.97 -                //generate the parameter list for the bridged member reference - the
    1.98 -                //bridge signature will match the signature of the target sam descriptor
    1.99 -
   1.100 -                VarSymbol rcvr = (recType == null)
   1.101 -                        ? null
   1.102 -                        : addParameter("rec$", recType, false);
   1.103 +                // generate the parameter list for the coverted member reference.
   1.104 +                // the signature will match the signature of the target sam descriptor
   1.105  
   1.106                  List<Type> refPTypes = tree.sym.type.getParameterTypes();
   1.107                  int refSize = refPTypes.size();
   1.108 @@ -810,64 +802,50 @@
   1.109                      addParameter("xva$" + i, tree.varargsElement, true);
   1.110                  }
   1.111  
   1.112 -                //generate the bridge method declaration
   1.113 -                JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()),
   1.114 -                        localContext.bridgeSym.name,
   1.115 -                        make.QualIdent(samDesc.getReturnType().tsym),
   1.116 -                        List.<JCTypeParameter>nil(),
   1.117 -                        params.toList(),
   1.118 -                        tree.sym.type.getThrownTypes() == null
   1.119 -                        ? List.<JCExpression>nil()
   1.120 -                        : make.Types(tree.sym.type.getThrownTypes()),
   1.121 -                        null,
   1.122 -                        null);
   1.123 -                bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym;
   1.124 -                bridgeDecl.type = localContext.bridgeSym.type =
   1.125 -                        types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList()));
   1.126 +                //body generation - this can be either a method call or a
   1.127 +                //new instance creation expression, depending on the member reference kind
   1.128 +                JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE)
   1.129 +                        ? expressionInvoke(rcvr)
   1.130 +                        : expressionNew();
   1.131  
   1.132 -                //bridge method body generation - this can be either a method call or a
   1.133 -                //new instance creation expression, depending on the member reference kind
   1.134 -                JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE)
   1.135 -                        ? bridgeExpressionInvoke(makeReceiver(rcvr))
   1.136 -                        : bridgeExpressionNew();
   1.137 -
   1.138 -                //the body is either a return expression containing a method call,
   1.139 -                //or the method call itself, depending on whether the return type of
   1.140 -                //the bridge is non-void/void.
   1.141 -                bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl);
   1.142 -
   1.143 -                return bridgeDecl;
   1.144 +                JCLambda slam = make.Lambda(params.toList(), expr);
   1.145 +                slam.targets = tree.targets;
   1.146 +                slam.type = tree.type;
   1.147 +                slam.pos = tree.pos;
   1.148 +                return slam;
   1.149              } finally {
   1.150                  make.at(prevPos);
   1.151              }
   1.152          }
   1.153 -        //where
   1.154 -            private JCExpression makeReceiver(VarSymbol rcvr) {
   1.155 -                if (rcvr == null) return null;
   1.156 -                JCExpression rcvrExpr = make.Ident(rcvr);
   1.157 -                Type rcvrType = tree.sym.enclClass().type;
   1.158 -                if (rcvrType == syms.arrayClass.type) {
   1.159 -                    // Map the receiver type to the actually type, not just "array"
   1.160 -                    rcvrType = tree.getQualifierExpression().type;
   1.161 -                }
   1.162 -                if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
   1.163 -                    rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
   1.164 -                }
   1.165 -                return rcvrExpr;
   1.166 +
   1.167 +        JCExpression getReceiverExpression() {
   1.168 +            return receiverExpression;
   1.169 +        }
   1.170 +
   1.171 +        private JCExpression makeReceiver(VarSymbol rcvr) {
   1.172 +            if (rcvr == null) return null;
   1.173 +            JCExpression rcvrExpr = make.Ident(rcvr);
   1.174 +            Type rcvrType = tree.sym.enclClass().type;
   1.175 +            if (rcvrType == syms.arrayClass.type) {
   1.176 +                // Map the receiver type to the actually type, not just "array"
   1.177 +                rcvrType = tree.getQualifierExpression().type;
   1.178              }
   1.179 +            if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
   1.180 +                rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
   1.181 +            }
   1.182 +            return rcvrExpr;
   1.183 +        }
   1.184  
   1.185          /**
   1.186 -         * determine the receiver of the bridged method call - the receiver can
   1.187 -         * be either the synthetic receiver parameter or a type qualifier; the
   1.188 -         * original qualifier expression is never used here, as it might refer
   1.189 -         * to symbols not available in the static context of the bridge
   1.190 +         * determine the receiver of the method call - the receiver can
   1.191 +         * be a type qualifier, the synthetic receiver parameter or 'super'.
   1.192           */
   1.193 -        private JCExpression bridgeExpressionInvoke(JCExpression rcvr) {
   1.194 +        private JCExpression expressionInvoke(VarSymbol rcvr) {
   1.195              JCExpression qualifier =
   1.196                      tree.sym.isStatic() ?
   1.197                          make.Type(tree.sym.owner.type) :
   1.198                          (rcvr != null) ?
   1.199 -                            rcvr :
   1.200 +                            makeReceiver(rcvr) :
   1.201                              tree.getQualifierExpression();
   1.202  
   1.203              //create the qualifier expression
   1.204 @@ -886,10 +864,9 @@
   1.205          }
   1.206  
   1.207          /**
   1.208 -         * the enclosing expression is either 'null' (no enclosing type) or set
   1.209 -         * to the first bridge synthetic parameter
   1.210 +         * Lambda body to use for a 'new'.
   1.211           */
   1.212 -        private JCExpression bridgeExpressionNew() {
   1.213 +        private JCExpression expressionNew() {
   1.214              if (tree.kind == ReferenceKind.ARRAY_CTOR) {
   1.215                  //create the array creation expression
   1.216                  JCNewArray newArr = make.NewArray(
   1.217 @@ -899,15 +876,10 @@
   1.218                  newArr.type = tree.getQualifierExpression().type;
   1.219                  return newArr;
   1.220              } else {
   1.221 -                JCExpression encl = null;
   1.222 -                switch (tree.kind) {
   1.223 -                    case UNBOUND:
   1.224 -                    case IMPLICIT_INNER:
   1.225 -                        encl = make.Ident(params.first());
   1.226 -                }
   1.227 -
   1.228                  //create the instance creation expression
   1.229 -                JCNewClass newClass = make.NewClass(encl,
   1.230 +                //note that method reference syntax does not allow an explicit
   1.231 +                //enclosing class (so the enclosing class is null)
   1.232 +                JCNewClass newClass = make.NewClass(null,
   1.233                          List.<JCExpression>nil(),
   1.234                          make.Type(tree.getQualifierExpression().type),
   1.235                          convertArgs(tree.sym, args.toList(), tree.varargsElement),
   1.236 @@ -921,7 +893,8 @@
   1.237          }
   1.238  
   1.239          private VarSymbol addParameter(String name, Type p, boolean genArg) {
   1.240 -            VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
   1.241 +            VarSymbol vsym = new VarSymbol(PARAMETER | SYNTHETIC, names.fromString(name), p, owner);
   1.242 +            vsym.pos = tree.pos;
   1.243              params.append(make.VarDef(vsym, null));
   1.244              if (genArg) {
   1.245                  args.append(make.Ident(vsym));
   1.246 @@ -930,15 +903,6 @@
   1.247          }
   1.248      }
   1.249  
   1.250 -    /**
   1.251 -     * Bridges a member reference - this is needed when:
   1.252 -     * * Var args in the referenced method need to be flattened away
   1.253 -     * * super is used
   1.254 -     */
   1.255 -    private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) {
   1.256 -        kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge());
   1.257 -    }
   1.258 -
   1.259      private MethodType typeToMethodType(Type mt) {
   1.260          Type type = types.erasure(mt);
   1.261          return new MethodType(type.getParameterTypes(),
   1.262 @@ -1258,9 +1222,25 @@
   1.263  
   1.264          @Override
   1.265          public void visitLambda(JCLambda tree) {
   1.266 +            analyzeLambda(tree, "lambda.stat");
   1.267 +        }
   1.268 +
   1.269 +        private void analyzeLambda(JCLambda tree, JCExpression methodReferenceReceiver) {
   1.270 +            // Translation of the receiver expression must occur first
   1.271 +            JCExpression rcvr = translate(methodReferenceReceiver);
   1.272 +            LambdaTranslationContext context = analyzeLambda(tree, "mref.stat.1");
   1.273 +            if (rcvr != null) {
   1.274 +                context.methodReferenceReceiver = rcvr;
   1.275 +            }
   1.276 +        }
   1.277 +
   1.278 +        private LambdaTranslationContext analyzeLambda(JCLambda tree, String statKey) {
   1.279              List<Frame> prevStack = frameStack;
   1.280              try {
   1.281 -                LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree);
   1.282 +                LambdaTranslationContext context = new LambdaTranslationContext(tree);
   1.283 +                if (dumpLambdaToMethodStats) {
   1.284 +                    log.note(tree, statKey, context.needsAltMetafactory(), context.translatedSym);
   1.285 +                }
   1.286                  frameStack = frameStack.prepend(new Frame(tree));
   1.287                  for (JCVariableDecl param : tree.params) {
   1.288                      context.addSymbol(param.sym, PARAM);
   1.289 @@ -1269,6 +1249,7 @@
   1.290                  contextMap.put(tree, context);
   1.291                  super.visitLambda(tree);
   1.292                  context.complete();
   1.293 +                return context;
   1.294              }
   1.295              finally {
   1.296                  frameStack = prevStack;
   1.297 @@ -1357,47 +1338,24 @@
   1.298           * information added in the LambdaToMethod pass will have the wrong
   1.299           * signature. Hooks between Lower and LambdaToMethod have been added to
   1.300           * handle normal "new" in this case. This visitor converts potentially
   1.301 -         * effected method references into a lambda containing a normal "new" of
   1.302 -         * the class.
   1.303 +         * affected method references into a lambda containing a normal
   1.304 +         * expression.
   1.305           *
   1.306           * @param tree
   1.307           */
   1.308          @Override
   1.309          public void visitReference(JCMemberReference tree) {
   1.310 -            if (tree.getMode() == ReferenceMode.NEW
   1.311 -                    && tree.kind != ReferenceKind.ARRAY_CTOR
   1.312 -                    && tree.sym.owner.isLocal()) {
   1.313 -                MethodSymbol consSym = (MethodSymbol) tree.sym;
   1.314 -                List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
   1.315 -                Type classType = consSym.owner.type;
   1.316 -
   1.317 -                // Build lambda parameters
   1.318 -                // partially cloned from TreeMaker.Params until 8014021 is fixed
   1.319 -                Symbol owner = owner();
   1.320 -                ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>();
   1.321 -                int i = 0;
   1.322 -                for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) {
   1.323 -                    JCVariableDecl param = make.Param(make.paramName(i++), l.head, owner);
   1.324 -                    param.sym.pos = tree.pos;
   1.325 -                    paramBuff.append(param);
   1.326 -                }
   1.327 -                List<JCVariableDecl> params = paramBuff.toList();
   1.328 -
   1.329 -                // Make new-class call
   1.330 -                JCNewClass nc = makeNewClass(classType, make.Idents(params));
   1.331 -                nc.pos = tree.pos;
   1.332 -
   1.333 -                // Make lambda holding the new-class call
   1.334 -                JCLambda slam = make.Lambda(params, nc);
   1.335 -                slam.targets = tree.targets;
   1.336 -                slam.type = tree.type;
   1.337 -                slam.pos = tree.pos;
   1.338 -
   1.339 -                // Now it is a lambda, process as such
   1.340 -                visitLambda(slam);
   1.341 +            ReferenceTranslationContext rcontext = new ReferenceTranslationContext(tree);
   1.342 +            contextMap.put(tree, rcontext);
   1.343 +            if (rcontext.needsConversionToLambda()) {
   1.344 +                 // Convert to a lambda, and process as such
   1.345 +                MemberReferenceToLambda conv = new MemberReferenceToLambda(tree, rcontext, owner());
   1.346 +                analyzeLambda(conv.lambda(), conv.getReceiverExpression());
   1.347              } else {
   1.348                  super.visitReference(tree);
   1.349 -                contextMap.put(tree, makeReferenceContext(tree));
   1.350 +                if (dumpLambdaToMethodStats) {
   1.351 +                    log.note(tree, "mref.stat", rcontext.needsAltMetafactory(), null);
   1.352 +                }
   1.353              }
   1.354          }
   1.355  
   1.356 @@ -1652,14 +1610,6 @@
   1.357              }
   1.358          }
   1.359  
   1.360 -        private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) {
   1.361 -            return new LambdaTranslationContext(tree);
   1.362 -        }
   1.363 -
   1.364 -        private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) {
   1.365 -            return new ReferenceTranslationContext(tree);
   1.366 -        }
   1.367 -
   1.368          private class Frame {
   1.369              final JCTree tree;
   1.370              List<Symbol> locals;
   1.371 @@ -1779,6 +1729,13 @@
   1.372               */
   1.373              final Set<Symbol> freeVarProcessedLocalClasses;
   1.374  
   1.375 +            /**
   1.376 +             * For method references converted to lambdas.  The method
   1.377 +             * reference receiver expression. Must be treated like a captured
   1.378 +             * variable.
   1.379 +             */
   1.380 +            JCExpression methodReferenceReceiver;
   1.381 +
   1.382              LambdaTranslationContext(JCLambda tree) {
   1.383                  super(tree);
   1.384                  Frame frame = frameStack.head;
   1.385 @@ -1798,9 +1755,6 @@
   1.386                  // This symbol will be filled-in in complete
   1.387                  this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass());
   1.388  
   1.389 -                if (dumpLambdaToMethodStats) {
   1.390 -                    log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym);
   1.391 -                }
   1.392                  translatedSymbols = new EnumMap<>(LambdaSymbolKind.class);
   1.393  
   1.394                  translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>());
   1.395 @@ -2017,6 +1971,13 @@
   1.396                  for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) {
   1.397                      params.append(make.VarDef((VarSymbol) thisSym, null));
   1.398                  }
   1.399 +                if (methodReferenceReceiver != null) {
   1.400 +                    params.append(make.VarDef(
   1.401 +                            make.Modifiers(PARAMETER|FINAL),
   1.402 +                            names.fromString("$rcvr$"),
   1.403 +                            make.Type(methodReferenceReceiver.type),
   1.404 +                            null));
   1.405 +                }
   1.406                  for (Symbol thisSym : getSymbolMap(PARAM).values()) {
   1.407                      params.append(make.VarDef((VarSymbol) thisSym, null));
   1.408                  }
   1.409 @@ -2044,40 +2005,27 @@
   1.410           * and the used by the main translation routines in order to adjust method
   1.411           * references (i.e. in case a bridge is needed)
   1.412           */
   1.413 -        private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
   1.414 +        private final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
   1.415  
   1.416              final boolean isSuper;
   1.417 -            final Symbol bridgeSym;
   1.418              final Symbol sigPolySym;
   1.419  
   1.420              ReferenceTranslationContext(JCMemberReference tree) {
   1.421                  super(tree);
   1.422                  this.isSuper = tree.hasKind(ReferenceKind.SUPER);
   1.423 -                this.bridgeSym = needsBridge()
   1.424 -                        ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC,
   1.425 -                                              referenceBridgeName(), null,
   1.426 -                                              owner.enclClass())
   1.427 -                        : null;
   1.428                  this.sigPolySym = isSignaturePolymorphic()
   1.429                          ? makePrivateSyntheticMethod(tree.sym.flags(),
   1.430                                                tree.sym.name,
   1.431                                                bridgedRefSig(),
   1.432                                                tree.sym.enclClass())
   1.433                          : null;
   1.434 -                if (dumpLambdaToMethodStats) {
   1.435 -                    String key = bridgeSym == null ?
   1.436 -                            "mref.stat" : "mref.stat.1";
   1.437 -                    log.note(tree, key, needsAltMetafactory(), bridgeSym);
   1.438 -                }
   1.439              }
   1.440  
   1.441              /**
   1.442               * Get the opcode associated with this method reference
   1.443               */
   1.444              int referenceKind() {
   1.445 -                return LambdaToMethod.this.referenceKind(needsBridge()
   1.446 -                        ? bridgeSym
   1.447 -                        : tree.sym);
   1.448 +                return LambdaToMethod.this.referenceKind(tree.sym);
   1.449              }
   1.450  
   1.451              boolean needsVarArgsConversion() {
   1.452 @@ -2085,62 +2033,6 @@
   1.453              }
   1.454  
   1.455              /**
   1.456 -             * Generate a disambiguating string to increase stability (important
   1.457 -             * if serialized)
   1.458 -             *
   1.459 -             * @return String to differentiate synthetic lambda method names
   1.460 -             */
   1.461 -            private String referenceBridgeDisambiguation() {
   1.462 -                StringBuilder buf = new StringBuilder();
   1.463 -                // Append the enclosing method signature to differentiate
   1.464 -                // overloaded enclosing methods.
   1.465 -                if (owner.type != null) {
   1.466 -                    buf.append(typeSig(owner.type));
   1.467 -                    buf.append(":");
   1.468 -                }
   1.469 -
   1.470 -                // Append qualifier type
   1.471 -                buf.append(classSig(tree.sym.owner.type));
   1.472 -
   1.473 -                // Note static/instance
   1.474 -                buf.append(tree.sym.isStatic()? " S " : " I ");
   1.475 -
   1.476 -                // Append referenced signature
   1.477 -                buf.append(typeSig(tree.sym.erasure(types)));
   1.478 -
   1.479 -                return buf.toString();
   1.480 -            }
   1.481 -
   1.482 -            /**
   1.483 -             * Construct a unique stable name for the method reference bridge
   1.484 -             *
   1.485 -             * @return Name to use for the synthetic method name
   1.486 -             */
   1.487 -            private Name referenceBridgeName() {
   1.488 -                StringBuilder buf = new StringBuilder();
   1.489 -                // Append lambda ID, this is semantically significant
   1.490 -                buf.append(names.lambda);
   1.491 -                // Note that it is a method reference bridge
   1.492 -                buf.append("MR$");
   1.493 -                // Append the enclosing method name
   1.494 -                buf.append(enclosingMethodName());
   1.495 -                buf.append('$');
   1.496 -                // Append the referenced method name
   1.497 -                buf.append(syntheticMethodNameComponent(tree.sym.name));
   1.498 -                buf.append('$');
   1.499 -                // Append a hash of the disambiguating string : enclosing method
   1.500 -                // signature, etc.
   1.501 -                String disam = referenceBridgeDisambiguation();
   1.502 -                buf.append(Integer.toHexString(disam.hashCode()));
   1.503 -                buf.append('$');
   1.504 -                // The above appended name components may not be unique, append
   1.505 -                // a count based on the above name components.
   1.506 -                buf.append(syntheticMethodNameCounts.getIndex(buf));
   1.507 -                String result = buf.toString();
   1.508 -                return names.fromString(result);
   1.509 -            }
   1.510 -
   1.511 -            /**
   1.512               * @return Is this an array operation like clone()
   1.513               */
   1.514              boolean isArrayOp() {
   1.515 @@ -2175,13 +2067,16 @@
   1.516              }
   1.517  
   1.518              /**
   1.519 -             * Does this reference needs a bridge (i.e. var args need to be
   1.520 -             * expanded or "super" is used)
   1.521 +             * Does this reference need to be converted to a lambda
   1.522 +             * (i.e. var args need to be expanded or "super" is used)
   1.523               */
   1.524 -            final boolean needsBridge() {
   1.525 +            final boolean needsConversionToLambda() {
   1.526                  return isSuper || needsVarArgsConversion() || isArrayOp() ||
   1.527                          isPrivateInOtherClass() ||
   1.528 -                        !receiverAccessible();
   1.529 +                        !receiverAccessible() ||
   1.530 +                        (tree.getMode() == ReferenceMode.NEW &&
   1.531 +                          tree.kind != ReferenceKind.ARRAY_CTOR &&
   1.532 +                          (tree.sym.owner.isLocal() || tree.sym.owner.isInner()));
   1.533              }
   1.534  
   1.535              Type generatedRefSig() {

mercurial