| /* |
| * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /** |
| * Provides interfaces for creating tools, such as a Read-Eval-Print Loop (REPL), |
| * which interactively evaluate "snippets" of Java programming language code. |
| * Where a "snippet" is a single expression, statement, or declaration. |
| * This functionality can be used to enhance tools such as IDEs or can be |
| * stand-alone. |
| * <p> |
| * {@link jdk.jshell.JShell} is the central class. An instance of |
| * <code>JShell</code> holds the evaluation state, which is both the current |
| * set of source snippets and the execution state they have produced. |
| * <p> |
| * Each source snippet is represented by an instance of a subclass of |
| * {@link jdk.jshell.Snippet}. For example, a statement is represented by an |
| * instance of {@link jdk.jshell.StatementSnippet}, and a method declaration is |
| * represented by an instance of {@link jdk.jshell.MethodSnippet}. |
| * Snippets are created when |
| * {@link jdk.jshell.JShell#eval(java.lang.String) JShell.eval(String)} |
| * is invoked with an input which includes one or more snippets of code. |
| * <p> |
| * Any change to the compilation status of a snippet is reported with a |
| * {@link jdk.jshell.SnippetEvent}. There are three major kinds of |
| * changes to the status of a snippet: it can created with <code>eval</code>, |
| * it can be dropped from the active source state with |
| * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet)}, and it can have |
| * its status updated as a result of a status change in another snippet. |
| * For |
| * example: given <code>js</code>, an instance of <code>JShell</code>, executing |
| * <code>js.eval("int x = 5;")</code> will add the variable <code>x</code> to |
| * the source state and will generate an event describing the creation of a |
| * {@link jdk.jshell.VarSnippet} for <code>x</code>. Then executing |
| * <code>js.eval("int timesx(int val) { return val * x; }")</code> will add |
| * a method to the source state and will generate an event |
| * describing the creation of a {@link jdk.jshell.MethodSnippet} for |
| * <code>timesx</code>. |
| * Assume that <code>varx</code> holds the snippet created by the first |
| * call to <code>eval</code>, executing <code>js.drop(varx)</code> will |
| * generate two events: one for changing the status of the |
| * variable snippet to <code>DROPPED</code> and one for |
| * updating the method snippet (which now has an unresolved reference to |
| * <code>x</code>). |
| * <p> |
| * Of course, for any general application of the API, the input would not be |
| * fixed strings, but would come from the user. Below is a very simplified |
| * example of how the API might be used to implement a REPL. |
| * <pre> |
| * {@code |
| * import java.io.ByteArrayInputStream; |
| * import java.io.Console; |
| * import java.util.List; |
| * import jdk.jshell.*; |
| * import jdk.jshell.Snippet.Status; |
| * |
| * class ExampleJShell { |
| * public static void main(String[] args) { |
| * Console console = System.console(); |
| * try (JShell js = JShell.create()) { |
| * do { |
| * System.out.print("Enter some Java code: "); |
| * String input = console.readLine(); |
| * if (input == null) { |
| * break; |
| * } |
| * List<SnippetEvent> events = js.eval(input); |
| * for (SnippetEvent e : events) { |
| * StringBuilder sb = new StringBuilder(); |
| * if (e.causeSnippet == null) { |
| * // We have a snippet creation event |
| * switch (e.status) { |
| * case VALID: |
| * sb.append("Successful "); |
| * break; |
| * case RECOVERABLE_DEFINED: |
| * sb.append("With unresolved references "); |
| * break; |
| * case RECOVERABLE_NOT_DEFINED: |
| * sb.append("Possibly reparable, failed "); |
| * break; |
| * case REJECTED: |
| * sb.append("Failed "); |
| * break; |
| * } |
| * if (e.previousStatus == Status.NONEXISTENT) { |
| * sb.append("addition"); |
| * } else { |
| * sb.append("modification"); |
| * } |
| * sb.append(" of "); |
| * sb.append(e.snippet.source()); |
| * System.out.println(sb); |
| * if (e.value != null) { |
| * System.out.printf("Value is: %s\n", e.value); |
| * } |
| * System.out.flush(); |
| * } |
| * } |
| * } while (true); |
| * } |
| * System.out.println("\nGoodbye"); |
| * } |
| * } |
| * } |
| * </pre> |
| * <p> |
| * To register for status change events use |
| * {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer)}. |
| * These events are only generated by <code>eval</code> and <code>drop</code>, |
| * the return values of these methods are the list of events generated by that |
| * call. So, as in the example above, events can be used without registering |
| * to receive events. |
| * <p> |
| * If you experiment with this example, you will see that failing to terminate |
| * a statement or variable declaration with a semi-colon will simply fail. |
| * An unfinished entry (for example a desired multi-line method) will also just |
| * fail after one line. The utilities in {@link jdk.jshell.SourceCodeAnalysis} |
| * provide source boundary and completeness analysis to address cases like |
| * those. <code>SourceCodeAnalysis</code> also provides suggested completions |
| * of input, as might be used in tab-completion. |
| * |
| * @since 9 |
| */ |
| |
| |
| package jdk.jshell; |
| |