1/*
2 * Copyright (c) 2013, 2015, 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/*
25 * @test
26 * @bug 8008077 8029721 8042451 8043974
27 * @summary Test population of reference info for lambda expressions
28 *          javac crash for annotated parameter type of lambda in a field
29 * @modules jdk.jdeps/com.sun.tools.classfile
30 * @ignore 8057687 emit correct byte code an attributes for type annotations
31 * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
32 * @run main Driver Lambda
33 * @author Werner Dietl
34 */
35
36import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
37
38public class Lambda {
39
40    @TADescription(annotation = "TA", type = METHOD_REFERENCE,
41                offset = ReferenceInfoUtil.IGNORE_VALUE)
42    @TADescription(annotation = "TB", type = METHOD_REFERENCE,
43                offset = ReferenceInfoUtil.IGNORE_VALUE)
44    public String returnMethodRef1() {
45        return
46                "class Lambda {" +
47                "  public String getName() { return \"Lambda!\"; }" +
48                "}" +
49
50                "class %TEST_CLASS_NAME% {" +
51                "  java.util.function.Function<Lambda, String> lambda() {" +
52                "    return @TA @TB Lambda::getName;" +
53                "  }" +
54                "}";
55    }
56
57    @TADescription(annotation = "TA", type = METHOD_REFERENCE,
58                offset = ReferenceInfoUtil.IGNORE_VALUE)
59    @TADescription(annotation = "TB", type = METHOD_REFERENCE,
60                offset = ReferenceInfoUtil.IGNORE_VALUE,
61                genericLocation = { 3, 0 })
62    @TADescription(annotation = "TC", type = METHOD_REFERENCE,
63                offset = ReferenceInfoUtil.IGNORE_VALUE,
64                genericLocation = { 3, 0 })
65    @TADescription(annotation = "TD", type = METHOD_REFERENCE,
66                offset = ReferenceInfoUtil.IGNORE_VALUE,
67                genericLocation = { 3, 1 })
68    @TADescription(annotation = "TE", type = METHOD_REFERENCE,
69                offset = ReferenceInfoUtil.IGNORE_VALUE,
70                genericLocation = { 3, 1})
71    public String returnMethodRef2() {
72        return
73                "class Lambda<S, T> {" +
74                "  public String getName() { return \"Lambda!\"; }" +
75                "}" +
76
77                "class %TEST_CLASS_NAME% {" +
78                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
79                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::getName;" +
80                "  }" +
81                "}";
82    }
83
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    public String returnMethodRef3() {
93        return
94                "class Lambda<S, T> {" +
95                "  public String getName() { return \"Lambda!\"; }" +
96                "}" +
97
98                "@Target(ElementType.TYPE_USE)" +
99                "@interface CTA {" +
100                "  String value();" +
101                "}" +
102
103                "@Target(ElementType.TYPE_USE)" +
104                "@interface CTB {" +
105                "  int age();" +
106                "}" +
107
108                "@Target(ElementType.TYPE_USE)" +
109                "@interface CTC {" +
110                "  String name();" +
111                "}" +
112
113                "class %TEST_CLASS_NAME% {" +
114                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
115                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::getName;" +
116                "  }" +
117                "}";
118    }
119
120
121    @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
122                offset = ReferenceInfoUtil.IGNORE_VALUE)
123    @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
124                offset = ReferenceInfoUtil.IGNORE_VALUE)
125    public String returnConstructorRef1() {
126        return
127                "class Lambda {" +
128                "  Lambda() { }" +
129                "}" +
130
131                "class %TEST_CLASS_NAME% {" +
132                "  Runnable lambda() {" +
133                "    return @TA @TB Lambda::new;" +
134                "  }" +
135                "}";
136    }
137
138    @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
139                offset = ReferenceInfoUtil.IGNORE_VALUE)
140    @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
141                offset = ReferenceInfoUtil.IGNORE_VALUE,
142                genericLocation = { 3, 0 })
143    @TADescription(annotation = "TC", type = CONSTRUCTOR_REFERENCE,
144                offset = ReferenceInfoUtil.IGNORE_VALUE,
145                genericLocation = { 3, 0 })
146    @TADescription(annotation = "TD", type = CONSTRUCTOR_REFERENCE,
147                offset = ReferenceInfoUtil.IGNORE_VALUE,
148                genericLocation = { 3, 1 })
149    @TADescription(annotation = "TE", type = CONSTRUCTOR_REFERENCE,
150                offset = ReferenceInfoUtil.IGNORE_VALUE,
151                genericLocation = { 3, 1    })
152    public String returnConstructorRef2() {
153        return
154                "class Lambda<S, T> {" +
155                "  Lambda() { }" +
156                "}" +
157
158                "class %TEST_CLASS_NAME% {" +
159                "  Runnable lambda() {" +
160                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::new;" +
161                "  }" +
162                "}";
163    }
164
165    @TADescription(annotation = "CTA", type = CONSTRUCTOR_REFERENCE,
166                offset = ReferenceInfoUtil.IGNORE_VALUE)
167    @TADescription(annotation = "CTB", type = CONSTRUCTOR_REFERENCE,
168                offset = ReferenceInfoUtil.IGNORE_VALUE,
169                genericLocation = { 3, 0 })
170    @TADescription(annotation = "CTC", type = CONSTRUCTOR_REFERENCE,
171                offset = ReferenceInfoUtil.IGNORE_VALUE,
172                genericLocation = { 3, 1    })
173    public String returnConstructorRef3() {
174        return
175                "class Lambda<S, T> {" +
176                "  Lambda() { }" +
177                "}" +
178
179                "@Target(ElementType.TYPE_USE)" +
180                "@interface CTA {" +
181                "  String value();" +
182                "}" +
183
184                "@Target(ElementType.TYPE_USE)" +
185                "@interface CTB {" +
186                "  int age();" +
187                "}" +
188
189                "@Target(ElementType.TYPE_USE)" +
190                "@interface CTC {" +
191                "  String name();" +
192                "}" +
193
194                "class %TEST_CLASS_NAME% {" +
195                "  Runnable lambda() {" +
196                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::new;" +
197                "  }" +
198                "}";
199    }
200
201
202    @TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
203                 offset = ReferenceInfoUtil.IGNORE_VALUE,
204                 typeIndex = 0)
205    @TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
206                 offset = ReferenceInfoUtil.IGNORE_VALUE,
207                 typeIndex = 1)
208    public String returnMethodRefTA1() {
209        return
210                "interface Lambda {" +
211                "  <S, T> void generic(S p1, T p2);" +
212                "}" +
213
214                "class LambdaImpl implements Lambda {" +
215                "  public <S, T> void generic(S p1, T p2) {}" +
216                "}" +
217
218                "class %TEST_CLASS_NAME% {" +
219                "  Lambda lambda(LambdaImpl r) {" +
220                "    return r::<@TA Object, @TB Object>generic;" +
221                "  }" +
222                "}";
223    }
224
225    @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
226                 offset = ReferenceInfoUtil.IGNORE_VALUE,
227                 typeIndex = 0)
228    @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
229                 offset = ReferenceInfoUtil.IGNORE_VALUE,
230                 typeIndex = 1)
231    public String returnConstructorRefTA2() {
232        return
233                "interface Lambda {" +
234                "  <S, T> void generic(S p1, T p2);" +
235                "}" +
236
237                "class LambdaImpl implements Lambda {" +
238                "  <S, T> LambdaImpl(S p1, T p2) {}" +
239                "  public <S, T> void generic(S p1, T p2) {}" +
240                "}" +
241
242                "class %TEST_CLASS_NAME% {" +
243                "  Lambda lambda() {" +
244                "    return LambdaImpl::<@TA Object, @TB Object>new;" +
245                "  }" +
246                "}";
247    }
248
249    @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
250                paramIndex = 0)
251    @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
252                paramIndex = 1)
253    @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
254                paramIndex = 1, genericLocation = { 3, 0 })
255    @TADescription(annotation = "TD", type = LOCAL_VARIABLE,
256                lvarOffset = ReferenceInfoUtil.IGNORE_VALUE,
257                lvarLength = ReferenceInfoUtil.IGNORE_VALUE,
258                lvarIndex = ReferenceInfoUtil.IGNORE_VALUE)
259    @TADescription(annotation = "TE", type = CAST,
260                offset = ReferenceInfoUtil.IGNORE_VALUE,
261                typeIndex = 0)
262    public String returnLambdaExpr1() {
263        return
264                "interface LambdaInt {" +
265                "  void lambda(Object p1, List<Object> p2);" +
266                "}" +
267                "class %TEST_CLASS_NAME% {" +
268                "  LambdaInt getLambda() {" +
269                "    return (@TA Object x, @TB List<@TC Object> y) -> { @TD Object l = null; System.out.println((@TE Object) l); };" +
270                "  }" +
271                "}";
272    }
273
274    @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
275            paramIndex = 0)
276    public String lambdaField1() {
277        return
278            "class %TEST_CLASS_NAME% {" +
279                " java.util.function.IntUnaryOperator field = (@TA int y) -> 1;" +
280            "}";
281    }
282
283    @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
284            paramIndex = 0)
285    public String lambdaField2() {
286        return
287            "class %TEST_CLASS_NAME% {" +
288                " static java.util.function.IntUnaryOperator field = (@TA int y) -> 1;" +
289            "}";
290    }
291
292    @TADescription(annotation = "RTAs", type = METHOD_REFERENCE,
293            offset = ReferenceInfoUtil.IGNORE_VALUE)
294    public String returnMethodRefRepeatableAnnotation1() {
295        return
296                "class Lambda {" +
297                        "  public String getName() { return \"Lambda!\"; }" +
298                        "}" +
299
300                        "class %TEST_CLASS_NAME% {" +
301                        "  java.util.function.Function<Lambda, String> lambda() {" +
302                        "    return @RTA @RTA Lambda::getName;" +
303                        "  }" +
304                        "}";
305    }
306
307    @TADescription(annotation = "RTAs", type = METHOD_REFERENCE,
308            offset = ReferenceInfoUtil.IGNORE_VALUE)
309    @TADescription(annotation = "RTBs", type = METHOD_REFERENCE,
310            offset = ReferenceInfoUtil.IGNORE_VALUE,
311            genericLocation = { 3, 0 })
312    @TADescription(annotation = "RTCs", type = METHOD_REFERENCE,
313            offset = ReferenceInfoUtil.IGNORE_VALUE,
314            genericLocation = { 3, 0 })
315    @TADescription(annotation = "RTDs", type = METHOD_REFERENCE,
316            offset = ReferenceInfoUtil.IGNORE_VALUE,
317            genericLocation = { 3, 1 })
318    @TADescription(annotation = "RTEs", type = METHOD_REFERENCE,
319            offset = ReferenceInfoUtil.IGNORE_VALUE,
320            genericLocation = { 3, 1})
321    public String returnMethodRefRepeatableAnnotation2() {
322        return
323                "class Lambda<S, T> {" +
324                        "  public String getName() { return \"Lambda!\"; }" +
325                        "}" +
326
327                        "class %TEST_CLASS_NAME% {" +
328                        "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
329                        "    return @RTA @RTA Lambda<@RTB @RTB @RTC @RTC Integer, @RTD @RTD @RTE @RTE Float>::getName;" +
330                        "  }" +
331                        "}";
332    }
333
334    @TADescription(annotation = "RTAs", type = CONSTRUCTOR_REFERENCE,
335            offset = ReferenceInfoUtil.IGNORE_VALUE)
336    public String returnConstructorRefRepeatable1() {
337        return
338                "class Lambda {" +
339                        "  Lambda() { }" +
340                        "}" +
341
342                        "class %TEST_CLASS_NAME% {" +
343                        "  Runnable lambda() {" +
344                        "    return @RTA @RTA Lambda::new;" +
345                        "  }" +
346                        "}";
347    }
348
349    @TADescription(annotation = "RTAs", type = CONSTRUCTOR_REFERENCE,
350            offset = ReferenceInfoUtil.IGNORE_VALUE)
351    @TADescription(annotation = "RTBs", type = CONSTRUCTOR_REFERENCE,
352            offset = ReferenceInfoUtil.IGNORE_VALUE,
353            genericLocation = { 3, 0 })
354    @TADescription(annotation = "RTCs", type = CONSTRUCTOR_REFERENCE,
355            offset = ReferenceInfoUtil.IGNORE_VALUE,
356            genericLocation = { 3, 1    })
357    public String returnConstructorRefRepeatable2() {
358        return
359                "class Lambda<S, T> {" +
360                        "  Lambda() { }" +
361                        "}" +
362
363                        "class %TEST_CLASS_NAME% {" +
364                        "  Runnable lambda() {" +
365                        "    return @RTA @RTA Lambda<@RTB @RTB Integer, @RTC @RTC Float>::new;" +
366                        "  }" +
367                        "}";
368    }
369
370    @TADescription(annotation = "RTAs", type = METHOD_REFERENCE_TYPE_ARGUMENT,
371            offset = ReferenceInfoUtil.IGNORE_VALUE,
372            typeIndex = 0)
373    @TADescription(annotation = "RTBs", type = METHOD_REFERENCE_TYPE_ARGUMENT,
374            offset = ReferenceInfoUtil.IGNORE_VALUE,
375            typeIndex = 1)
376    public String returnMethodRefTARepeatableAnnotation1() {
377        return
378                "interface Lambda {" +
379                        "  <S, T> void generic(S p1, T p2);" +
380                        "}" +
381
382                        "class LambdaImpl implements Lambda {" +
383                        "  public <S, T> void generic(S p1, T p2) {}" +
384                        "}" +
385
386                        "class %TEST_CLASS_NAME% {" +
387                        "  Lambda lambda(LambdaImpl r) {" +
388                        "    return r::<@RTA @RTA Object, @RTB @RTB Object>generic;" +
389                        "  }" +
390                        "}";
391    }
392
393    @TADescription(annotation = "RTAs", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
394            offset = ReferenceInfoUtil.IGNORE_VALUE,
395            typeIndex = 0)
396    @TADescription(annotation = "RTBs", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
397            offset = ReferenceInfoUtil.IGNORE_VALUE,
398            typeIndex = 1)
399    public String returnConstructorRefTARepeatableAnnotation2() {
400        return
401                "interface Lambda {" +
402                        "  <S, T> void generic(S p1, T p2);" +
403                        "}" +
404
405                        "class LambdaImpl implements Lambda {" +
406                        "  <S, T> LambdaImpl(S p1, T p2) {}" +
407                        "  public <S, T> void generic(S p1, T p2) {}" +
408                        "}" +
409
410                        "class %TEST_CLASS_NAME% {" +
411                        "  Lambda lambda() {" +
412                        "    return LambdaImpl::<@RTA @RTA Object, @RTB @RTB Object>new;" +
413                        "  }" +
414                        "}";
415    }
416
417    @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER,
418            paramIndex = 0)
419    @TADescription(annotation = "RTBs", type = METHOD_FORMAL_PARAMETER,
420            paramIndex = 1)
421    @TADescription(annotation = "RTCs", type = METHOD_FORMAL_PARAMETER,
422            paramIndex = 1, genericLocation = { 3, 0 })
423    @TADescription(annotation = "RTDs", type = LOCAL_VARIABLE,
424            lvarOffset = ReferenceInfoUtil.IGNORE_VALUE,
425            lvarLength = ReferenceInfoUtil.IGNORE_VALUE,
426            lvarIndex = ReferenceInfoUtil.IGNORE_VALUE)
427    @TADescription(annotation = "RTEs", type = CAST,
428            offset = ReferenceInfoUtil.IGNORE_VALUE,
429            typeIndex = 0)
430    public String returnLambdaExprRepeatableAnnotation1() {
431        return
432                "interface LambdaInt {" +
433                        "  void lambda(Object p1, List<Object> p2);" +
434                        "}" +
435                        "class %TEST_CLASS_NAME% {" +
436                        "  LambdaInt getLambda() {" +
437                        "    return (@RTA @RTA Object x, @RTB @RTB List<@RTC @RTC Object> y) ->" +
438                        " { @RTD @RTD Object l = null; System.out.println((@RTE @RTE Object) l); };" +
439                        "  }" +
440                        "}";
441    }
442
443    @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER,
444            paramIndex = 0)
445    public String lambdaFieldRepeatableAnnotation1() {
446        return
447                "class %TEST_CLASS_NAME% {" +
448                        " java.util.function.IntUnaryOperator field = (@RTA @RTA int y) -> 1;" +
449                        "}";
450    }
451
452    @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER,
453            paramIndex = 0)
454    public String lambdaFieldRepeatableAnnotation2() {
455        return
456                "class %TEST_CLASS_NAME% {" +
457                        " static java.util.function.IntUnaryOperator field = (@RTA @RTA int y) -> 1;" +
458                        "}";
459    }
460}
461