1 /*
2 * Copyright (c) 2026, 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 * @summary Test for local class creation in early construction context
27 * @modules jdk.incubator.code
28 */
29 import jdk.incubator.code.Op;
30 import jdk.incubator.code.Reflect;
31 import jdk.incubator.code.extern.OpWriter;
32
33 public class LocalClassInEarlyContext {
34 static class TestNoCapture {
35 TestNoCapture() {
36 class Foo {
37 void t() { }
38 }
39 check((@Reflect Runnable)() -> new Foo(), EXPECTED);
40 super();
41 }
42
43 static final String EXPECTED =
44 """
45 %0 : java.type:"java.lang.Runnable" = lambda @lambda.isReflectable=true ()java.type:"void" -> {
46 %1 : java.type:"LocalClassInEarlyContext$TestNoCapture::$1Foo" = new @java.ref:"LocalClassInEarlyContext$TestNoCapture::$1Foo::()";
47 return;
48 };
49 """;
50 }
51
52 static class TestCapture {
53 TestCapture(int i, String s) {
54 final long L = 42L; // this should NOT be captured
55 class Foo {
56 long t() {
57 return i + s.length() + L;
58 }
59 }
60 check((@Reflect Runnable)() -> new Foo(), EXPECTED);
61 super();
62 }
63
64 static final String EXPECTED =
65 """
66 %0 : java.type:"java.lang.Runnable" = lambda @lambda.isReflectable=true ()java.type:"void" -> {
67 %1 : java.type:"int" = var.load %2;
68 %3 : java.type:"java.lang.String" = var.load %4;
69 %5 : java.type:"LocalClassInEarlyContext$TestCapture::$1Foo" = new %1 %3 @java.ref:"LocalClassInEarlyContext$TestCapture::$1Foo::(int, java.lang.String)";
70 return;
71 };
72 """;
73 }
74
75 public static void main(String[] args) {
76 new TestNoCapture();
77 new TestCapture(1, "");
78 }
79
80 static void check(Runnable r, String expected) {
81 expected = expected.trim();
82 var quoted = Op.ofLambda(r).get();
83 var found = OpWriter.toText(quoted.op(), OpWriter.LocationOption.DROP_LOCATION);
84 if (!found.equals(expected)) {
85 throw new AssertionError("Model mismatch. Found:\n" + found + "\nExpected:\n" + expected);
86 }
87 }
88 }