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 148package jdk.jshell; 149 150