1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
  25 
  26 /*
  27  * @test
  28  * @summary Test population of reference info for lambda expressions
  29  * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
  30  * @run main Driver Lambda
  31  * @author Werner Dietl
  32  */
  33 public class Lambda {
  34 
  35     @TADescriptions({
  36         @TADescription(annotation = "TA", type = METHOD_REFERENCE,
  37                 offset = ReferenceInfoUtil.IGNORE_VALUE),
  38         @TADescription(annotation = "TB", type = METHOD_REFERENCE,
  39                 offset = ReferenceInfoUtil.IGNORE_VALUE)
  40     })
  41     public String returnMethodRef1() {
  42         return
  43                 "class Lambda {" +
  44                 "  public String getName() { return \"Lambda!\"; }" +
  45                 "}" +
  46 
  47                 "class Test {" +
  48                 "  java.util.function.Function<Lambda, String> lambda() {" +
  49                 "    return @TA @TB Lambda::getName;" +
  50                 "  }" +
  51                 "}";
  52     }
  53 
  54     @TADescriptions({
  55         @TADescription(annotation = "TA", type = METHOD_REFERENCE,
  56                 offset = ReferenceInfoUtil.IGNORE_VALUE),
  57         @TADescription(annotation = "TB", type = METHOD_REFERENCE,
  58                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  59                 genericLocation = { 3, 0 }),
  60         @TADescription(annotation = "TC", type = METHOD_REFERENCE,
  61                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  62                 genericLocation = { 3, 0 }),
  63         @TADescription(annotation = "TD", type = METHOD_REFERENCE,
  64                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  65                 genericLocation = { 3, 1 }),
  66         @TADescription(annotation = "TE", type = METHOD_REFERENCE,
  67                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  68                 genericLocation = { 3, 1 })
  69     })
  70     public String returnMethodRef2() {
  71         return
  72                 "class Lambda<S, T> {" +
  73                 "  public String getName() { return \"Lambda!\"; }" +
  74                 "}" +
  75 
  76                 "class Test {" +
  77                 "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
  78                 "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::getName;" +
  79                 "  }" +
  80                 "}";
  81     }
  82 
  83     @TADescriptions({
  84         @TADescription(annotation = "CTA", type = METHOD_REFERENCE,
  85                 offset = ReferenceInfoUtil.IGNORE_VALUE),
  86         @TADescription(annotation = "CTB", type = METHOD_REFERENCE,
  87                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  88                 genericLocation = { 3, 0 }),
  89         @TADescription(annotation = "CTC", type = METHOD_REFERENCE,
  90                 offset = ReferenceInfoUtil.IGNORE_VALUE,
  91                 genericLocation = { 3, 1 })
  92     })
  93     public String returnMethodRef3() {
  94         return
  95                 "class Lambda<S, T> {" +
  96                 "  public String getName() { return \"Lambda!\"; }" +
  97                 "}" +
  98 
  99                 "@Target(ElementType.TYPE_USE)" +
 100                 "@interface CTA {" +
 101                 "  String value();" +
 102                 "}" +
 103 
 104                 "@Target(ElementType.TYPE_USE)" +
 105                 "@interface CTB {" +
 106                 "  int age();" +
 107                 "}" +
 108 
 109                 "@Target(ElementType.TYPE_USE)" +
 110                 "@interface CTC {" +
 111                 "  String name();" +
 112                 "}" +
 113 
 114                 "class Test {" +
 115                 "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
 116                 "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::getName;" +
 117                 "  }" +
 118                 "}";
 119     }
 120 
 121 
 122     @TADescriptions({
 123         @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
 124                 offset = ReferenceInfoUtil.IGNORE_VALUE),
 125         @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
 126                 offset = ReferenceInfoUtil.IGNORE_VALUE)
 127     })
 128     public String returnConstructorRef1() {
 129         return
 130                 "class Lambda {" +
 131                 "  Lambda() { }" +
 132                 "}" +
 133 
 134                 "class Test {" +
 135                 "  Runnable lambda() {" +
 136                 "    return @TA @TB Lambda::new;" +
 137                 "  }" +
 138                 "}";
 139     }
 140 
 141     @TADescriptions({
 142         @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
 143                 offset = ReferenceInfoUtil.IGNORE_VALUE),
 144         @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
 145                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 146                 genericLocation = { 3, 0 }),
 147         @TADescription(annotation = "TC", type = CONSTRUCTOR_REFERENCE,
 148                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 149                 genericLocation = { 3, 0 }),
 150         @TADescription(annotation = "TD", type = CONSTRUCTOR_REFERENCE,
 151                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 152                 genericLocation = { 3, 1 }),
 153         @TADescription(annotation = "TE", type = CONSTRUCTOR_REFERENCE,
 154                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 155                 genericLocation = { 3, 1 })
 156     })
 157     public String returnConstructorRef2() {
 158         return
 159                 "class Lambda<S, T> {" +
 160                 "  Lambda() { }" +
 161                 "}" +
 162 
 163                 "class Test {" +
 164                 "  Runnable lambda() {" +
 165                 "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::new;" +
 166                 "  }" +
 167                 "}";
 168     }
 169 
 170     @TADescriptions({
 171         @TADescription(annotation = "CTA", type = CONSTRUCTOR_REFERENCE,
 172                 offset = ReferenceInfoUtil.IGNORE_VALUE),
 173         @TADescription(annotation = "CTB", type = CONSTRUCTOR_REFERENCE,
 174                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 175                 genericLocation = { 3, 0 }),
 176         @TADescription(annotation = "CTC", type = CONSTRUCTOR_REFERENCE,
 177                 offset = ReferenceInfoUtil.IGNORE_VALUE,
 178                 genericLocation = { 3, 1 })
 179     })
 180     public String returnConstructorRef3() {
 181         return
 182                 "class Lambda<S, T> {" +
 183                 "  Lambda() { }" +
 184                 "}" +
 185 
 186                 "@Target(ElementType.TYPE_USE)" +
 187                 "@interface CTA {" +
 188                 "  String value();" +
 189                 "}" +
 190 
 191                 "@Target(ElementType.TYPE_USE)" +
 192                 "@interface CTB {" +
 193                 "  int age();" +
 194                 "}" +
 195 
 196                 "@Target(ElementType.TYPE_USE)" +
 197                 "@interface CTC {" +
 198                 "  String name();" +
 199                 "}" +
 200 
 201                 "class Test {" +
 202                 "  Runnable lambda() {" +
 203                 "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::new;" +
 204                 "  }" +
 205                 "}";
 206     }
 207 
 208 
 209     @TADescriptions({
 210         @TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
 211                  offset = ReferenceInfoUtil.IGNORE_VALUE,
 212                  typeIndex = 0),
 213         @TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
 214                  offset = ReferenceInfoUtil.IGNORE_VALUE,
 215                  typeIndex = 1)
 216     })
 217     public String returnMethodRefTA1() {
 218         return
 219                 "interface Lambda {" +
 220                 "  <S, T> void generic(S p1, T p2);" +
 221                 "}" +
 222 
 223                 "class LambdaImpl implements Lambda {" +
 224                 "  public <S, T> void generic(S p1, T p2) {}" +
 225                 "}" +
 226 
 227                 "class Test {" +
 228                 "  Lambda lambda(LambdaImpl r) {" +
 229                 "    return r::<@TA Object, @TB Object>generic;" +
 230                 "  }" +
 231                 "}";
 232     }
 233 
 234     @TADescriptions({
 235         @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
 236                  offset = ReferenceInfoUtil.IGNORE_VALUE,
 237                  typeIndex = 0),
 238         @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
 239                  offset = ReferenceInfoUtil.IGNORE_VALUE,
 240                  typeIndex = 1)
 241     })
 242     public String returnConstructorRefTA2() {
 243         return
 244                 "interface Lambda {" +
 245                 "  <S, T> void generic(S p1, T p2);" +
 246                 "}" +
 247 
 248                 "class LambdaImpl implements Lambda {" +
 249                 "  <S, T> LambdaImpl(S p1, T p2) {}" +
 250                 "  public <S, T> void generic(S p1, T p2) {}" +
 251                 "}" +
 252 
 253                 "class Test {" +
 254                 "  Lambda lambda() {" +
 255                 "    return LambdaImpl::<@TA Object, @TB Object>new;" +
 256                 "  }" +
 257                 "}";
 258     }
 259 
 260 }