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.  Oracle designates this
 8  * particular file as subject to the "Classpath" exception as provided
 9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.incubator.code;
27 
28 import java.util.*;
29 
30 /**
31  * The quoted form of an operation.
32  * <p>
33  * The quoted form is utilized when the code model of some code is to be obtained rather than obtaining the result of
34  * executing that code. For example passing the of a lambda expression in quoted form rather than the expression being
35  * targeted to a functional interface from which it can be invoked.
36  */
37 public final class Quoted {
38     private final Op op;
39     private final SequencedMap<Value, Object> capturedValues;
40 
41     static final SequencedMap<Value, Object> EMPTY_SEQUENCED_MAP = new LinkedHashMap<>();
42 
43     /**
44      * Constructs the quoted form of a given operation.
45      *
46      * @param op the invokable operation.
47      */
48     public Quoted(Op op) {
49         this(op, EMPTY_SEQUENCED_MAP);
50     }
51 
52     /**
53      * Constructs the quoted form of a given operation.
54      * <p>
55      * The captured values key set must have the same elements and same encounter order as
56      * operation's captured values, specifically the following expression should evaluate to true:
57      * {@snippet lang=java :
58      * op.capturedValues().equals(new ArrayList<>(capturedValues.keySet()));
59      * }
60      *
61      * @param op             the operation.
62      * @param capturedValues the captured values referred to by the operation
63      * @see Op#capturedValues()
64      */
65     public Quoted(Op op, SequencedMap<Value, Object> capturedValues) {
66         // @@@ This check is potentially expensive, remove or keep as assert?
67         // @@@ Or make Quoted an interface, with a module private implementation?
68         assert op.capturedValues().equals(new ArrayList<>(capturedValues.keySet()));
69         this.op = op;
70         this.capturedValues = Collections.unmodifiableSequencedMap(new LinkedHashMap<>(capturedValues));
71     }
72 
73     /**
74      * Returns the operation.
75      *
76      * @return the operation.
77      */
78     public Op op() {
79         return op;
80     }
81 
82     /**
83      * Returns the captured values.
84      * <p>
85      * The captured values key set has the same elements and same encounter order as
86      * operation's captured values, specifically the following expression evaluates to true:
87      * {@snippet lang=java :
88      * op().capturedValues().equals(new ArrayList<>(capturedValues().keySet()));
89      * }
90      *
91      * @return the captured values, as an unmodifiable map.
92      */
93     public SequencedMap<Value, Object> capturedValues() {
94         return capturedValues;
95     }
96 }