1 /*
2  * Copyright (c) 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.  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 /**
27  * Provides interfaces for creating tools, such as a Read-Eval-Print Loop (REPL),
28  * which interactively evaluate "snippets" of Java programming language code.
29  * Where a "snippet" is a single expression, statement, or declaration.
30  * This functionality can be used to enhance tools such as IDEs or can be
31  * stand-alone.
32  * <p>
33  * {@link jdk.jshell.JShell} is the central class.  An instance of
34  * <code>JShell</code> holds the evaluation state, which is both the current
35  * set of source snippets and the execution state they have produced.
36  * <p>
37  * Each source snippet is represented by an instance of a subclass of
38  * {@link jdk.jshell.Snippet}. For example, a statement is represented by an
39  * instance of {@link jdk.jshell.StatementSnippet}, and a method declaration is
40  * represented by an instance of {@link jdk.jshell.MethodSnippet}.
41  * Snippets are created when
42  * {@link jdk.jshell.JShell#eval(java.lang.String) JShell.eval(String)}
43  * is invoked with an input which includes one or more snippets of code.
44  * <p>
45  * Any change to the compilation status of a snippet is reported with a
46  * {@link jdk.jshell.SnippetEvent}.  There are three major kinds of
47  * changes to the status of a snippet: it can created with <code>eval</code>,
48  * it can be dropped from the active source state with
49  * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet)}, and it can have
50  * its status updated as a result of a status change in another snippet.
51  * For
52  * example: given <code>js</code>, an instance of <code>JShell</code>, executing
53  * <code>js.eval("int x = 5;")</code> will add the variable <code>x</code> to
54  * the source state and will generate an event describing the creation of a
55  * {@link jdk.jshell.VarSnippet} for <code>x</code>. Then executing
56  * <code>js.eval("int timesx(int val) { return val * x; }")</code> will add
57  * a method to the source state and will generate an event
58  * describing the creation of a {@link jdk.jshell.MethodSnippet} for
59  * <code>timesx</code>.
60  * Assume that <code>varx</code> holds the snippet created by the first
61  * call to <code>eval</code>, executing <code>js.drop(varx)</code> will
62  * generate two events: one for changing the status of the
63  * variable snippet to <code>DROPPED</code> and one for
64  * updating the method snippet (which now has an unresolved reference to
65  * <code>x</code>).
66  * <p>
67  * Of course, for any general application of the API, the input would not be
68  * fixed strings, but would come from the user. Below is a very simplified
69  * example of how the API might be used to implement a REPL.
70  * <pre>
71 * {@code
72  *     import java.io.ByteArrayInputStream;
73  *     import java.io.Console;
74  *     import java.util.List;
75  *     import jdk.jshell.*;
76  *     import jdk.jshell.Snippet.Status;
77  *
78  *     class ExampleJShell {
79  *         public static void main(String[] args) {
80  *             Console console = System.console();
81  *             try (JShell js = JShell.create()) {
82  *                 do {
83  *                     System.out.print("Enter some Java code: ");
84  *                     String input = console.readLine();
85  *                     if (input == null) {
86  *                         break;
87  *                     }
88  *                     List<SnippetEvent> events = js.eval(input);
89  *                     for (SnippetEvent e : events) {
90  *                         StringBuilder sb = new StringBuilder();
91  *                         if (e.causeSnippet == null) {
92  *                             //  We have a snippet creation event
93  *                             switch (e.status) {
94  *                                 case VALID:
95  *                                     sb.append("Successful ");
96  *                                     break;
97  *                                 case RECOVERABLE_DEFINED:
98  *                                     sb.append("With unresolved references ");
99  *                                     break;
100  *                                 case RECOVERABLE_NOT_DEFINED:
101  *                                     sb.append("Possibly reparable, failed  ");
102  *                                     break;
103  *                                 case REJECTED:
104  *                                     sb.append("Failed ");
105  *                                     break;
106  *                             }
107  *                             if (e.previousStatus == Status.NONEXISTENT) {
108  *                                 sb.append("addition");
109  *                             } else {
110  *                                 sb.append("modification");
111  *                             }
112  *                             sb.append(" of ");
113  *                             sb.append(e.snippet.source());
114  *                             System.out.println(sb);
115  *                             if (e.value != null) {
116  *                                 System.out.printf("Value is: %s\n", e.value);
117  *                             }
118  *                             System.out.flush();
119  *                         }
120  *                     }
121  *                 } while (true);
122  *             }
123  *             System.out.println("\nGoodbye");
124  *         }
125  *     }
126  * }
127  * </pre>
128  * <p>
129  * To register for status change events use
130  * {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer)}.
131  * These events are only generated by <code>eval</code> and <code>drop</code>,
132  * the return values of these methods are the list of events generated by that
133  * call.  So, as in the example above, events can be used without registering
134  * to receive events.
135  * <p>
136  * If you experiment with this example, you will see that failing to terminate
137  * a statement or variable declaration with a semi-colon will simply fail.
138  * An unfinished entry (for example a desired multi-line method) will also just
139  * fail after one line.  The utilities in {@link jdk.jshell.SourceCodeAnalysis}
140  * provide source boundary and completeness analysis to address cases like
141  * those.  <code>SourceCodeAnalysis</code> also provides suggested completions
142  * of input, as might be used in tab-completion.
143  *
144  * @since 9
145  */
146 
147 
148 package jdk.jshell;
149 
150