langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
author rfield
Tue, 14 May 2013 11:11:09 -0700
changeset 17575 7693e6ff0d7d
parent 17550 567df1379253
child 17578 46ac954e4a84
permissions -rw-r--r--
8012556: Implement lambda methods on interfaces as static 8006140: Javac NPE compiling Lambda expression on initialization expression of static field in interface Summary: Lambdas occurring in static contexts or those not needing instance information should be generated into static methods. This has long been the case for classes. However, as a work-around to the lack of support for statics on interfaces, interface lambda methods have been generated into default methods. For lambdas in interface static contexts (fields and static methods) this causes an NPE in javac because there is no 'this'. MethodHandles now support static methods on interfaces. This changeset allows lambda methods to be generated as static interface methods. An existing bug in Hotspot (8013875) is exposed in a test when the "-esa" flag is used. This test and another test that already exposed this bug have been marked with @ignore. Reviewed-by: mcimadamore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     1
/*
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     4
 *
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    10
 *
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    15
 * accompanied this code).
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    16
 *
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    20
 *
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    23
 * questions.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    24
 */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    25
package com.sun.tools.javac.comp;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    26
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    27
import com.sun.tools.javac.tree.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    28
import com.sun.tools.javac.tree.JCTree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    29
import com.sun.tools.javac.tree.JCTree.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    30
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    31
import com.sun.tools.javac.tree.TreeMaker;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    32
import com.sun.tools.javac.tree.TreeScanner;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    33
import com.sun.tools.javac.tree.TreeTranslator;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    34
import com.sun.tools.javac.code.Kinds;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    35
import com.sun.tools.javac.code.Scope;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    36
import com.sun.tools.javac.code.Symbol;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    37
import com.sun.tools.javac.code.Symbol.ClassSymbol;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    38
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    39
import com.sun.tools.javac.code.Symbol.MethodSymbol;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    40
import com.sun.tools.javac.code.Symbol.VarSymbol;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    41
import com.sun.tools.javac.code.Symtab;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    42
import com.sun.tools.javac.code.Type;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    43
import com.sun.tools.javac.code.Type.MethodType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    44
import com.sun.tools.javac.code.Types;
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
    45
import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
    46
import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    47
import com.sun.tools.javac.jvm.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    48
import com.sun.tools.javac.util.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    49
import com.sun.tools.javac.util.List;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    50
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    51
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    52
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    53
import java.util.HashMap;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    54
import java.util.LinkedHashMap;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    55
import java.util.Map;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    56
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    57
import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    58
import static com.sun.tools.javac.code.Flags.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    59
import static com.sun.tools.javac.code.Kinds.*;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    60
import static com.sun.tools.javac.code.TypeTag.*;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    61
import static com.sun.tools.javac.tree.JCTree.Tag.*;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    62
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    63
/**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    64
 * This pass desugars lambda expressions into static methods
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    65
 *
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    66
 *  <p><b>This is NOT part of any supported API.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    67
 *  If you write code that depends on this, you do so at your own risk.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    68
 *  This code and its internal interfaces are subject to change or
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    69
 *  deletion without notice.</b>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    70
 */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    71
public class LambdaToMethod extends TreeTranslator {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    72
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
    73
    private Lower lower;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    74
    private Names names;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    75
    private Symtab syms;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    76
    private Resolve rs;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    77
    private TreeMaker make;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    78
    private Types types;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    79
    private TransTypes transTypes;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    80
    private Env<AttrContext> attrEnv;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    81
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    82
    /** the analyzer scanner */
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
    83
    private LambdaAnalyzerPreprocessor analyzer;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    84
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    85
    /** map from lambda trees to translation contexts */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    86
    private Map<JCTree, TranslationContext<?>> contextMap;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    87
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    88
    /** current translation context (visitor argument) */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    89
    private TranslationContext<?> context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
    90
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    91
    /** info about the current class being processed */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    92
    private KlassInfo kInfo;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    93
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    94
    /** Flag for alternate metafactories indicating the lambda object is intended to be serializable */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    95
    public static final int FLAG_SERIALIZABLE = 1 << 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    96
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    97
    /** Flag for alternate metafactories indicating the lambda object has multiple targets */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    98
    public static final int FLAG_MARKERS = 1 << 1;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
    99
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   100
    private class KlassInfo {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   101
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   102
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   103
         * list of methods to append
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   104
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   105
        private ListBuffer<JCTree> appendedMethodList;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   106
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   107
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   108
         * list of deserialization cases
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   109
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   110
        private final Map<String, ListBuffer<JCStatement>> deserializeCases;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   111
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   112
       /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   113
         * deserialize method symbol
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   114
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   115
        private final MethodSymbol deserMethodSym;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   116
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   117
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   118
         * deserialize method parameter symbol
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   119
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   120
        private final VarSymbol deserParamSym;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   121
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   122
        private KlassInfo(Symbol kSym) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   123
            appendedMethodList = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   124
            deserializeCases = new HashMap<String, ListBuffer<JCStatement>>();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   125
            long flags = PRIVATE | STATIC | SYNTHETIC;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   126
            MethodType type = new MethodType(List.of(syms.serializedLambdaType), syms.objectType,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   127
                    List.<Type>nil(), syms.methodClass);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   128
            deserMethodSym = makeSyntheticMethod(flags, names.deserializeLambda, type, kSym);
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   129
            deserParamSym = new VarSymbol(FINAL, names.fromString("lambda"),
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   130
                    syms.serializedLambdaType, deserMethodSym);
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   131
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   132
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   133
        private void addMethod(JCTree decl) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   134
            appendedMethodList = appendedMethodList.prepend(decl);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   135
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   136
    }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   137
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   138
    // <editor-fold defaultstate="collapsed" desc="Instantiating">
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   139
    private static final Context.Key<LambdaToMethod> unlambdaKey =
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   140
            new Context.Key<LambdaToMethod>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   141
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   142
    public static LambdaToMethod instance(Context context) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   143
        LambdaToMethod instance = context.get(unlambdaKey);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   144
        if (instance == null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   145
            instance = new LambdaToMethod(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   146
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   147
        return instance;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   148
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   149
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   150
    private LambdaToMethod(Context context) {
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
   151
        lower = Lower.instance(context);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   152
        names = Names.instance(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   153
        syms = Symtab.instance(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   154
        rs = Resolve.instance(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   155
        make = TreeMaker.instance(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   156
        types = Types.instance(context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   157
        transTypes = TransTypes.instance(context);
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   158
        analyzer = new LambdaAnalyzerPreprocessor();
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   159
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   160
    // </editor-fold>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   161
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   162
    // <editor-fold defaultstate="collapsed" desc="translate methods">
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   163
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   164
    public <T extends JCTree> T translate(T tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   165
        TranslationContext<?> newContext = contextMap.get(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   166
        return translate(tree, newContext != null ? newContext : context);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   167
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   168
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   169
    public <T extends JCTree> T translate(T tree, TranslationContext<?> newContext) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   170
        TranslationContext<?> prevContext = context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   171
        try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   172
            context = newContext;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   173
            return super.translate(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   174
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   175
        finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   176
            context = prevContext;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   177
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   178
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   179
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   180
    public <T extends JCTree> List<T> translate(List<T> trees, TranslationContext<?> newContext) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   181
        ListBuffer<T> buf = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   182
        for (T tree : trees) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   183
            buf.append(translate(tree, newContext));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   184
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   185
        return buf.toList();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   186
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   187
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   188
    public JCTree translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   189
        this.make = make;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   190
        this.attrEnv = env;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   191
        this.context = null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   192
        this.contextMap = new HashMap<JCTree, TranslationContext<?>>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   193
        return translate(cdef);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   194
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   195
    // </editor-fold>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   196
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   197
    // <editor-fold defaultstate="collapsed" desc="visitor methods">
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   198
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   199
     * Visit a class.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   200
     * Maintain the translatedMethodList across nested classes.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   201
     * Append the translatedMethodList to the class after it is translated.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   202
     * @param tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   203
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   204
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   205
    public void visitClassDef(JCClassDecl tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   206
        if (tree.sym.owner.kind == PCK) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   207
            //analyze class
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   208
            tree = analyzer.analyzeAndPreprocessClass(tree);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   209
        }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   210
        KlassInfo prevKlassInfo = kInfo;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   211
        try {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   212
            kInfo = new KlassInfo(tree.sym);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   213
            super.visitClassDef(tree);
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   214
            if (!kInfo.deserializeCases.isEmpty()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   215
                kInfo.addMethod(makeDeserializeMethod(tree.sym));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   216
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   217
            //add all translated instance methods here
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   218
            List<JCTree> newMethods = kInfo.appendedMethodList.toList();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   219
            tree.defs = tree.defs.appendList(newMethods);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   220
            for (JCTree lambda : newMethods) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   221
                tree.sym.members().enter(((JCMethodDecl)lambda).sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   222
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   223
            result = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   224
        } finally {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   225
            kInfo = prevKlassInfo;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   226
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   227
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   228
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   229
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   230
     * Translate a lambda into a method to be inserted into the class.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   231
     * Then replace the lambda site with an invokedynamic call of to lambda
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   232
     * meta-factory, which will use the lambda method.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   233
     * @param tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   234
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   235
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   236
    public void visitLambda(JCLambda tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   237
        LambdaTranslationContext localContext = (LambdaTranslationContext)context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   238
        MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   239
        MethodType lambdaType = (MethodType) sym.type;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   240
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   241
        //create the method declaration hoisting the lambda body
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   242
        JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   243
                sym.name,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   244
                make.QualIdent(lambdaType.getReturnType().tsym),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   245
                List.<JCTypeParameter>nil(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   246
                localContext.syntheticParams,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   247
                lambdaType.getThrownTypes() == null ?
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   248
                    List.<JCExpression>nil() :
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   249
                    make.Types(lambdaType.getThrownTypes()),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   250
                null,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   251
                null);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   252
        lambdaDecl.sym = sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   253
        lambdaDecl.type = lambdaType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   254
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   255
        //translate lambda body
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   256
        //As the lambda body is translated, all references to lambda locals,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   257
        //captured variables, enclosing members are adjusted accordingly
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   258
        //to refer to the static method parameters (rather than i.e. acessing to
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   259
        //captured members directly).
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   260
        lambdaDecl.body = translate(makeLambdaBody(tree, lambdaDecl));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   261
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   262
        //Add the method to the list of methods to be added to this class.
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   263
        kInfo.addMethod(lambdaDecl);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   264
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   265
        //now that we have generated a method for the lambda expression,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   266
        //we can translate the lambda into a method reference pointing to the newly
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   267
        //created method.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   268
        //
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   269
        //Note that we need to adjust the method handle so that it will match the
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   270
        //signature of the SAM descriptor - this means that the method reference
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   271
        //should be added the following synthetic arguments:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   272
        //
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   273
        // * the "this" argument if it is an instance method
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   274
        // * enclosing locals captured by the lambda expression
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   275
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   276
        ListBuffer<JCExpression> syntheticInits = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   277
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   278
        if (!sym.isStatic()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   279
            syntheticInits.append(makeThis(
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   280
                    sym.owner.enclClass().asType(),
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   281
                    localContext.owner.enclClass()));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   282
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   283
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   284
        //add captured locals
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   285
        for (Symbol fv : localContext.getSymbolMap(CAPTURED_VAR).keySet()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   286
            if (fv != localContext.self) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   287
                JCTree captured_local = make.Ident(fv).setType(fv.type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   288
                syntheticInits.append((JCExpression) captured_local);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   289
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   290
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   291
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   292
        //then, determine the arguments to the indy call
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   293
        List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   294
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   295
        //build a sam instance using an indy call to the meta-factory
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   296
        int refKind = referenceKind(sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   297
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   298
        //convert to an invokedynamic call
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   299
        result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   300
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   301
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   302
    private JCIdent makeThis(Type type, Symbol owner) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   303
        VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   304
                names._this,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   305
                type,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   306
                owner);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   307
        return make.Ident(_this);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   308
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   309
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   310
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   311
     * Translate a method reference into an invokedynamic call to the
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   312
     * meta-factory.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   313
     * @param tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   314
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   315
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   316
    public void visitReference(JCMemberReference tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   317
        ReferenceTranslationContext localContext = (ReferenceTranslationContext)context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   318
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   319
        //first determine the method symbol to be used to generate the sam instance
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   320
        //this is either the method reference symbol, or the bridged reference symbol
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   321
        Symbol refSym = localContext.needsBridge() ?
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   322
            localContext.bridgeSym :
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   323
            tree.sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   324
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   325
        //build the bridge method, if needed
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   326
        if (localContext.needsBridge()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   327
            bridgeMemberReference(tree, localContext);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   328
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   329
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   330
        //the qualifying expression is treated as a special captured arg
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   331
        JCExpression init;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   332
        switch(tree.kind) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   333
14724
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   334
            case IMPLICIT_INNER:    /** Inner :: new */
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   335
            case SUPER:             /** super :: instMethod */
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   336
                init = makeThis(
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   337
                    localContext.owner.enclClass().asType(),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   338
                    localContext.owner.enclClass());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   339
                break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   340
14724
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   341
            case BOUND:             /** Expr :: instMethod */
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   342
                init = tree.getQualifierExpression();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   343
                break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   344
14724
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   345
            case UNBOUND:           /** Type :: instMethod */
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   346
            case STATIC:            /** Type :: staticMethod */
b542db73539a 8004101: Add checks for method reference well-formedness
mcimadamore
parents: 14537
diff changeset
   347
            case TOPLEVEL:          /** Top level :: new */
15360
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   348
            case ARRAY_CTOR:        /** ArrayType :: new */
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   349
                init = null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   350
                break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   351
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   352
            default:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   353
                throw new InternalError("Should not have an invalid kind");
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   354
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   355
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   356
        List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   357
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   358
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   359
        //build a sam instance using an indy call to the meta-factory
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   360
        result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   361
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   362
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   363
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   364
     * Translate identifiers within a lambda to the mapped identifier
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   365
     * @param tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   366
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   367
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   368
    public void visitIdent(JCIdent tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   369
        if (context == null || !analyzer.lambdaIdentSymbolFilter(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   370
            super.visitIdent(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   371
        } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   372
            LambdaTranslationContext lambdaContext = (LambdaTranslationContext) context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   373
            if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   374
                Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   375
                result = make.Ident(translatedSym).setType(tree.type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   376
            } else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   377
                Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   378
                result = make.Ident(translatedSym).setType(tree.type);
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   379
            } else if (lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   380
                Symbol translatedSym = lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   381
                result = make.Ident(translatedSym).setType(translatedSym.type);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   382
            } else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   383
                Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   384
                result = make.Ident(translatedSym).setType(tree.type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   385
            } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   386
                //access to untranslated symbols (i.e. compile-time constants,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   387
                //members defined inside the lambda body, etc.) )
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   388
                super.visitIdent(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   389
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   390
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   391
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   392
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   393
    @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   394
    public void visitVarDef(JCVariableDecl tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   395
        LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   396
        if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   397
            JCExpression init = translate(tree.init);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   398
            result = make.VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init);
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   399
        } else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   400
            JCExpression init = translate(tree.init);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   401
            VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   402
            result = make.VarDef(xsym, init);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   403
            // Replace the entered symbol for this variable
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   404
            Scope sc = tree.sym.owner.members();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   405
            if (sc != null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   406
                sc.remove(tree.sym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   407
                sc.enter(xsym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   408
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   409
        } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   410
            super.visitVarDef(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   411
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   412
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   413
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   414
    // </editor-fold>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   415
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   416
    // <editor-fold defaultstate="collapsed" desc="Translation helper methods">
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   417
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   418
    private JCBlock makeLambdaBody(JCLambda tree, JCMethodDecl lambdaMethodDecl) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   419
        return tree.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   420
                makeLambdaExpressionBody((JCExpression)tree.body, lambdaMethodDecl) :
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   421
                makeLambdaStatementBody((JCBlock)tree.body, lambdaMethodDecl, tree.canCompleteNormally);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   422
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   423
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   424
    private JCBlock makeLambdaExpressionBody(JCExpression expr, JCMethodDecl lambdaMethodDecl) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   425
        Type restype = lambdaMethodDecl.type.getReturnType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   426
        boolean isLambda_void = expr.type.hasTag(VOID);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   427
        boolean isTarget_void = restype.hasTag(VOID);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   428
        boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   429
        if (isTarget_void) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   430
            //target is void:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   431
            // BODY;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   432
            JCStatement stat = make.Exec(expr);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   433
            return make.Block(0, List.<JCStatement>of(stat));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   434
        } else if (isLambda_void && isTarget_Void) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   435
            //void to Void conversion:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   436
            // BODY; return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   437
            ListBuffer<JCStatement> stats = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   438
            stats.append(make.Exec(expr));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   439
            stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType)));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   440
            return make.Block(0, stats.toList());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   441
        } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   442
            //non-void to non-void conversion:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   443
            // return (TYPE)BODY;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   444
            JCExpression retExpr = transTypes.coerce(attrEnv, expr, restype);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   445
            return make.Block(0, List.<JCStatement>of(make.Return(retExpr)));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   446
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   447
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   448
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   449
    private JCBlock makeLambdaStatementBody(JCBlock block, final JCMethodDecl lambdaMethodDecl, boolean completeNormally) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   450
        final Type restype = lambdaMethodDecl.type.getReturnType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   451
        final boolean isTarget_void = restype.hasTag(VOID);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   452
        boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   453
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   454
        class LambdaBodyTranslator extends TreeTranslator {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   455
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   456
            @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   457
            public void visitClassDef(JCClassDecl tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   458
                //do NOT recurse on any inner classes
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   459
                result = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   460
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   461
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   462
            @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   463
            public void visitLambda(JCLambda tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   464
                //do NOT recurse on any nested lambdas
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   465
                result = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   466
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   467
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   468
            @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   469
            public void visitReturn(JCReturn tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   470
                boolean isLambda_void = tree.expr == null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   471
                if (isTarget_void && !isLambda_void) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   472
                    //Void to void conversion:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   473
                    // { TYPE $loc = RET-EXPR; return; }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   474
                    VarSymbol loc = makeSyntheticVar(0, names.fromString("$loc"), tree.expr.type, lambdaMethodDecl.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   475
                    JCVariableDecl varDef = make.VarDef(loc, tree.expr);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   476
                    result = make.Block(0, List.<JCStatement>of(varDef, make.Return(null)));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   477
                } else if (!isTarget_void || !isLambda_void) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   478
                    //non-void to non-void conversion:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   479
                    // return (TYPE)RET-EXPR;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   480
                    tree.expr = transTypes.coerce(attrEnv, tree.expr, restype);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   481
                    result = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   482
                } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   483
                    result = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   484
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   485
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   486
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   487
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   488
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   489
        JCBlock trans_block = new LambdaBodyTranslator().translate(block);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   490
        if (completeNormally && isTarget_Void) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   491
            //there's no return statement and the lambda (possibly inferred)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   492
            //return type is java.lang.Void; emit a synthetic return statement
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   493
            trans_block.stats = trans_block.stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType)));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   494
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   495
        return trans_block;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   496
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   497
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   498
    private JCMethodDecl makeDeserializeMethod(Symbol kSym) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   499
        ListBuffer<JCCase> cases = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   500
        ListBuffer<JCBreak> breaks = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   501
        for (Map.Entry<String, ListBuffer<JCStatement>> entry : kInfo.deserializeCases.entrySet()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   502
            JCBreak br = make.Break(null);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   503
            breaks.add(br);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   504
            List<JCStatement> stmts = entry.getValue().append(br).toList();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   505
            cases.add(make.Case(make.Literal(entry.getKey()), stmts));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   506
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   507
        JCSwitch sw = make.Switch(deserGetter("getImplMethodName", syms.stringType), cases.toList());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   508
        for (JCBreak br : breaks) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   509
            br.target = sw;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   510
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   511
        JCBlock body = make.Block(0L, List.<JCStatement>of(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   512
                sw,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   513
                make.Throw(makeNewClass(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   514
                    syms.illegalArgumentExceptionType,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   515
                    List.<JCExpression>of(make.Literal("Invalid lambda deserialization"))))));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   516
        JCMethodDecl deser = make.MethodDef(make.Modifiers(kInfo.deserMethodSym.flags()),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   517
                        names.deserializeLambda,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   518
                        make.QualIdent(kInfo.deserMethodSym.getReturnType().tsym),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   519
                        List.<JCTypeParameter>nil(),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   520
                        List.of(make.VarDef(kInfo.deserParamSym, null)),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   521
                        List.<JCExpression>nil(),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   522
                        body,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   523
                        null);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   524
        deser.sym = kInfo.deserMethodSym;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   525
        deser.type = kInfo.deserMethodSym.type;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   526
        //System.err.printf("DESER: '%s'\n", deser);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   527
        return deser;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   528
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   529
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   530
    /** Make an attributed class instance creation expression.
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   531
     *  @param ctype    The class type.
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   532
     *  @param args     The constructor arguments.
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   533
     *  @param cons     The constructor symbol
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   534
     */
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   535
    JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   536
        JCNewClass tree = make.NewClass(null,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   537
            null, make.QualIdent(ctype.tsym), args, null);
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   538
        tree.constructor = cons;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   539
        tree.type = ctype;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   540
        return tree;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   541
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   542
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   543
    /** Make an attributed class instance creation expression.
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   544
     *  @param ctype    The class type.
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   545
     *  @param args     The constructor arguments.
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   546
     */
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   547
    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   548
        return makeNewClass(ctype, args,
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   549
                rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()));
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   550
     }
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
   551
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   552
    private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   553
            DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   554
        String functionalInterfaceClass = classSig(targetType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   555
        String functionalInterfaceMethodName = samSym.getSimpleName().toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   556
        String functionalInterfaceMethodSignature = methodSig(types.erasure(samSym.type));
16335
4f7fe060522f 8009582: Method reference generic constructor gives: IllegalArgumentException: Invalid lambda deserialization
rfield
parents: 16332
diff changeset
   557
        String implClass = classSig(types.erasure(refSym.owner.type));
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   558
        String implMethodName = refSym.getQualifiedName().toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   559
        String implMethodSignature = methodSig(types.erasure(refSym.type));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   560
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   561
        JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   562
        ListBuffer<JCExpression> serArgs = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   563
        int i = 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   564
        for (Type t : indyType.getParameterTypes()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   565
            List<JCExpression> indexAsArg = ListBuffer.<JCExpression>lb().append(make.Literal(i)).toList();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   566
            List<Type> argTypes = ListBuffer.<Type>lb().append(syms.intType).toList();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   567
            serArgs.add(make.TypeCast(types.erasure(t), deserGetter("getCapturedArg", syms.objectType, argTypes, indexAsArg)));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   568
            ++i;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   569
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   570
        JCStatement stmt = make.If(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   571
                deserTest(deserTest(deserTest(deserTest(deserTest(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   572
                    kindTest,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   573
                    "getFunctionalInterfaceClass", functionalInterfaceClass),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   574
                    "getFunctionalInterfaceMethodName", functionalInterfaceMethodName),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   575
                    "getFunctionalInterfaceMethodSignature", functionalInterfaceMethodSignature),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   576
                    "getImplClass", implClass),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   577
                    "getImplMethodSignature", implMethodSignature),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   578
                make.Return(makeIndyCall(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   579
                    pos,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   580
                    syms.lambdaMetafactory,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   581
                    names.altMetaFactory,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   582
                    staticArgs, indyType, serArgs.toList())),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   583
                null);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   584
        ListBuffer<JCStatement> stmts = kInfo.deserializeCases.get(implMethodName);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   585
        if (stmts == null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   586
            stmts = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   587
            kInfo.deserializeCases.put(implMethodName, stmts);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   588
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   589
        /****
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   590
        System.err.printf("+++++++++++++++++\n");
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   591
        System.err.printf("*functionalInterfaceClass: '%s'\n", functionalInterfaceClass);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   592
        System.err.printf("*functionalInterfaceMethodName: '%s'\n", functionalInterfaceMethodName);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   593
        System.err.printf("*functionalInterfaceMethodSignature: '%s'\n", functionalInterfaceMethodSignature);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   594
        System.err.printf("*implMethodKind: %d\n", implMethodKind);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   595
        System.err.printf("*implClass: '%s'\n", implClass);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   596
        System.err.printf("*implMethodName: '%s'\n", implMethodName);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   597
        System.err.printf("*implMethodSignature: '%s'\n", implMethodSignature);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   598
        ****/
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   599
        stmts.append(stmt);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   600
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   601
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   602
    private JCExpression eqTest(Type argType, JCExpression arg1, JCExpression arg2) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   603
        JCBinary testExpr = make.Binary(JCTree.Tag.EQ, arg1, arg2);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   604
        testExpr.operator = rs.resolveBinaryOperator(null, JCTree.Tag.EQ, attrEnv, argType, argType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   605
        testExpr.setType(syms.booleanType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   606
        return testExpr;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   607
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   608
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   609
    private JCExpression deserTest(JCExpression prev, String func, String lit) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   610
        MethodType eqmt = new MethodType(List.of(syms.objectType), syms.booleanType, List.<Type>nil(), syms.methodClass);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   611
        Symbol eqsym = rs.resolveQualifiedMethod(null, attrEnv, syms.objectType, names.equals, List.of(syms.objectType), List.<Type>nil());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   612
        JCMethodInvocation eqtest = make.Apply(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   613
                List.<JCExpression>nil(),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   614
                make.Select(deserGetter(func, syms.stringType), eqsym).setType(eqmt),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   615
                List.<JCExpression>of(make.Literal(lit)));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   616
        eqtest.setType(syms.booleanType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   617
        JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   618
        compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   619
        compound.setType(syms.booleanType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   620
        return compound;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   621
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   622
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   623
    private JCExpression deserGetter(String func, Type type) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   624
        return deserGetter(func, type, List.<Type>nil(), List.<JCExpression>nil());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   625
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   626
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   627
    private JCExpression deserGetter(String func, Type type, List<Type> argTypes, List<JCExpression> args) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   628
        MethodType getmt = new MethodType(argTypes, type, List.<Type>nil(), syms.methodClass);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   629
        Symbol getsym = rs.resolveQualifiedMethod(null, attrEnv, syms.serializedLambdaType, names.fromString(func), argTypes, List.<Type>nil());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   630
        return make.Apply(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   631
                    List.<JCExpression>nil(),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   632
                    make.Select(make.Ident(kInfo.deserParamSym).setType(syms.serializedLambdaType), getsym).setType(getmt),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   633
                    args).setType(type);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   634
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   635
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   636
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   637
     * Create new synthetic method with given flags, name, type, owner
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   638
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   639
    private MethodSymbol makeSyntheticMethod(long flags, Name name, Type type, Symbol owner) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   640
        return new MethodSymbol(flags | SYNTHETIC, name, type, owner);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   641
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   642
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   643
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   644
     * Create new synthetic variable with given flags, name, type, owner
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   645
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   646
    private VarSymbol makeSyntheticVar(long flags, String name, Type type, Symbol owner) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   647
        return makeSyntheticVar(flags, names.fromString(name), type, owner);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   648
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   649
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   650
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   651
     * Create new synthetic variable with given flags, name, type, owner
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   652
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   653
    private VarSymbol makeSyntheticVar(long flags, Name name, Type type, Symbol owner) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   654
        return new VarSymbol(flags | SYNTHETIC, name, type, owner);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   655
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   656
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   657
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   658
     * Set varargsElement field on a given tree (must be either a new class tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   659
     * or a method call tree)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   660
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   661
    private void setVarargsIfNeeded(JCTree tree, Type varargsElement) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   662
        if (varargsElement != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   663
            switch (tree.getTag()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   664
                case APPLY: ((JCMethodInvocation)tree).varargsElement = varargsElement; break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   665
                case NEWCLASS: ((JCNewClass)tree).varargsElement = varargsElement; break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   666
                default: throw new AssertionError();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   667
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   668
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   669
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   670
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   671
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   672
     * Convert method/constructor arguments by inserting appropriate cast
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   673
     * as required by type-erasure - this is needed when bridging a lambda/method
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   674
     * reference, as the bridged signature might require downcast to be compatible
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   675
     * with the generated signature.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   676
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   677
    private List<JCExpression> convertArgs(Symbol meth, List<JCExpression> args, Type varargsElement) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   678
       Assert.check(meth.kind == Kinds.MTH);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   679
       List<Type> formals = types.erasure(meth.type).getParameterTypes();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   680
       if (varargsElement != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   681
           Assert.check((meth.flags() & VARARGS) != 0);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   682
       }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   683
       return transTypes.translateArgs(args, formals, varargsElement, attrEnv);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   684
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   685
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   686
    // </editor-fold>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   687
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   688
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   689
     * Generate an adapter method "bridge" for a method reference which cannot
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   690
     * be used directly.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   691
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   692
    private class MemberReferenceBridger {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   693
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   694
        private final JCMemberReference tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   695
        private final ReferenceTranslationContext localContext;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   696
        private final ListBuffer<JCExpression> args = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   697
        private final ListBuffer<JCVariableDecl> params = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   698
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   699
        MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   700
            this.tree = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   701
            this.localContext = localContext;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   702
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   703
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   704
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   705
         * Generate the bridge
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   706
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   707
        JCMethodDecl bridge() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   708
            int prevPos = make.pos;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   709
            try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   710
                make.at(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   711
                Type samDesc = localContext.bridgedRefSig();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   712
                List<Type> samPTypes = samDesc.getParameterTypes();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   713
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   714
                //an extra argument is prepended to the signature of the bridge in case
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   715
                //the member reference is an instance method reference (in which case
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   716
                //the receiver expression is passed to the bridge itself).
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   717
                Type recType = null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   718
                switch (tree.kind) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   719
                    case IMPLICIT_INNER:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   720
                        recType = tree.sym.owner.type.getEnclosingType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   721
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   722
                    case BOUND:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   723
                        recType = tree.getQualifierExpression().type;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   724
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   725
                    case UNBOUND:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   726
                        recType = samPTypes.head;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   727
                        samPTypes = samPTypes.tail;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   728
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   729
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   730
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   731
                //generate the parameter list for the bridged member reference - the
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   732
                //bridge signature will match the signature of the target sam descriptor
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   733
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   734
                VarSymbol rcvr = (recType == null)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   735
                        ? null
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   736
                        : addParameter("rec$", recType, false);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   737
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   738
                List<Type> refPTypes = tree.sym.type.getParameterTypes();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   739
                int refSize = refPTypes.size();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   740
                int samSize = samPTypes.size();
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   741
                // Last parameter to copy from referenced method
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   742
                int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   743
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   744
                List<Type> l = refPTypes;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   745
                // Use parameter types of the referenced method, excluding final var args
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   746
                for (int i = 0; l.nonEmpty() && i < last; ++i) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   747
                    addParameter("x$" + i, l.head, true);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   748
                    l = l.tail;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   749
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   750
                // Flatten out the var args
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   751
                for (int i = last; i < samSize; ++i) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   752
                    addParameter("xva$" + i, tree.varargsElement, true);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   753
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   754
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   755
                //generate the bridge method declaration
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   756
                JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   757
                        localContext.bridgeSym.name,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   758
                        make.QualIdent(samDesc.getReturnType().tsym),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   759
                        List.<JCTypeParameter>nil(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   760
                        params.toList(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   761
                        tree.sym.type.getThrownTypes() == null
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   762
                        ? List.<JCExpression>nil()
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   763
                        : make.Types(tree.sym.type.getThrownTypes()),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   764
                        null,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   765
                        null);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   766
                bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym;
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   767
                bridgeDecl.type = localContext.bridgeSym.type =
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   768
                        types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList()));
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   769
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   770
                //bridge method body generation - this can be either a method call or a
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   771
                //new instance creation expression, depending on the member reference kind
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   772
                JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE)
16327
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   773
                        ? bridgeExpressionInvoke(makeReceiver(rcvr))
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   774
                        : bridgeExpressionNew();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   775
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   776
                //the body is either a return expression containing a method call,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   777
                //or the method call itself, depending on whether the return type of
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   778
                //the bridge is non-void/void.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   779
                bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   780
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   781
                return bridgeDecl;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   782
            } finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   783
                make.at(prevPos);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   784
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   785
        }
16327
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   786
        //where
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   787
            private JCExpression makeReceiver(VarSymbol rcvr) {
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   788
                if (rcvr == null) return null;
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   789
                JCExpression rcvrExpr = make.Ident(rcvr);
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   790
                Type rcvrType = tree.sym.enclClass().type;
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   791
                if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   792
                    rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   793
                }
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   794
                return rcvrExpr;
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   795
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   796
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   797
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   798
         * determine the receiver of the bridged method call - the receiver can
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   799
         * be either the synthetic receiver parameter or a type qualifier; the
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   800
         * original qualifier expression is never used here, as it might refer
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   801
         * to symbols not available in the static context of the bridge
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   802
         */
16327
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   803
        private JCExpression bridgeExpressionInvoke(JCExpression rcvr) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   804
            JCExpression qualifier =
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   805
                    tree.sym.isStatic() ?
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   806
                        make.Type(tree.sym.owner.type) :
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   807
                        (rcvr != null) ?
16327
01a0c0cb811c 8009154: Missing cast in method reference bridge leads to NoSuchMethodError
mcimadamore
parents: 16325
diff changeset
   808
                            rcvr :
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   809
                            tree.getQualifierExpression();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   810
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   811
            //create the qualifier expression
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   812
            JCFieldAccess select = make.Select(qualifier, tree.sym.name);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   813
            select.sym = tree.sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   814
            select.type = tree.sym.erasure(types);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   815
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   816
            //create the method call expression
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   817
            JCExpression apply = make.Apply(List.<JCExpression>nil(), select,
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   818
                    convertArgs(tree.sym, args.toList(), tree.varargsElement)).
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   819
                    setType(tree.sym.erasure(types).getReturnType());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   820
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   821
            apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   822
            setVarargsIfNeeded(apply, tree.varargsElement);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   823
            return apply;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   824
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   825
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   826
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   827
         * the enclosing expression is either 'null' (no enclosing type) or set
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   828
         * to the first bridge synthetic parameter
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   829
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   830
        private JCExpression bridgeExpressionNew() {
15360
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   831
            if (tree.kind == ReferenceKind.ARRAY_CTOR) {
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   832
                //create the array creation expression
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   833
                JCNewArray newArr = make.NewArray(
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   834
                        make.Type(types.elemtype(tree.getQualifierExpression().type)),
15360
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   835
                        List.of(make.Ident(params.first())),
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   836
                        null);
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   837
                newArr.type = tree.getQualifierExpression().type;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   838
                return newArr;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   839
            } else {
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   840
                JCExpression encl = null;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   841
                switch (tree.kind) {
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   842
                    case UNBOUND:
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   843
                    case IMPLICIT_INNER:
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   844
                        encl = make.Ident(params.first());
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   845
                }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   846
15360
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   847
                //create the instance creation expression
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   848
                JCNewClass newClass = make.NewClass(encl,
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   849
                        List.<JCExpression>nil(),
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   850
                        make.Type(tree.getQualifierExpression().type),
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   851
                        convertArgs(tree.sym, args.toList(), tree.varargsElement),
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   852
                        null);
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   853
                newClass.constructor = tree.sym;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   854
                newClass.constructorType = tree.sym.erasure(types);
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   855
                newClass.type = tree.getQualifierExpression().type;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   856
                setVarargsIfNeeded(newClass, tree.varargsElement);
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   857
                return newClass;
450af2a9e3c9 8005854: Add support for array constructor references
mcimadamore
parents: 14949
diff changeset
   858
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   859
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   860
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   861
        private VarSymbol addParameter(String name, Type p, boolean genArg) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   862
            VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   863
            params.append(make.VarDef(vsym, null));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   864
            if (genArg) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   865
                args.append(make.Ident(vsym));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   866
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   867
            return vsym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   868
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   869
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   870
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   871
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   872
     * Bridges a member reference - this is needed when:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   873
     * * Var args in the referenced method need to be flattened away
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   874
     * * super is used
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   875
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   876
    private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   877
        kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   878
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   879
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   880
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   881
     * Generate an indy method call to the meta factory
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   882
     */
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   883
    private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   884
            boolean isSerializable, int refKind, Symbol refSym, List<JCExpression> indy_args) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   885
        //determine the static bsm args
15374
fb8f6acf09cc 8005244: Implement overload resolution as per latest spec EDR
mcimadamore
parents: 15360
diff changeset
   886
        Type mtype = types.erasure(tree.descriptorType);
fb8f6acf09cc 8005244: Implement overload resolution as per latest spec EDR
mcimadamore
parents: 15360
diff changeset
   887
        MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   888
        List<Object> staticArgs = List.<Object>of(
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   889
                new Pool.MethodHandle(ClassFile.REF_invokeInterface,
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   890
                    types.findDescriptorSymbol(tree.type.tsym), types),
14949
45f43822bbde 8000518: Javac generates duplicate name_and_type constant pool entry for class BinaryOpValueExp.java
vromero
parents: 14724
diff changeset
   891
                new Pool.MethodHandle(refKind, refSym, types),
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   892
                new MethodType(mtype.getParameterTypes(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   893
                        mtype.getReturnType(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   894
                        mtype.getThrownTypes(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   895
                        syms.methodClass));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   896
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   897
        //computed indy arg types
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   898
        ListBuffer<Type> indy_args_types = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   899
        for (JCExpression arg : indy_args) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   900
            indy_args_types.append(arg.type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   901
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   902
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   903
        //finally, compute the type of the indy call
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   904
        MethodType indyType = new MethodType(indy_args_types.toList(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   905
                tree.type,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   906
                List.<Type>nil(),
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   907
                syms.methodClass);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   908
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   909
        Name metafactoryName = needsAltMetafactory ?
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   910
                names.altMetaFactory : names.metaFactory;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   911
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   912
        if (needsAltMetafactory) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   913
            ListBuffer<Object> markers = ListBuffer.lb();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   914
            for (Symbol t : tree.targets.tail) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   915
                if (t != syms.serializableType.tsym) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   916
                    markers.append(t);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   917
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   918
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   919
            int flags = isSerializable? FLAG_SERIALIZABLE : 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   920
            boolean hasMarkers = markers.nonEmpty();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   921
            flags |= hasMarkers ? FLAG_MARKERS : 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   922
            staticArgs = staticArgs.append(flags);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   923
            if (hasMarkers) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   924
                staticArgs = staticArgs.append(markers.length());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   925
                staticArgs = staticArgs.appendList(markers.toList());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   926
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   927
            if (isSerializable) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   928
                addDeserializationCase(refKind, refSym, tree.type, samSym,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   929
                        tree, staticArgs, indyType);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   930
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   931
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   932
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
   933
        return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   934
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   935
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   936
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   937
     * Generate an indy method call with given name, type and static bootstrap
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   938
     * arguments types
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   939
     */
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   940
    private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName,
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   941
            List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   942
        int prevPos = make.pos;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   943
        try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   944
            make.at(pos);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   945
            List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   946
                    syms.stringType,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   947
                    syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   948
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   949
            Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   950
                    bsmName, bsm_staticArgs, List.<Type>nil());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   951
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   952
            DynamicMethodSymbol dynSym =
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   953
                    new DynamicMethodSymbol(names.lambda,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   954
                                            syms.noSymbol,
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   955
                                            bsm.isStatic() ?
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   956
                                                ClassFile.REF_invokeStatic :
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
   957
                                                ClassFile.REF_invokeVirtual,
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   958
                                            (MethodSymbol)bsm,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   959
                                            indyType,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   960
                                            staticArgs.toArray());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   961
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   962
            JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   963
            qualifier.sym = dynSym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   964
            qualifier.type = indyType.getReturnType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   965
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   966
            JCMethodInvocation proxyCall = make.Apply(List.<JCExpression>nil(), qualifier, indyArgs);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   967
            proxyCall.type = indyType.getReturnType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   968
            return proxyCall;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   969
        } finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   970
            make.at(prevPos);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   971
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   972
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   973
    //where
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   974
    private List<Type> bsmStaticArgToTypes(List<Object> args) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   975
        ListBuffer<Type> argtypes = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   976
        for (Object arg : args) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   977
            argtypes.append(bsmStaticArgToType(arg));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   978
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   979
        return argtypes.toList();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   980
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   981
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   982
    private Type bsmStaticArgToType(Object arg) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   983
        Assert.checkNonNull(arg);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   984
        if (arg instanceof ClassSymbol) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   985
            return syms.classType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   986
        } else if (arg instanceof Integer) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   987
            return syms.intType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   988
        } else if (arg instanceof Long) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   989
            return syms.longType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   990
        } else if (arg instanceof Float) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   991
            return syms.floatType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   992
        } else if (arg instanceof Double) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   993
            return syms.doubleType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   994
        } else if (arg instanceof String) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   995
            return syms.stringType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   996
        } else if (arg instanceof Pool.MethodHandle) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   997
            return syms.methodHandleType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   998
        } else if (arg instanceof MethodType) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
   999
            return syms.methodTypeType;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1000
        } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1001
            Assert.error("bad static arg " + arg.getClass());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1002
            return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1003
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1004
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1005
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1006
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1007
     * Get the opcode associated with this method reference
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1008
     */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1009
    private int referenceKind(Symbol refSym) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1010
        if (refSym.isConstructor()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1011
            return ClassFile.REF_newInvokeSpecial;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1012
        } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1013
            if (refSym.isStatic()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1014
                return ClassFile.REF_invokeStatic;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1015
            } else if (refSym.enclClass().isInterface()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1016
                return ClassFile.REF_invokeInterface;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1017
            } else {
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1018
                return (refSym.flags() & PRIVATE) != 0 ?
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1019
                        ClassFile.REF_invokeSpecial :
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1020
                        ClassFile.REF_invokeVirtual;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1021
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1022
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1023
    }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1024
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1025
    // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1026
    /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1027
     * This visitor collects information about translation of a lambda expression.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1028
     * More specifically, it keeps track of the enclosing contexts and captured locals
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1029
     * accessed by the lambda being translated (as well as other useful info).
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1030
     * It also translates away problems for LambdaToMethod.
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1031
     */
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1032
    class LambdaAnalyzerPreprocessor extends TreeTranslator {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1033
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1034
        /** the frame stack - used to reconstruct translation info about enclosing scopes */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1035
        private List<Frame> frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1036
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1037
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1038
         * keep the count of lambda expression (used to generate unambiguous
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1039
         * names)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1040
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1041
        private int lambdaCount = 0;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1042
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1043
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1044
         * keep the count of lambda expression defined in given context (used to
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1045
         * generate unambiguous names for serializable lambdas)
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1046
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1047
        private Map<String, Integer> serializableLambdaCounts =
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1048
                new HashMap<String, Integer>();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1049
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1050
        private Map<Symbol, JCClassDecl> localClassDefs;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1051
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1052
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1053
         * maps for fake clinit symbols to be used as owners of lambda occurring in
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1054
         * a static var init context
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1055
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1056
        private Map<ClassSymbol, Symbol> clinits =
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1057
                new HashMap<ClassSymbol, Symbol>();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1058
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1059
        private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1060
            frameStack = List.nil();
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1061
            localClassDefs = new HashMap<Symbol, JCClassDecl>();
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1062
            return translate(tree);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1063
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1064
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1065
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1066
        public void visitBlock(JCBlock tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1067
            List<Frame> prevStack = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1068
            try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1069
                if (frameStack.nonEmpty() && frameStack.head.tree.hasTag(CLASSDEF)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1070
                    frameStack = frameStack.prepend(new Frame(tree));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1071
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1072
                super.visitBlock(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1073
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1074
            finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1075
                frameStack = prevStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1076
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1077
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1078
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1079
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1080
        public void visitClassDef(JCClassDecl tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1081
            List<Frame> prevStack = frameStack;
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1082
            Map<String, Integer> prevSerializableLambdaCount =
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1083
                    serializableLambdaCounts;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1084
            Map<ClassSymbol, Symbol> prevClinits = clinits;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1085
            try {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1086
                serializableLambdaCounts = new HashMap<String, Integer>();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1087
                prevClinits = new HashMap<ClassSymbol, Symbol>();
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1088
                if (tree.sym.owner.kind == MTH) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1089
                    localClassDefs.put(tree.sym, tree);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1090
                }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1091
                if (directlyEnclosingLambda() != null) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1092
                    tree.sym.owner = owner();
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1093
                    if (tree.sym.hasOuterInstance()) {
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1094
                        //if a class is defined within a lambda, the lambda must capture
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1095
                        //its enclosing instance (if any)
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1096
                        TranslationContext<?> localContext = context();
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1097
                        while (localContext != null) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1098
                            if (localContext.tree.getTag() == LAMBDA) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1099
                                ((LambdaTranslationContext)localContext)
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1100
                                        .addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1101
                            }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1102
                            localContext = localContext.prev;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1103
                        }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1104
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1105
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1106
                frameStack = frameStack.prepend(new Frame(tree));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1107
                super.visitClassDef(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1108
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1109
            finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1110
                frameStack = prevStack;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1111
                serializableLambdaCounts = prevSerializableLambdaCount;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1112
                clinits = prevClinits;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1113
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1114
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1115
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1116
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1117
        public void visitIdent(JCIdent tree) {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1118
            if (context() != null && lambdaIdentSymbolFilter(tree.sym)) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1119
                if (tree.sym.kind == VAR &&
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1120
                        tree.sym.owner.kind == MTH &&
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1121
                        tree.type.constValue() == null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1122
                    TranslationContext<?> localContext = context();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1123
                    while (localContext != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1124
                        if (localContext.tree.getTag() == LAMBDA) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1125
                            JCTree block = capturedDecl(localContext.depth, tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1126
                            if (block == null) break;
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1127
                            ((LambdaTranslationContext)localContext)
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1128
                                    .addSymbol(tree.sym, CAPTURED_VAR);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1129
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1130
                        localContext = localContext.prev;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1131
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1132
                } else if (tree.sym.owner.kind == TYP) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1133
                    TranslationContext<?> localContext = context();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1134
                    while (localContext != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1135
                        if (localContext.tree.hasTag(LAMBDA)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1136
                            JCTree block = capturedDecl(localContext.depth, tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1137
                            if (block == null) break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1138
                            switch (block.getTag()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1139
                                case CLASSDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1140
                                    JCClassDecl cdecl = (JCClassDecl)block;
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1141
                                    ((LambdaTranslationContext)localContext)
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1142
                                            .addSymbol(cdecl.sym, CAPTURED_THIS);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1143
                                    break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1144
                                default:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1145
                                    Assert.error("bad block kind");
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1146
                            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1147
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1148
                        localContext = localContext.prev;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1149
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1150
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1151
            }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1152
            super.visitIdent(tree);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1153
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1154
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1155
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1156
        public void visitLambda(JCLambda tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1157
            List<Frame> prevStack = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1158
            try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1159
                LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1160
                frameStack = frameStack.prepend(new Frame(tree));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1161
                for (JCVariableDecl param : tree.params) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1162
                    context.addSymbol(param.sym, PARAM);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1163
                    frameStack.head.addLocal(param.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1164
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1165
                contextMap.put(tree, context);
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1166
                super.visitLambda(tree);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1167
                context.complete();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1168
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1169
            finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1170
                frameStack = prevStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1171
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1172
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1173
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1174
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1175
        public void visitMethodDef(JCMethodDecl tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1176
            List<Frame> prevStack = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1177
            try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1178
                frameStack = frameStack.prepend(new Frame(tree));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1179
                super.visitMethodDef(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1180
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1181
            finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1182
                frameStack = prevStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1183
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1184
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1185
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1186
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1187
        public void visitNewClass(JCNewClass tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1188
            if (lambdaNewClassFilter(context(), tree)) {
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1189
                TranslationContext<?> localContext = context();
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1190
                while (localContext != null) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1191
                    if (localContext.tree.getTag() == LAMBDA) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1192
                        ((LambdaTranslationContext)localContext)
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1193
                                .addSymbol(tree.type.getEnclosingType().tsym, CAPTURED_THIS);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1194
                    }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1195
                    localContext = localContext.prev;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1196
                }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1197
            }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1198
            if (context() != null && tree.type.tsym.owner.kind == MTH) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1199
                LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context();
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1200
                captureLocalClassDefs(tree.type.tsym, lambdaContext);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1201
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1202
            super.visitNewClass(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1203
        }
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1204
        //where
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1205
            void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1206
                JCClassDecl localCDef = localClassDefs.get(csym);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1207
                if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1208
                    BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1209
                        @Override
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1210
                        void addFreeVars(ClassSymbol c) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1211
                            captureLocalClassDefs(c, lambdaContext);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1212
                        }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1213
                        @Override
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1214
                        void visitSymbol(Symbol sym) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1215
                            if (sym.kind == VAR &&
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1216
                                    sym.owner.kind == MTH &&
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1217
                                    ((VarSymbol)sym).getConstValue() == null) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1218
                                TranslationContext<?> localContext = context();
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1219
                                while (localContext != null) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1220
                                    if (localContext.tree.getTag() == LAMBDA) {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1221
                                        JCTree block = capturedDecl(localContext.depth, sym);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1222
                                        if (block == null) break;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1223
                                        ((LambdaTranslationContext)localContext).addSymbol(sym, CAPTURED_VAR);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1224
                                    }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1225
                                    localContext = localContext.prev;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1226
                                }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1227
                            }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1228
                        }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1229
                    };
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1230
                    fvc.scan(localCDef);
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1231
                }
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1232
        }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1233
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1234
        /**
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1235
         * Method references to local class constructors, may, if the local
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1236
         * class references local variables, have implicit constructor
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1237
         * parameters added in Lower; As a result, the invokedynamic bootstrap
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1238
         * information added in the LambdaToMethod pass will have the wrong
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1239
         * signature. Hooks between Lower and LambdaToMethod have been added to
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1240
         * handle normal "new" in this case. This visitor converts potentially
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1241
         * effected method references into a lambda containing a normal "new" of
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1242
         * the class.
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1243
         *
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1244
         * @param tree
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1245
         */
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1246
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1247
        public void visitReference(JCMemberReference tree) {
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1248
            if (tree.getMode() == ReferenceMode.NEW
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1249
                    && tree.kind != ReferenceKind.ARRAY_CTOR
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1250
                    && tree.sym.owner.isLocal()) {
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1251
                MethodSymbol consSym = (MethodSymbol) tree.sym;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1252
                List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1253
                Type classType = consSym.owner.type;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1254
17550
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1255
                // Build lambda parameters
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1256
                // partially cloned from TreeMaker.Params until 8014021 is fixed
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1257
                Symbol owner = owner();
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1258
                ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>();
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1259
                int i = 0;
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1260
                for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) {
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1261
                    paramBuff.append(make.Param(make.paramName(i++), l.head, owner));
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1262
                }
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1263
                List<JCVariableDecl> params = paramBuff.toList();
567df1379253 8014023: When a method reference to a local class constructor is contained in a method whose number of parameters matches the number of constructor parameters compilation fails
rfield
parents: 17286
diff changeset
  1264
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1265
                // Make new-class call
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1266
                JCNewClass nc = makeNewClass(classType, make.Idents(params));
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1267
                nc.pos = tree.pos;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1268
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1269
                // Make lambda holding the new-class call
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1270
                JCLambda slam = make.Lambda(params, nc);
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1271
                slam.descriptorType = tree.descriptorType;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1272
                slam.targets = tree.targets;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1273
                slam.type = tree.type;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1274
                slam.pos = tree.pos;
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1275
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1276
                // Now it is a lambda, process as such
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1277
                visitLambda(slam);
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1278
            } else {
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1279
                super.visitReference(tree);
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1280
                contextMap.put(tree, makeReferenceContext(tree));
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1281
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1282
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1283
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1284
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1285
        public void visitSelect(JCFieldAccess tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1286
            if (context() != null && lambdaSelectSymbolFilter(tree.sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1287
                TranslationContext<?> localContext = context();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1288
                while (localContext != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1289
                    if (localContext.tree.hasTag(LAMBDA)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1290
                        JCClassDecl clazz = (JCClassDecl)capturedDecl(localContext.depth, tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1291
                        if (clazz == null) break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1292
                        ((LambdaTranslationContext)localContext).addSymbol(clazz.sym, CAPTURED_THIS);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1293
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1294
                    localContext = localContext.prev;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1295
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1296
            }
17286
fec581c36de4 8011591: BootstrapMethodError when capturing constructor ref to local classes
rfield
parents: 16798
diff changeset
  1297
            super.visitSelect(tree);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1298
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1299
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1300
        @Override
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1301
        public void visitVarDef(JCVariableDecl tree) {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1302
            TranslationContext<?> context = context();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1303
            LambdaTranslationContext ltc = (context != null && context instanceof LambdaTranslationContext)?
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1304
                    (LambdaTranslationContext)context :
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1305
                    null;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1306
            if (ltc != null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1307
                if (frameStack.head.tree.hasTag(LAMBDA)) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1308
                    ltc.addSymbol(tree.sym, LOCAL_VAR);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1309
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1310
                // Check for type variables (including as type arguments).
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1311
                // If they occur within class nested in a lambda, mark for erasure
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1312
                Type type = tree.sym.asType();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1313
                if (inClassWithinLambda() && !types.isSameType(types.erasure(type), type)) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1314
                    ltc.addSymbol(tree.sym, TYPE_VAR);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1315
                }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1316
            }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1317
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1318
            List<Frame> prevStack = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1319
            try {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1320
                if (tree.sym.owner.kind == MTH) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1321
                    frameStack.head.addLocal(tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1322
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1323
                frameStack = frameStack.prepend(new Frame(tree));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1324
                super.visitVarDef(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1325
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1326
            finally {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1327
                frameStack = prevStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1328
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1329
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1330
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1331
        private Name lambdaName() {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1332
            return names.lambda.append(names.fromString("" + lambdaCount++));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1333
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1334
16551
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1335
        /**
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1336
         * For a serializable lambda, generate a name which maximizes name
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1337
         * stability across deserialization.
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1338
         * @param owner
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1339
         * @return Name to use for the synthetic lambda method name
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1340
         */
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1341
        private Name serializedLambdaName(Symbol owner) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1342
            StringBuilder buf = new StringBuilder();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1343
            buf.append(names.lambda);
16551
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1344
            // Append the name of the method enclosing the lambda.
16337
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1345
            String methodName = owner.name.toString();
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1346
            if (methodName.equals("<clinit>"))
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1347
                methodName = "static";
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1348
            else if (methodName.equals("<init>"))
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1349
                methodName = "new";
181ac468ab24 8009742: Bad lambda name for lambda in a static initializer or ctor
rfield
parents: 16335
diff changeset
  1350
            buf.append(methodName);
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1351
            buf.append('$');
16551
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1352
            // Append a hash of the enclosing method signature to differentiate
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1353
            // overloaded enclosing methods.  For lambdas enclosed in lambdas,
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1354
            // the generated lambda method will not have type yet, but the
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1355
            // enclosing method's name will have been generated with this same
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1356
            // method, so it will be unique and never be overloaded.
16797
652a5f8c8ca5 8010469: Bad assertion in LambdaToMethod
mcimadamore
parents: 16564
diff changeset
  1357
            Assert.check(owner.type != null || directlyEnclosingLambda() != null);
16551
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1358
            if (owner.type != null) {
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1359
                int methTypeHash = methodSig(owner.type).hashCode();
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1360
                buf.append(Integer.toHexString(methTypeHash));
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1361
            }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1362
            buf.append('$');
16551
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1363
            // The above appended name components may not be unique, append a
c08f5b2c7232 8010010: NPE generating serializedLambdaName for nested lambda
rfield
parents: 16337
diff changeset
  1364
            // count based on the above name components.
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1365
            String temp = buf.toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1366
            Integer count = serializableLambdaCounts.get(temp);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1367
            if (count == null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1368
                count = 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1369
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1370
            buf.append(count++);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1371
            serializableLambdaCounts.put(temp, count);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1372
            return names.fromString(buf.toString());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1373
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1374
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1375
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1376
         * Return a valid owner given the current declaration stack
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1377
         * (required to skip synthetic lambda symbols)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1378
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1379
        private Symbol owner() {
15379
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1380
            return owner(false);
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1381
        }
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1382
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1383
        @SuppressWarnings("fallthrough")
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1384
        private Symbol owner(boolean skipLambda) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1385
            List<Frame> frameStack2 = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1386
            while (frameStack2.nonEmpty()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1387
                switch (frameStack2.head.tree.getTag()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1388
                    case VARDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1389
                        if (((JCVariableDecl)frameStack2.head.tree).sym.isLocal()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1390
                            frameStack2 = frameStack2.tail;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1391
                            break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1392
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1393
                        JCClassDecl cdecl = (JCClassDecl)frameStack2.tail.head.tree;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1394
                        return initSym(cdecl.sym,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1395
                                ((JCVariableDecl)frameStack2.head.tree).sym.flags() & STATIC);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1396
                    case BLOCK:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1397
                        JCClassDecl cdecl2 = (JCClassDecl)frameStack2.tail.head.tree;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1398
                        return initSym(cdecl2.sym,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1399
                                ((JCBlock)frameStack2.head.tree).flags & STATIC);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1400
                    case CLASSDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1401
                        return ((JCClassDecl)frameStack2.head.tree).sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1402
                    case METHODDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1403
                        return ((JCMethodDecl)frameStack2.head.tree).sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1404
                    case LAMBDA:
15379
c483442d0939 8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
mcimadamore
parents: 15374
diff changeset
  1405
                        if (!skipLambda)
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1406
                            return ((LambdaTranslationContext)contextMap
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1407
                                    .get(frameStack2.head.tree)).translatedSym;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1408
                    default:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1409
                        frameStack2 = frameStack2.tail;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1410
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1411
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1412
            Assert.error();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1413
            return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1414
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1415
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1416
        private Symbol initSym(ClassSymbol csym, long flags) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1417
            boolean isStatic = (flags & STATIC) != 0;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1418
            if (isStatic) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1419
                //static clinits are generated in Gen - so we need to fake them
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1420
                Symbol clinit = clinits.get(csym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1421
                if (clinit == null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1422
                    clinit = makeSyntheticMethod(STATIC,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1423
                            names.clinit,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1424
                            new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), syms.methodClass),
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1425
                            csym);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1426
                    clinits.put(csym, clinit);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1427
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1428
                return clinit;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1429
            } else {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1430
                //get the first constructor and treat it as the instance init sym
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1431
                for (Symbol s : csym.members_field.getElementsByName(names.init)) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1432
                    return s;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1433
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1434
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1435
            Assert.error("init not found");
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1436
            return null;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1437
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1438
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1439
        private JCTree directlyEnclosingLambda() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1440
            if (frameStack.isEmpty()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1441
                return null;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1442
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1443
            List<Frame> frameStack2 = frameStack;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1444
            while (frameStack2.nonEmpty()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1445
                switch (frameStack2.head.tree.getTag()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1446
                    case CLASSDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1447
                    case METHODDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1448
                        return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1449
                    case LAMBDA:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1450
                        return frameStack2.head.tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1451
                    default:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1452
                        frameStack2 = frameStack2.tail;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1453
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1454
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1455
            Assert.error();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1456
            return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1457
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1458
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1459
        private boolean inClassWithinLambda() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1460
            if (frameStack.isEmpty()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1461
                return false;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1462
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1463
            List<Frame> frameStack2 = frameStack;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1464
            boolean classFound = false;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1465
            while (frameStack2.nonEmpty()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1466
                switch (frameStack2.head.tree.getTag()) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1467
                    case LAMBDA:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1468
                        return classFound;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1469
                    case CLASSDEF:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1470
                        classFound = true;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1471
                        frameStack2 = frameStack2.tail;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1472
                        break;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1473
                    default:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1474
                        frameStack2 = frameStack2.tail;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1475
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1476
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1477
            // No lambda
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1478
            return false;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1479
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1480
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1481
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1482
         * Return the declaration corresponding to a symbol in the enclosing
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1483
         * scope; the depth parameter is used to filter out symbols defined
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1484
         * in nested scopes (which do not need to undergo capture).
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1485
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1486
        private JCTree capturedDecl(int depth, Symbol sym) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1487
            int currentDepth = frameStack.size() - 1;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1488
            for (Frame block : frameStack) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1489
                switch (block.tree.getTag()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1490
                    case CLASSDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1491
                        ClassSymbol clazz = ((JCClassDecl)block.tree).sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1492
                        if (sym.isMemberOf(clazz, types)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1493
                            return currentDepth > depth ? null : block.tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1494
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1495
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1496
                    case VARDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1497
                        if (((JCVariableDecl)block.tree).sym == sym &&
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1498
                                sym.owner.kind == MTH) { //only locals are captured
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1499
                            return currentDepth > depth ? null : block.tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1500
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1501
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1502
                    case BLOCK:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1503
                    case METHODDEF:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1504
                    case LAMBDA:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1505
                        if (block.locals != null && block.locals.contains(sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1506
                            return currentDepth > depth ? null : block.tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1507
                        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1508
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1509
                    default:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1510
                        Assert.error("bad decl kind " + block.tree.getTag());
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1511
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1512
                currentDepth--;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1513
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1514
            return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1515
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1516
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1517
        private TranslationContext<?> context() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1518
            for (Frame frame : frameStack) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1519
                TranslationContext<?> context = contextMap.get(frame.tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1520
                if (context != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1521
                    return context;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1522
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1523
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1524
            return null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1525
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1526
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1527
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1528
         *  This is used to filter out those identifiers that needs to be adjusted
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1529
         *  when translating away lambda expressions
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1530
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1531
        private boolean lambdaIdentSymbolFilter(Symbol sym) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1532
            return (sym.kind == VAR || sym.kind == MTH)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1533
                    && !sym.isStatic()
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1534
                    && sym.name != names.init;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1535
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1536
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1537
        private boolean lambdaSelectSymbolFilter(Symbol sym) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1538
            return (sym.kind == VAR || sym.kind == MTH) &&
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1539
                        !sym.isStatic() &&
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1540
                        (sym.name == names._this ||
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1541
                        sym.name == names._super);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1542
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1543
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1544
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1545
         * This is used to filter out those new class expressions that need to
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1546
         * be qualified with an enclosing tree
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1547
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1548
        private boolean lambdaNewClassFilter(TranslationContext<?> context, JCNewClass tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1549
            if (context != null
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1550
                    && tree.encl == null
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1551
                    && tree.def == null
14537
ad188879b6fe 8003306: Compiler crash: calculation of inner class access modifier
rfield
parents: 14365
diff changeset
  1552
                    && !tree.type.getEnclosingType().hasTag(NONE)) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1553
                Type encl = tree.type.getEnclosingType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1554
                Type current = context.owner.enclClass().type;
14537
ad188879b6fe 8003306: Compiler crash: calculation of inner class access modifier
rfield
parents: 14365
diff changeset
  1555
                while (!current.hasTag(NONE)) {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1556
                    if (current.tsym.isSubClass(encl.tsym, types)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1557
                        return true;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1558
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1559
                    current = current.getEnclosingType();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1560
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1561
                return false;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1562
            } else {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1563
                return false;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1564
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1565
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1566
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1567
        private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1568
            return new LambdaTranslationContext(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1569
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1570
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1571
        private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1572
            return new ReferenceTranslationContext(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1573
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1574
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1575
        private class Frame {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1576
            final JCTree tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1577
            List<Symbol> locals;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1578
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1579
            public Frame(JCTree tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1580
                this.tree = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1581
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1582
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1583
            void addLocal(Symbol sym) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1584
                if (locals == null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1585
                    locals = List.nil();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1586
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1587
                locals = locals.prepend(sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1588
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1589
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1590
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1591
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1592
         * This class is used to store important information regarding translation of
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1593
         * lambda expression/method references (see subclasses).
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1594
         */
15374
fb8f6acf09cc 8005244: Implement overload resolution as per latest spec EDR
mcimadamore
parents: 15360
diff changeset
  1595
        private abstract class TranslationContext<T extends JCFunctionalExpression> {
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1596
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1597
            /** the underlying (untranslated) tree */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1598
            T tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1599
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1600
            /** points to the adjusted enclosing scope in which this lambda/mref expression occurs */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1601
            Symbol owner;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1602
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1603
            /** the depth of this lambda expression in the frame stack */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1604
            int depth;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1605
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1606
            /** the enclosing translation context (set for nested lambdas/mref) */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1607
            TranslationContext<?> prev;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1608
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1609
            TranslationContext(T tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1610
                this.tree = tree;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1611
                this.owner = owner();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1612
                this.depth = frameStack.size() - 1;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1613
                this.prev = context();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1614
            }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1615
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1616
            /** does this functional expression need to be created using alternate metafactory? */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1617
            boolean needsAltMetafactory() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1618
                return (tree.targets.length() > 1 ||
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1619
                        isSerializable());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1620
            }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1621
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1622
            /** does this functional expression require serialization support? */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1623
            boolean isSerializable() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1624
                for (Symbol target : tree.targets) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1625
                    if (types.asSuper(target.type, syms.serializableType.tsym) != null) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1626
                        return true;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1627
                    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1628
                }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1629
                return false;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1630
            }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1631
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1632
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1633
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1634
         * This class retains all the useful information about a lambda expression;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1635
         * the contents of this class are filled by the LambdaAnalyzer visitor,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1636
         * and the used by the main translation routines in order to adjust references
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1637
         * to captured locals/members, etc.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1638
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1639
        private class LambdaTranslationContext extends TranslationContext<JCLambda> {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1640
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1641
            /** variable in the enclosing context to which this lambda is assigned */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1642
            Symbol self;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1643
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1644
            /** map from original to translated lambda parameters */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1645
            Map<Symbol, Symbol> lambdaParams = new LinkedHashMap<Symbol, Symbol>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1646
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1647
            /** map from original to translated lambda locals */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1648
            Map<Symbol, Symbol> lambdaLocals = new LinkedHashMap<Symbol, Symbol>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1649
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1650
            /** map from variables in enclosing scope to translated synthetic parameters */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1651
            Map<Symbol, Symbol> capturedLocals  = new LinkedHashMap<Symbol, Symbol>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1652
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1653
            /** map from class symbols to translated synthetic parameters (for captured member access) */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1654
            Map<Symbol, Symbol> capturedThis = new LinkedHashMap<Symbol, Symbol>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1655
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1656
            /** map from original to translated lambda locals */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1657
            Map<Symbol, Symbol> typeVars = new LinkedHashMap<Symbol, Symbol>();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1658
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1659
            /** the synthetic symbol for the method hoisting the translated lambda */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1660
            Symbol translatedSym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1661
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1662
            List<JCVariableDecl> syntheticParams;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1663
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1664
            LambdaTranslationContext(JCLambda tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1665
                super(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1666
                Frame frame = frameStack.head;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1667
                if (frame.tree.hasTag(VARDEF)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1668
                    self = ((JCVariableDecl)frame.tree).sym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1669
                }
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1670
                Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1671
                this.translatedSym = makeSyntheticMethod(0, name, null, owner.enclClass());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1672
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1673
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1674
            /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1675
             * Translate a symbol of a given kind into something suitable for the
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1676
             * synthetic lambda body
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1677
             */
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1678
            Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) {
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1679
                switch (skind) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1680
                    case CAPTURED_THIS:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1681
                        return sym;  // self represented
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1682
                    case TYPE_VAR:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1683
                        // Just erase the type var
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1684
                        return new VarSymbol(sym.flags(), name,
16308
a0658c36f717 8008227: Mixing lambdas with anonymous classes leads to NPE thrown by compiler
mcimadamore
parents: 16300
diff changeset
  1685
                                types.erasure(sym.type), sym.owner);
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1686
                    case CAPTURED_VAR:
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1687
                        return new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
16325
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1688
                            @Override
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1689
                            public Symbol baseSymbol() {
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1690
                                //keep mapping with original captured symbol
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1691
                                return sym;
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1692
                            }
088a91896245 8004962: Code generation crash with lambda and local classes
mcimadamore
parents: 16310
diff changeset
  1693
                        };
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1694
                    default:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1695
                        return makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1696
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1697
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1698
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1699
            void addSymbol(Symbol sym, LambdaSymbolKind skind) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1700
                Map<Symbol, Symbol> transMap = null;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1701
                Name preferredName;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1702
                switch (skind) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1703
                    case CAPTURED_THIS:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1704
                        transMap = capturedThis;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1705
                        preferredName = names.fromString("encl$" + capturedThis.size());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1706
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1707
                    case CAPTURED_VAR:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1708
                        transMap = capturedLocals;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1709
                        preferredName = names.fromString("cap$" + capturedLocals.size());
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1710
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1711
                    case LOCAL_VAR:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1712
                        transMap = lambdaLocals;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1713
                        preferredName = sym.name;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1714
                        break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1715
                    case PARAM:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1716
                        transMap = lambdaParams;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1717
                        preferredName = sym.name;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1718
                        break;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1719
                    case TYPE_VAR:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1720
                        transMap = typeVars;
16564
061aa10703e8 8009649: Lambda back-end should generate invokespecial for method handles referring to private instance methods
mcimadamore
parents: 16551
diff changeset
  1721
                        preferredName = sym.name;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1722
                        break;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1723
                    default: throw new AssertionError();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1724
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1725
                if (!transMap.containsKey(sym)) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1726
                    transMap.put(sym, translate(preferredName, sym, skind));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1727
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1728
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1729
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1730
            Map<Symbol, Symbol> getSymbolMap(LambdaSymbolKind... skinds) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1731
                LinkedHashMap<Symbol, Symbol> translationMap = new LinkedHashMap<Symbol, Symbol>();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1732
                for (LambdaSymbolKind skind : skinds) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1733
                    switch (skind) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1734
                        case CAPTURED_THIS:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1735
                            translationMap.putAll(capturedThis);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1736
                            break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1737
                        case CAPTURED_VAR:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1738
                            translationMap.putAll(capturedLocals);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1739
                            break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1740
                        case LOCAL_VAR:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1741
                            translationMap.putAll(lambdaLocals);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1742
                            break;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1743
                        case PARAM:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1744
                            translationMap.putAll(lambdaParams);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1745
                            break;
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1746
                        case TYPE_VAR:
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1747
                            translationMap.putAll(typeVars);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1748
                            break;
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1749
                        default: throw new AssertionError();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1750
                    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1751
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1752
                return translationMap;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1753
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1754
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1755
            /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1756
             * The translatedSym is not complete/accurate until the analysis is
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1757
             * finished.  Once the analysis is finished, the translatedSym is
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1758
             * "completed" -- updated with type information, access modifiers,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1759
             * and full parameter list.
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1760
             */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1761
            void complete() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1762
                if (syntheticParams != null) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1763
                    return;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1764
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1765
                boolean inInterface = translatedSym.owner.isInterface();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1766
                boolean thisReferenced = !getSymbolMap(CAPTURED_THIS).isEmpty();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1767
17575
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1768
                // If instance access isn't needed, make it static.
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1769
                // Interface instance methods must be default methods.
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1770
                // Awaiting VM channges, default methods are public
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1771
                translatedSym.flags_field = SYNTHETIC |
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1772
                        ((inInterface && thisReferenced)? PUBLIC : PRIVATE) |
7693e6ff0d7d 8012556: Implement lambda methods on interfaces as static
rfield
parents: 17550
diff changeset
  1773
                        (thisReferenced? (inInterface? DEFAULT : 0) : STATIC);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1774
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1775
                //compute synthetic params
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1776
                ListBuffer<JCVariableDecl> params = ListBuffer.lb();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1777
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1778
                // The signature of the method is augmented with the following
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1779
                // synthetic parameters:
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1780
                //
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1781
                // 1) reference to enclosing contexts captured by the lambda expression
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1782
                // 2) enclosing locals captured by the lambda expression
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1783
                for (Symbol thisSym : getSymbolMap(CAPTURED_VAR, PARAM).values()) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1784
                    params.append(make.VarDef((VarSymbol) thisSym, null));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1785
                }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1786
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1787
                syntheticParams = params.toList();
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1788
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1789
                //prepend synthetic args to translated lambda method signature
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1790
                translatedSym.type = types.createMethodTypeWithParameters(
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1791
                        generatedLambdaSig(),
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1792
                        TreeInfo.types(syntheticParams));
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1793
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1794
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1795
            Type generatedLambdaSig() {
15374
fb8f6acf09cc 8005244: Implement overload resolution as per latest spec EDR
mcimadamore
parents: 15360
diff changeset
  1796
                return types.erasure(tree.descriptorType);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1797
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1798
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1799
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1800
        /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1801
         * This class retains all the useful information about a method reference;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1802
         * the contents of this class are filled by the LambdaAnalyzer visitor,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1803
         * and the used by the main translation routines in order to adjust method
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1804
         * references (i.e. in case a bridge is needed)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1805
         */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1806
        private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1807
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1808
            final boolean isSuper;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1809
            final Symbol bridgeSym;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1810
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1811
            ReferenceTranslationContext(JCMemberReference tree) {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1812
                super(tree);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1813
                this.isSuper = tree.hasKind(ReferenceKind.SUPER);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1814
                this.bridgeSym = needsBridge()
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1815
                        ? makeSyntheticMethod(isSuper ? 0 : STATIC,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1816
                                              lambdaName().append(names.fromString("$bridge")), null,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1817
                                              owner.enclClass())
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1818
                        : null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1819
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1820
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1821
            /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1822
             * Get the opcode associated with this method reference
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1823
             */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1824
            int referenceKind() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1825
                return LambdaToMethod.this.referenceKind(needsBridge() ? bridgeSym : tree.sym);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1826
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1827
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1828
            boolean needsVarArgsConversion() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1829
                return tree.varargsElement != null;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1830
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1831
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1832
            /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1833
             * @return Is this an array operation like clone()
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1834
             */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1835
            boolean isArrayOp() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1836
                return tree.sym.owner == syms.arrayClass;
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1837
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1838
16310
af1565438e63 8005183: Missing accessor for constructor reference pointing to private inner class ctor
mcimadamore
parents: 16308
diff changeset
  1839
            boolean isPrivateConstructor() {
16328
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1840
                //hack needed to workaround 292 bug (8005122)
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1841
                //when 292 issue is fixed we should simply remove this
16310
af1565438e63 8005183: Missing accessor for constructor reference pointing to private inner class ctor
mcimadamore
parents: 16308
diff changeset
  1842
                return tree.sym.name == names.init &&
af1565438e63 8005183: Missing accessor for constructor reference pointing to private inner class ctor
mcimadamore
parents: 16308
diff changeset
  1843
                        (tree.sym.flags() & PRIVATE) != 0;
af1565438e63 8005183: Missing accessor for constructor reference pointing to private inner class ctor
mcimadamore
parents: 16308
diff changeset
  1844
            }
af1565438e63 8005183: Missing accessor for constructor reference pointing to private inner class ctor
mcimadamore
parents: 16308
diff changeset
  1845
16328
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1846
            boolean receiverAccessible() {
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1847
                //hack needed to workaround 292 bug (7087658)
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1848
                //when 292 issue is fixed we should remove this and change the backend
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1849
                //code to always generate a method handle to an accessible method
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1850
                return tree.ownerAccessible;
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1851
            }
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1852
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1853
            /**
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1854
             * Does this reference needs a bridge (i.e. var args need to be
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1855
             * expanded or "super" is used)
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1856
             */
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1857
            final boolean needsBridge() {
16328
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1858
                return isSuper || needsVarArgsConversion() || isArrayOp() ||
8b9eb42167f6 8009129: Illegal access error when calling method reference
mcimadamore
parents: 16327
diff changeset
  1859
                        isPrivateConstructor() || !receiverAccessible();
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1860
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1861
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1862
            Type generatedRefSig() {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1863
                return types.erasure(tree.sym.type);
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1864
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1865
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1866
            Type bridgedRefSig() {
15374
fb8f6acf09cc 8005244: Implement overload resolution as per latest spec EDR
mcimadamore
parents: 15360
diff changeset
  1867
                return types.erasure(types.findDescriptorSymbol(tree.targets.head).type);
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1868
            }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1869
        }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1870
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1871
    // </editor-fold>
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1872
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1873
    enum LambdaSymbolKind {
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1874
        CAPTURED_VAR,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1875
        CAPTURED_THIS,
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1876
        LOCAL_VAR,
16300
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1877
        PARAM,
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1878
        TYPE_VAR;
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1879
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1880
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1881
    /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1882
     * ****************************************************************
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1883
     * Signature Generation
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1884
     * ****************************************************************
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1885
     */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1886
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1887
    private String methodSig(Type type) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1888
        L2MSignatureGenerator sg = new L2MSignatureGenerator();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1889
        sg.assembleSig(type);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1890
        return sg.toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1891
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1892
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1893
    private String classSig(Type type) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1894
        L2MSignatureGenerator sg = new L2MSignatureGenerator();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1895
        sg.assembleClassSig(type);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1896
        return sg.toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1897
    }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1898
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1899
    /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1900
     * Signature Generation
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1901
     */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1902
    private class L2MSignatureGenerator extends Types.SignatureGenerator {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1903
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1904
        /**
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1905
         * An output buffer for type signatures.
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1906
         */
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1907
        StringBuilder sb = new StringBuilder();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1908
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1909
        L2MSignatureGenerator() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1910
            super(types);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1911
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1912
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1913
        @Override
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1914
        protected void append(char ch) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1915
            sb.append(ch);
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1916
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1917
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1918
        @Override
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1919
        protected void append(byte[] ba) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1920
            sb.append(new String(ba));
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1921
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1922
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1923
        @Override
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1924
        protected void append(Name name) {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1925
            sb.append(name.toString());
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1926
        }
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1927
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1928
        @Override
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1929
        public String toString() {
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1930
            return sb.toString();
7cf27559c8df 8004969: Generate $deserializeLambda$ method
rfield
parents: 15379
diff changeset
  1931
        }
14365
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1932
    }
20f388573215 8000694: Add generation of lambda implementation code: invokedynamic call, lambda method, adaptor methods
rfield
parents:
diff changeset
  1933
}