1 /*
2 * Copyright (c) 2024, 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 * @modules jdk.incubator.code
27 * @run junit TestVarOp
28 */
29
30 import jdk.incubator.code.CodeReflection;
31 import jdk.incubator.code.Op;
32 import jdk.incubator.code.OpTransformer;
33 import jdk.incubator.code.Value;
34 import jdk.incubator.code.dialect.core.CoreOp;
35 import jdk.incubator.code.dialect.core.CoreType;
36 import jdk.incubator.code.dialect.java.JavaOp;
37 import jdk.incubator.code.dialect.java.JavaType;
38 import jdk.incubator.code.extern.OpParser;
39 import org.junit.jupiter.api.Assertions;
40 import org.junit.jupiter.api.Test;
41
42 import java.lang.reflect.Method;
43 import java.util.List;
44 import java.util.Optional;
45 import java.util.stream.Stream;
46
47 public class TestVarOp {
48
49 @CodeReflection
50 static Object f(String s) {
51 Object o = s;
52 return o;
53 }
54
55 @Test
56 public void testTypeSubstitutionAndPreserve() {
57 CoreOp.FuncOp f = getFuncOp("f");
58 CoreOp.FuncOp ft = CoreOp.func("f", CoreType.functionType(JavaType.J_L_OBJECT, JavaType.type(CharSequence.class)))
59 .body(fb -> {
60 fb.body(f.body(), fb.parameters(), OpTransformer.COPYING_TRANSFORMER);
61 });
62
63 List<CoreOp.VarOp> vops = ft.elements()
64 .flatMap(ce -> ce instanceof CoreOp.VarOp vop ? Stream.of(vop) : null)
65 .toList();
66 // VarOp for block parameter, translate from String to CharSequence
67 Assertions.assertEquals(JavaType.type(CharSequence.class), vops.get(0).resultType().valueType());
68 // VarOp for local variable, preserve Object
69 Assertions.assertEquals(JavaType.J_L_OBJECT, vops.get(1).resultType().valueType());
70 }
71
72 @Test
73 public void testNoName() {
74 CoreOp.FuncOp f = getFuncOp("f");
75 f = f.transform((block, op) -> {
76 if (op instanceof CoreOp.VarOp vop) {
77 Value init = block.context().getValue(vop.initOperand());
78 Op.Result v = block.op(CoreOp.var(init));
79 block.context().mapValue(vop.result(), v);
80 } else {
81 block.op(op);
82 }
83 return block;
84 });
85
86 Op op = OpParser.fromString(JavaOp.JAVA_DIALECT_FACTORY, f.toText()).get(0);
87 boolean allNullNames = op.elements()
88 .flatMap(ce -> ce instanceof CoreOp.VarOp vop ? Stream.of(vop) : null)
89 .allMatch(CoreOp.VarOp::isUnnamedVariable);
90 Assertions.assertTrue(allNullNames);
91 }
92
93 static CoreOp.FuncOp getFuncOp(String name) {
94 Optional<Method> om = Stream.of(TestVarOp.class.getDeclaredMethods())
95 .filter(m -> m.getName().equals(name))
96 .findFirst();
97
98 Method m = om.get();
99 return Op.ofMethod(m).get();
100 }
101 }