langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
author ihse
Tue, 09 May 2017 12:55:07 +0200
changeset 45045 834233132ab1
parent 43770 a321bed02000
child 46185 f4c981fc7818
permissions -rw-r--r--
8179889: Fix typographic errors in copyright headers Reviewed-by: erikj, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     1
/*
45045
834233132ab1 8179889: Fix typographic errors in copyright headers
ihse
parents: 43770
diff changeset
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     4
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    10
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    15
 * accompanied this code).
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    16
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    20
 *
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    23
 * questions.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    24
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    25
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    26
package jdk.jshell;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    27
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
    28
import jdk.jshell.spi.ExecutionControl;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    29
import java.io.ByteArrayInputStream;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    30
import java.io.InputStream;
41628
664e7664343d 8167461: jshell tool: Scanner#next() hangs tool
jlahoda
parents: 41514
diff changeset
    31
import java.io.InterruptedIOException;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    32
import java.io.PrintStream;
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
    33
import java.net.InetAddress;
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
    34
import java.text.MessageFormat;
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
    35
import java.util.ArrayList;
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
    36
import java.util.Arrays;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    37
import java.util.Collections;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    38
import java.util.HashMap;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    39
import java.util.List;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    40
import java.util.Map;
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
    41
import java.util.MissingResourceException;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    42
import java.util.Objects;
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
    43
import java.util.ResourceBundle;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    44
import java.util.function.BiFunction;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    45
import java.util.function.Consumer;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    46
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
    47
import java.util.function.Function;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    48
import java.util.function.Supplier;
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
    49
import java.util.stream.Stream;
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
    50
import javax.tools.StandardJavaFileManager;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    51
import jdk.internal.jshell.debug.InternalDebugControl;
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
    52
import jdk.jshell.Snippet.Status;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
    53
import jdk.jshell.spi.ExecutionControl.EngineTerminationException;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
    54
import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
    55
import jdk.jshell.spi.ExecutionControlProvider;
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
    56
import jdk.jshell.spi.ExecutionEnv;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    57
import static jdk.jshell.Util.expunge;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    58
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    59
/**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    60
 * The JShell evaluation state engine.  This is the central class in the JShell
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
    61
 * API.  A {@code JShell} instance holds the evolving compilation and
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    62
 * execution state.  The state is changed with the instance methods
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    63
 * {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
41514
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
    64
 * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop(Snippet)} and
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    65
 * {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    66
 * The majority of methods query the state.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
    67
 * A {@code JShell} instance also allows registering for events with
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    68
 * {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer) onSnippetEvent(Consumer)}
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    69
 * and {@link jdk.jshell.JShell#onShutdown(java.util.function.Consumer) onShutdown(Consumer)}, which
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    70
 * are unregistered with
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    71
 * {@link jdk.jshell.JShell#unsubscribe(jdk.jshell.JShell.Subscription) unsubscribe(Subscription)}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    72
 * Access to the source analysis utilities is via
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    73
 * {@link jdk.jshell.JShell#sourceCodeAnalysis()}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    74
 * When complete the instance should be closed to free resources --
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    75
 * {@link jdk.jshell.JShell#close()}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    76
 * <p>
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
    77
 * An instance of {@code JShell} is created with
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
    78
 * {@code JShell.create()}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    79
 * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    80
 * This class is not thread safe, except as noted, all access should be through
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    81
 * a single thread.
43770
a321bed02000 8174762: JShell: @since tags missing
rfield
parents: 43758
diff changeset
    82
 *
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    83
 * @author Robert Field
43770
a321bed02000 8174762: JShell: @since tags missing
rfield
parents: 43758
diff changeset
    84
 * @since 9
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    85
 */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    86
public class JShell implements AutoCloseable {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    87
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    88
    final SnippetMaps maps;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    89
    final KeyMap keyMap;
37644
33cf53901cac 8154485: JShell: infrastructure for multi-Snippet class wrappers
rfield
parents: 37004
diff changeset
    90
    final OuterWrapMap outerMap;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    91
    final TaskFactory taskFactory;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    92
    final InputStream in;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    93
    final PrintStream out;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    94
    final PrintStream err;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    95
    final Supplier<String> tempVariableNameGenerator;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
    96
    final BiFunction<Snippet, Integer, String> idGenerator;
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
    97
    final List<String> extraRemoteVMOptions;
39369
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
    98
    final List<String> extraCompilerOptions;
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
    99
    final Function<StandardJavaFileManager, StandardJavaFileManager> fileManagerMapping;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   100
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   101
    private int nextKeyIndex = 1;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   102
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   103
    final Eval eval;
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   104
    final ClassTracker classTracker;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   105
    private final Map<Subscription, Consumer<JShell>> shutdownListeners = new HashMap<>();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   106
    private final Map<Subscription, Consumer<SnippetEvent>> keyStatusListeners = new HashMap<>();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   107
    private boolean closed = false;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   108
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   109
    private final ExecutionControl executionControl;
33715
74b1bed86932 8141092: JShell: Completion hangs on identifier completion
jlahoda
parents: 33714
diff changeset
   110
    private SourceCodeAnalysisImpl sourceCodeAnalysis = null;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   111
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   112
    private static final String L10N_RB_NAME    = "jdk.jshell.resources.l10n";
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   113
    private static ResourceBundle outputRB  = null;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   114
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   115
    JShell(Builder b) throws IllegalStateException {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   116
        this.in = b.in;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   117
        this.out = b.out;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   118
        this.err = b.err;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   119
        this.tempVariableNameGenerator = b.tempVariableNameGenerator;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   120
        this.idGenerator = b.idGenerator;
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   121
        this.extraRemoteVMOptions = b.extraRemoteVMOptions;
39369
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   122
        this.extraCompilerOptions = b.extraCompilerOptions;
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   123
        this.fileManagerMapping = b.fileManagerMapping;
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   124
        try {
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   125
            if (b.executionControlProvider != null) {
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   126
                executionControl = b.executionControlProvider.generate(new ExecutionEnvImpl(),
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   127
                        b.executionControlParameters == null
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   128
                                ? b.executionControlProvider.defaultParameters()
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   129
                                : b.executionControlParameters);
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   130
            } else {
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   131
                String loopback = InetAddress.getLoopbackAddress().getHostAddress();
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   132
                String spec = b.executionControlSpec == null
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   133
                        ? "failover:0(jdi:hostname(" + loopback + ")),"
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   134
                          + "1(jdi:launch(true)), 2(jdi)"
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   135
                        : b.executionControlSpec;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   136
                executionControl = ExecutionControl.generate(new ExecutionEnvImpl(), spec);
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   137
            }
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   138
        } catch (Throwable ex) {
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   139
            throw new IllegalStateException("Launching JShell execution engine threw: " + ex.getMessage(), ex);
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   140
        }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   141
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   142
        this.maps = new SnippetMaps(this);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   143
        this.keyMap = new KeyMap(this);
37644
33cf53901cac 8154485: JShell: infrastructure for multi-Snippet class wrappers
rfield
parents: 37004
diff changeset
   144
        this.outerMap = new OuterWrapMap(this);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   145
        this.taskFactory = new TaskFactory(this);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   146
        this.eval = new Eval(this);
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   147
        this.classTracker = new ClassTracker();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   148
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   149
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   150
    /**
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   151
     * Builder for {@code JShell} instances.
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   152
     * Create custom instances of {@code JShell} by using the setter
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   153
     * methods on this class.  After zero or more of these, use the
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   154
     * {@link #build()} method to create a {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   155
     * These can all be chained. For example, setting the remote output and
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   156
     * error streams:
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   157
     * <pre>
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   158
     * {@code
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   159
     *     JShell myShell =
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   160
     *       JShell.builder()
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   161
     *         .out(myOutStream)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   162
     *         .err(myErrStream)
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   163
     *         .build(); } </pre>
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   164
     * If no special set-up is needed, just use
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   165
     * {@code JShell.builder().build()} or the short-cut equivalent
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   166
     * {@code JShell.create()}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   167
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   168
    public static class Builder {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   169
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   170
        InputStream in = new ByteArrayInputStream(new byte[0]);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   171
        PrintStream out = System.out;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   172
        PrintStream err = System.err;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   173
        Supplier<String> tempVariableNameGenerator = null;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   174
        BiFunction<Snippet, Integer, String> idGenerator = null;
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   175
        List<String> extraRemoteVMOptions = new ArrayList<>();
39369
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   176
        List<String> extraCompilerOptions = new ArrayList<>();
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   177
        ExecutionControlProvider executionControlProvider;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   178
        Map<String,String> executionControlParameters;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   179
        String executionControlSpec;
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   180
        Function<StandardJavaFileManager, StandardJavaFileManager> fileManagerMapping;
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   181
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   182
        Builder() { }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   183
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   184
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   185
         * Sets the input for the running evaluation (it's {@code System.in}). Note:
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   186
         * applications that use {@code System.in} for snippet or other
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   187
         * user input cannot use {@code System.in} as the input stream for
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   188
         * the remote process.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   189
         * <p>
41628
664e7664343d 8167461: jshell tool: Scanner#next() hangs tool
jlahoda
parents: 41514
diff changeset
   190
         * The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException}
664e7664343d 8167461: jshell tool: Scanner#next() hangs tool
jlahoda
parents: 41514
diff changeset
   191
         * to signal the user canceled the input. The currently running snippet will be automatically
664e7664343d 8167461: jshell tool: Scanner#next() hangs tool
jlahoda
parents: 41514
diff changeset
   192
         * {@link JShell#stop() stopped}.
664e7664343d 8167461: jshell tool: Scanner#next() hangs tool
jlahoda
parents: 41514
diff changeset
   193
         * <p>
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   194
         * The default, if this is not set, is to provide an empty input stream
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   195
         * -- {@code new ByteArrayInputStream(new byte[0])}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   196
         *
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   197
         * @param in the {@code InputStream} to be channelled to
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   198
         * {@code System.in} in the remote execution process
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   199
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   200
         * initialization)
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   201
         */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   202
        public Builder in(InputStream in) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   203
            this.in = in;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   204
            return this;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   205
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   206
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   207
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   208
         * Sets the output for the running evaluation (it's {@code System.out}).
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   209
         * The controlling process and
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   210
         * the remote process can share {@code System.out}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   211
         * <p>
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   212
         * The default, if this is not set, is {@code System.out}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   213
         *
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   214
         * @param out the {@code PrintStream} to be channelled to
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   215
         * {@code System.out} in the remote execution process
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   216
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   217
         * initialization)
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   218
         */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   219
        public Builder out(PrintStream out) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   220
            this.out = out;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   221
            return this;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   222
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   223
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   224
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   225
         * Sets the error output for the running evaluation (it's
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   226
         * {@code System.err}). The controlling process and the remote
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   227
         * process can share {@code System.err}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   228
         * <p>
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   229
         * The default, if this is not set, is {@code System.err}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   230
         *
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   231
         * @param err the {@code PrintStream} to be channelled to
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   232
         * {@code System.err} in the remote execution process
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   233
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   234
         * initialization)
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   235
         */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   236
        public Builder err(PrintStream err) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   237
            this.err = err;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   238
            return this;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   239
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   240
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   241
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   242
         * Sets a generator of temp variable names for
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   243
         * {@link jdk.jshell.VarSnippet} of
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   244
         * {@link jdk.jshell.Snippet.SubKind#TEMP_VAR_EXPRESSION_SUBKIND}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   245
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   246
         * Do not use this method unless you have explicit need for it.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   247
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   248
         * The generator will be used for newly created VarSnippet
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   249
         * instances. The name of a variable is queried with
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   250
         * {@link jdk.jshell.VarSnippet#name()}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   251
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   252
         * The callback is sent during the processing of the snippet, the
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   253
         * JShell state is not stable. No calls whatsoever on the
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   254
         * {@code JShell} instance may be made from the callback.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   255
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   256
         * The generated name must be unique within active snippets.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   257
         * <p>
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   258
         * The default behavior (if this is not set or {@code generator}
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   259
         * is null) is to generate the name as a sequential number with a
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   260
         * prefixing dollar sign ("$").
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   261
         *
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   262
         * @param generator the {@code Supplier} to generate the temporary
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   263
         * variable name string or {@code null}
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   264
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   265
         * initialization)
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   266
         */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   267
        public Builder tempVariableNameGenerator(Supplier<String> generator) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   268
            this.tempVariableNameGenerator = generator;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   269
            return this;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   270
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   271
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   272
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   273
         * Sets the generator of identifying names for Snippets.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   274
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   275
         * Do not use this method unless you have explicit need for it.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   276
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   277
         * The generator will be used for newly created Snippet instances. The
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   278
         * identifying name (id) is accessed with
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   279
         * {@link jdk.jshell.Snippet#id()} and can be seen in the
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   280
         * {@code StackTraceElement.getFileName()} for a
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   281
         * {@link jdk.jshell.EvalException} and
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   282
         * {@link jdk.jshell.UnresolvedReferenceException}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   283
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   284
         * The inputs to the generator are the {@link jdk.jshell.Snippet} and an
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   285
         * integer. The integer will be the same for two Snippets which would
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   286
         * overwrite one-another, but otherwise is unique.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   287
         * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   288
         * The callback is sent during the processing of the snippet and the
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   289
         * Snippet and the state as a whole are not stable. No calls to change
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   290
         * system state (including Snippet state) should be made. Queries of
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   291
         * Snippet may be made except to {@link jdk.jshell.Snippet#id()}. No
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   292
         * calls on the {@code JShell} instance may be made from the
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   293
         * callback, except to
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   294
         * {@link #status(jdk.jshell.Snippet) status(Snippet)}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   295
         * <p>
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   296
         * The default behavior (if this is not set or {@code generator}
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   297
         * is null) is to generate the id as the integer converted to a string.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   298
         *
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   299
         * @param generator the {@code BiFunction} to generate the id
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   300
         * string or {@code null}
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   301
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   302
         * initialization)
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   303
         */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   304
        public Builder idGenerator(BiFunction<Snippet, Integer, String> generator) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   305
            this.idGenerator = generator;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   306
            return this;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   307
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   308
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   309
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   310
         * Sets additional VM options for launching the VM.
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   311
         *
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   312
         * @param options The options for the remote VM
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   313
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   314
         * initialization)
37745
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   315
         */
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   316
        public Builder remoteVMOptions(String... options) {
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   317
            this.extraRemoteVMOptions.addAll(Arrays.asList(options));
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   318
            return this;
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   319
        }
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   320
4b6b59f8e327 8150382: JShell API: Allow setting remote JVM arguments
rfield
parents: 37644
diff changeset
   321
        /**
39369
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   322
         * Adds compiler options.  These additional options will be used on
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   323
         * parsing, analysis, and code generation calls to the compiler.
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   324
         * Options which interfere with results are not supported and have
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   325
         * undefined effects on JShell's operation.
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   326
         *
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   327
         * @param options the addition options for compiler invocations
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   328
         * @return the {@code Builder} instance (for use in chained
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   329
         * initialization)
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   330
         */
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   331
        public Builder compilerOptions(String... options) {
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   332
            this.extraCompilerOptions.addAll(Arrays.asList(options));
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   333
            return this;
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   334
        }
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   335
0469f052203d 8159635: JShell API: Add compiler options
rfield
parents: 38908
diff changeset
   336
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   337
         * Sets the custom engine for execution. Snippet execution will be
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   338
         * provided by the {@link ExecutionControl} instance selected by the
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   339
         * specified execution control spec.
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   340
         * Use, at most, one of these overloaded {@code executionEngine} builder
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   341
         * methods.
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   342
         *
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   343
         * @param executionControlSpec the execution control spec,
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   344
         * which is documented in the {@link jdk.jshell.spi}
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   345
         * package documentation.
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   346
         * @return the {@code Builder} instance (for use in chained
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   347
         * initialization)
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   348
         */
42969
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   349
        public Builder executionEngine(String executionControlSpec) {
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   350
            this.executionControlSpec = executionControlSpec;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   351
            return this;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   352
        }
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   353
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   354
        /**
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   355
         * Sets the custom engine for execution. Snippet execution will be
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   356
         * provided by the specified {@link ExecutionControl} instance.
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   357
         * Use, at most, one of these overloaded {@code executionEngine} builder
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   358
         * methods.
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   359
         *
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   360
         * @param executionControlProvider the provider to supply the execution
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   361
         * engine
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   362
         * @param executionControlParameters the parameters to the provider, or
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   363
         * {@code null} for default parameters
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   364
         * @return the {@code Builder} instance (for use in chained
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   365
         * initialization)
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   366
         */
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   367
        public Builder executionEngine(ExecutionControlProvider executionControlProvider,
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   368
                Map<String,String> executionControlParameters) {
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   369
            this.executionControlProvider = executionControlProvider;
a48d4f74d322 8168615: JShell API: jdk.jshell.spi should be a pluggable ServiceLoader SPI
rfield
parents: 42272
diff changeset
   370
            this.executionControlParameters = executionControlParameters;
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   371
            return this;
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   372
        }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   373
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   374
        /**
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   375
         * Configure the {@code FileManager} to be used by compilation and
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   376
         * source analysis.
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   377
         * If not set or passed null, the compiler's standard file manager will
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   378
         * be used (identity mapping).
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   379
         * For use in special applications where the compiler's normal file
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   380
         * handling needs to be overridden.  See the file manager APIs for more
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   381
         * information.
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   382
         * The file manager input enables forwarding file managers, if this
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   383
         * is not needed, the incoming file manager can be ignored (constant
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   384
         * function).
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   385
         *
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   386
         * @param mapping a function that given the compiler's standard file
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   387
         * manager, returns a file manager to use
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   388
         * @return the {@code Builder} instance (for use in chained
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   389
         * initialization)
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   390
         */
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   391
        public Builder fileManager(Function<StandardJavaFileManager, StandardJavaFileManager> mapping) {
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   392
            this.fileManagerMapping = mapping;
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   393
            return this;
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   394
        }
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   395
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   396
        /**
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   397
         * Builds a JShell state engine. This is the entry-point to all JShell
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   398
         * functionality. This creates a remote process for execution. It is
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   399
         * thus important to close the returned instance.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   400
         *
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   401
         * @throws IllegalStateException if the {@code JShell} instance could not be created.
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   402
         * @return the state engine
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   403
         */
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   404
        public JShell build() throws IllegalStateException {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   405
            return new JShell(this);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   406
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   407
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   408
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   409
    // --- public API ---
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   410
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   411
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   412
     * Create a new JShell state engine.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   413
     * That is, create an instance of {@code JShell}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   414
     * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   415
     * Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   416
     * @throws IllegalStateException if the {@code JShell} instance could not be created.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   417
     * @return an instance of {@code JShell}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   418
     */
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   419
    public static JShell create() throws IllegalStateException {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   420
        return builder().build();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   421
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   422
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   423
    /**
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   424
     * Factory method for {@code JShell.Builder} which, in-turn, is used
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   425
     * for creating instances of {@code JShell}.
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   426
     * Create a default instance of {@code JShell} with
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   427
     * {@code JShell.builder().build()}. For more construction options
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   428
     * see {@link jdk.jshell.JShell.Builder}.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   429
     * @return an instance of {@code Builder}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   430
     * @see jdk.jshell.JShell.Builder
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   431
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   432
    public static Builder builder() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   433
        return new Builder();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   434
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   435
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   436
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   437
     * Access to source code analysis functionality.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   438
     * An instance of {@code JShell} will always return the same
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   439
     * {@code SourceCodeAnalysis} instance from
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   440
     * {@code sourceCodeAnalysis()}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   441
     * @return an instance of {@link SourceCodeAnalysis SourceCodeAnalysis}
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   442
     * which can be used for source analysis such as completion detection and
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   443
     * completion suggestions.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   444
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   445
    public SourceCodeAnalysis sourceCodeAnalysis() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   446
        if (sourceCodeAnalysis == null) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   447
            sourceCodeAnalysis = new SourceCodeAnalysisImpl(this);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   448
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   449
        return sourceCodeAnalysis;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   450
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   451
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   452
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   453
     * Evaluate the input String, including definition and/or execution, if
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   454
     * applicable. The input is checked for errors, unless the errors can be
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   455
     * deferred (as is the case with some unresolvedDependencies references),
39370
437ba9bd2582 8159111: JShell API: Add access to wrappers and dependencies
rfield
parents: 39369
diff changeset
   456
     * errors will abort evaluation.
437ba9bd2582 8159111: JShell API: Add access to wrappers and dependencies
rfield
parents: 39369
diff changeset
   457
     * <p>
437ba9bd2582 8159111: JShell API: Add access to wrappers and dependencies
rfield
parents: 39369
diff changeset
   458
     * The input should be
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   459
     * exactly one complete snippet of source code, that is, one expression,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   460
     * statement, variable declaration, method declaration, class declaration,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   461
     * or import.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   462
     * To break arbitrary input into individual complete snippets, use
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   463
     * {@link SourceCodeAnalysis#analyzeCompletion(String)}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   464
     * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   465
     * For imports, the import is added.  Classes, interfaces. methods,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   466
     * and variables are defined.  The initializer of variables, statements,
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   467
     * and expressions are executed.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   468
     * The modifiers public, protected, private, static, and final are not
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   469
     * allowed on op-level declarations and are ignored with a warning.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   470
     * Synchronized, native, abstract, and default top-level methods are not
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   471
     * allowed and are errors.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   472
     * If a previous definition of a declaration is overwritten then there will
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   473
     * be an event showing its status changed to OVERWRITTEN, this will not
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   474
     * occur for dropped, rejected, or already overwritten declarations.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   475
     * <p>
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   476
     * If execution environment is out of process, as is the default case, then
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   477
     * if the evaluated code
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   478
     * causes the execution environment to terminate, this {@code JShell}
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   479
     * instance will be closed but the calling process and VM remain valid.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   480
     * @param input The input String to evaluate
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   481
     * @return the list of events directly or indirectly caused by this evaluation.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   482
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   483
     * @see SourceCodeAnalysis#analyzeCompletion(String)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   484
     * @see JShell#onShutdown(java.util.function.Consumer)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   485
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   486
    public List<SnippetEvent> eval(String input) throws IllegalStateException {
36160
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   487
        SourceCodeAnalysisImpl a = sourceCodeAnalysis;
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   488
        if (a != null) {
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   489
            a.suspendIndexing();
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   490
        }
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   491
        try {
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   492
            checkIfAlive();
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   493
            List<SnippetEvent> events = eval.eval(input);
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   494
            events.forEach(this::notifyKeyStatusEvent);
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   495
            return Collections.unmodifiableList(events);
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   496
        } finally {
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   497
            if (a != null) {
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   498
                a.resumeIndexing();
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   499
            }
f42d362d0d17 8131027: JShell API/tool: suggest imports for a class
jlahoda
parents: 33715
diff changeset
   500
        }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   501
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   502
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   503
    /**
41514
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   504
     * Remove a declaration from the state.  That is, if the snippet is an
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   505
     * {@linkplain jdk.jshell.Snippet.Status#isActive() active}
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   506
     * {@linkplain jdk.jshell.PersistentSnippet persistent} snippet, remove the
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   507
     * snippet and update the JShell evaluation state accordingly.
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   508
     * For all active snippets, change the {@linkplain #status status} to
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   509
     * {@link jdk.jshell.Snippet.Status#DROPPED DROPPED}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   510
     * @param snippet The snippet to remove
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   511
     * @return The list of events from updating declarations dependent on the
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   512
     * dropped snippet.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   513
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   514
     * @throws IllegalArgumentException if the snippet is not associated with
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   515
     * this {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   516
     */
41514
a75c2b869d8d 8167128: JShell: /drop of statement gives confusing output
rfield
parents: 40764
diff changeset
   517
    public List<SnippetEvent> drop(Snippet snippet) throws IllegalStateException {
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   518
        checkIfAlive();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   519
        checkValidSnippet(snippet);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   520
        List<SnippetEvent> events = eval.drop(snippet);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   521
        events.forEach(this::notifyKeyStatusEvent);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   522
        return Collections.unmodifiableList(events);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   523
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   524
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   525
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   526
     * The specified path is added to the end of the classpath used in eval().
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   527
     * Note that the unnamed package is not accessible from the package in which
37004
ff77b7986967 8153243: make docs should generate JShell API docs
jlahoda
parents: 36990
diff changeset
   528
     * {@link JShell#eval(String)} code is placed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   529
     * @param path the path to add to the classpath.
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   530
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   531
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   532
    public void addToClasspath(String path) {
43758
868af3718a21 8173845: JShell API: not patch compatible
rfield
parents: 43757
diff changeset
   533
        checkIfAlive();
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   534
        // Compiler
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   535
        taskFactory.addToClasspath(path);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   536
        // Runtime
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   537
        try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   538
            executionControl().addToClasspath(path);
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   539
        } catch (ExecutionControlException ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   540
            debug(ex, "on addToClasspath(" + path + ")");
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   541
        }
33715
74b1bed86932 8141092: JShell: Completion hangs on identifier completion
jlahoda
parents: 33714
diff changeset
   542
        if (sourceCodeAnalysis != null) {
74b1bed86932 8141092: JShell: Completion hangs on identifier completion
jlahoda
parents: 33714
diff changeset
   543
            sourceCodeAnalysis.classpathChanged();
74b1bed86932 8141092: JShell: Completion hangs on identifier completion
jlahoda
parents: 33714
diff changeset
   544
        }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   545
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   546
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   547
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   548
     * Attempt to stop currently running evaluation. When called while
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   549
     * the {@link #eval(java.lang.String) } method is running and the
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   550
     * user's code being executed, an attempt will be made to stop user's code.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   551
     * Note that typically this method needs to be called from a different thread
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   552
     * than the one running the {@code eval} method.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   553
     * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   554
     * If the {@link #eval(java.lang.String) } method is not running, does nothing.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   555
     * <p>
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   556
     * The attempt to stop the user's code may fail in some case, which may include
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   557
     * when the execution is blocked on an I/O operation, or when the user's code is
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   558
     * catching the {@link ThreadDeath} exception.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   559
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   560
    public void stop() {
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   561
        if (executionControl != null) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   562
            try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   563
                executionControl.stop();
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   564
            } catch (ExecutionControlException ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   565
                debug(ex, "on stop()");
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   566
            }
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   567
        }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   568
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   569
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   570
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   571
     * Close this state engine. Frees resources. Should be called when this
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   572
     * state engine is no longer needed.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   573
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   574
    @Override
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   575
    public void close() {
43757
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   576
        closeDown();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   577
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   578
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   579
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   580
     * Return all snippets.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   581
     * @return the snippets for all current snippets in id order.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   582
     */
40515
819fc588bd19 8164277: JShell API: Snippets are immutable and should be available for post-mortem analysis
rfield
parents: 40304
diff changeset
   583
    public Stream<Snippet> snippets() {
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   584
        return maps.snippetList().stream();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   585
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   586
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   587
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   588
     * Returns the active variable snippets.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   589
     * This convenience method is equivalent to {@code snippets()} filtered for
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   590
     * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   591
     * {@code && snippet.kind() == Kind.VARIABLE}
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   592
     * and cast to {@code VarSnippet}.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   593
     * @return the active declared variables.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   594
     */
40515
819fc588bd19 8164277: JShell API: Snippets are immutable and should be available for post-mortem analysis
rfield
parents: 40304
diff changeset
   595
    public Stream<VarSnippet> variables() {
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   596
        return snippets()
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   597
                     .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR)
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   598
                     .map(sn -> (VarSnippet) sn);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   599
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   600
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   601
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   602
     * Returns the active method snippets.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   603
     * This convenience method is equivalent to {@code snippets()} filtered for
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   604
     * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   605
     * {@code && snippet.kind() == Kind.METHOD}
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   606
     * and cast to MethodSnippet.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   607
     * @return the active declared methods.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   608
     */
40515
819fc588bd19 8164277: JShell API: Snippets are immutable and should be available for post-mortem analysis
rfield
parents: 40304
diff changeset
   609
    public Stream<MethodSnippet> methods() {
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   610
        return snippets()
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   611
                     .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD)
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   612
                     .map(sn -> (MethodSnippet)sn);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   613
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   614
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   615
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   616
     * Returns the active type declaration (class, interface, annotation type, and enum) snippets.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   617
     * This convenience method is equivalent to {@code snippets()} filtered for
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   618
     * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   619
     * {@code && snippet.kind() == Kind.TYPE_DECL}
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   620
     * and cast to TypeDeclSnippet.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   621
     * @return the active declared type declarations.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   622
     */
40515
819fc588bd19 8164277: JShell API: Snippets are immutable and should be available for post-mortem analysis
rfield
parents: 40304
diff changeset
   623
    public Stream<TypeDeclSnippet> types() {
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   624
        return snippets()
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   625
                .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL)
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   626
                .map(sn -> (TypeDeclSnippet) sn);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   627
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   628
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   629
    /**
33714
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   630
     * Returns the active import snippets.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   631
     * This convenience method is equivalent to {@code snippets()} filtered for
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   632
     * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   633
     * {@code && snippet.kind() == Kind.IMPORT}
33714
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   634
     * and cast to ImportSnippet.
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   635
     * @return the active declared import declarations.
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   636
     */
40515
819fc588bd19 8164277: JShell API: Snippets are immutable and should be available for post-mortem analysis
rfield
parents: 40304
diff changeset
   637
    public Stream<ImportSnippet> imports() {
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   638
        return snippets()
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   639
                .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT)
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   640
                .map(sn -> (ImportSnippet) sn);
33714
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   641
    }
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   642
8064f484590e 8142384: JShell tool: New command: /imports, /i which show the list of imported packages or classes, etc...
shinyafox
parents: 33362
diff changeset
   643
    /**
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   644
     * Return the status of the snippet.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   645
     * This is updated either because of an explicit {@code eval()} call or
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   646
     * an automatic update triggered by a dependency.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   647
     * @param snippet the {@code Snippet} to look up
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   648
     * @return the status corresponding to this snippet
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   649
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   650
     * @throws IllegalArgumentException if the snippet is not associated with
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   651
     * this {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   652
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   653
    public Status status(Snippet snippet) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   654
        return checkValidSnippet(snippet).status();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   655
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   656
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   657
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   658
     * Return the diagnostics of the most recent evaluation of the snippet.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   659
     * The evaluation can either because of an explicit {@code eval()} call or
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   660
     * an automatic update triggered by a dependency.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   661
     * @param snippet the {@code Snippet} to look up
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   662
     * @return the diagnostics corresponding to this snippet.  This does not
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   663
     * include unresolvedDependencies references reported in {@code unresolvedDependencies()}.
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   664
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   665
     * @throws IllegalArgumentException if the snippet is not associated with
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   666
     * this {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   667
     */
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   668
    public Stream<Diag> diagnostics(Snippet snippet) {
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   669
        return checkValidSnippet(snippet).diagnostics().stream();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   670
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   671
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   672
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   673
     * For {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED} or
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   674
     * {@link jdk.jshell.Snippet.Status#RECOVERABLE_NOT_DEFINED RECOVERABLE_NOT_DEFINED}
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   675
     * declarations, the names of current unresolved dependencies for
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   676
     * the snippet.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   677
     * The returned value of this method, for a given method may change when an
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   678
     * {@code eval()} or {@code drop()} of another snippet causes
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   679
     * an update of a dependency.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   680
     * @param snippet the declaration {@code Snippet} to look up
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   681
     * @return a stream of symbol names that are currently unresolvedDependencies.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   682
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   683
     * @throws IllegalArgumentException if the snippet is not associated with
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   684
     * this {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   685
     */
40304
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   686
    public Stream<String> unresolvedDependencies(DeclarationSnippet snippet) {
0318f4e75c6d 8143964: JShell API: convert query responses to Stream instead of List
rfield
parents: 39807
diff changeset
   687
        return checkValidSnippet(snippet).unresolved().stream();
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   688
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   689
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   690
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   691
     * Get the current value of a variable.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   692
     * @param snippet the variable Snippet whose value is queried.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   693
     * @return the current value of the variable referenced by snippet.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   694
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   695
     * @throws IllegalArgumentException if the snippet is not associated with
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   696
     * this {@code JShell} instance.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   697
     * @throws IllegalArgumentException if the variable's status is anything but
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   698
     * {@link jdk.jshell.Snippet.Status#VALID}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   699
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   700
    public String varValue(VarSnippet snippet) throws IllegalStateException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   701
        checkIfAlive();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   702
        checkValidSnippet(snippet);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   703
        if (snippet.status() != Status.VALID) {
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   704
            throw new IllegalArgumentException(
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   705
                    messageFormat("jshell.exc.var.not.valid",  snippet, snippet.status()));
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   706
        }
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   707
        String value;
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   708
        try {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   709
            value = executionControl().varValue(snippet.classFullName(), snippet.name());
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   710
        } catch (EngineTerminationException ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   711
            throw new IllegalStateException(ex.getMessage());
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   712
        } catch (ExecutionControlException ex) {
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   713
            debug(ex, "In varValue()");
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   714
            return "[" + ex.getMessage() + "]";
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   715
        }
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   716
        return expunge(value);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   717
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   718
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   719
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   720
     * Register a callback to be called when the Status of a snippet changes.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   721
     * Each call adds a new subscription.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   722
     * @param listener Action to perform when the Status changes.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   723
     * @return A token which can be used to {@linkplain JShell#unsubscribe unsubscribe} this subscription.
38908
f0c186d76c8a 8139829: JShell API: No use of fields to return information from public types
rfield
parents: 38836
diff changeset
   724
     * @throws IllegalStateException if this {@code JShell} instance is closed.
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   725
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   726
    public Subscription onSnippetEvent(Consumer<SnippetEvent> listener)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   727
            throws IllegalStateException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   728
        return onX(keyStatusListeners, listener);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   729
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   730
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   731
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   732
     * Register a callback to be called when this JShell instance terminates.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   733
     * This occurs either because the client process has ended (e.g. called System.exit(0))
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   734
     * or the connection has been shutdown, as by close().
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   735
     * Each call adds a new subscription.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   736
     * @param listener Action to perform when the state terminates.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   737
     * @return A token which can be used to {@linkplain JShell#unsubscribe unsubscribe} this subscription.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   738
     * @throws IllegalStateException if this JShell instance is closed
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   739
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   740
    public Subscription onShutdown(Consumer<JShell> listener)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   741
            throws IllegalStateException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   742
        return onX(shutdownListeners, listener);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   743
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   744
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   745
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   746
     * Cancel a callback subscription.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   747
     * @param token The token corresponding to the subscription to be unsubscribed.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   748
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   749
    public void unsubscribe(Subscription token) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   750
        synchronized (this) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   751
            token.remover.accept(token);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   752
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   753
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   754
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   755
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   756
     * Subscription is a token for referring to subscriptions so they can
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   757
     * be {@linkplain JShell#unsubscribe unsubscribed}.
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   758
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   759
    public class Subscription {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   760
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   761
        Consumer<Subscription> remover;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   762
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   763
        Subscription(Consumer<Subscription> remover) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   764
            this.remover = remover;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   765
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   766
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   767
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   768
    /**
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   769
     * Provide the environment for a execution engine.
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   770
     */
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   771
    class ExecutionEnvImpl implements ExecutionEnv {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   772
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   773
        @Override
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   774
        public InputStream userIn() {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   775
            return in;
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   776
        }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   777
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   778
        @Override
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   779
        public PrintStream userOut() {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   780
            return out;
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   781
        }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   782
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   783
        @Override
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   784
        public PrintStream userErr() {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   785
            return err;
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   786
        }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   787
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   788
        @Override
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   789
        public List<String> extraRemoteVMOptions() {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   790
            return extraRemoteVMOptions;
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   791
        }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   792
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   793
        @Override
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   794
        public void closeDown() {
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   795
            JShell.this.closeDown();
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   796
        }
39807
ba0ff343d241 8160127: JShell API: extract abstract JDI and abstract streaming implementations of ExecutionControl
rfield
parents: 39370
diff changeset
   797
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   798
    }
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   799
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   800
    // --- private / package-private implementation support ---
42272
82e273c4f2b3 8169519: JShell: Handle start-up failures and hangs gracefully
rfield
parents: 41941
diff changeset
   801
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   802
    ExecutionControl executionControl() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   803
        return executionControl;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   804
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   805
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   806
    void debug(int flags, String format, Object... args) {
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   807
        InternalDebugControl.debug(this, err, flags, format, args);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   808
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   809
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   810
    void debug(Exception ex, String where) {
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   811
        InternalDebugControl.debug(this, err, ex, where);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   812
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   813
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   814
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   815
     * Generate the next key index, indicating a unique snippet signature.
38535
4a25025e0b0d 8156101: JShell SPI: Provide a pluggable execution control SPI
rfield
parents: 37745
diff changeset
   816
     *
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   817
     * @return the next key index
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   818
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   819
    int nextKeyIndex() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   820
        return nextKeyIndex++;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   821
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   822
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   823
    private synchronized <T> Subscription onX(Map<Subscription, Consumer<T>> map, Consumer<T> listener)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   824
            throws IllegalStateException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   825
        Objects.requireNonNull(listener);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   826
        checkIfAlive();
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   827
        Subscription token = new Subscription(map::remove);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   828
        map.put(token, listener);
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   829
        return token;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   830
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   831
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   832
    private synchronized void notifyKeyStatusEvent(SnippetEvent event) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   833
        keyStatusListeners.values().forEach(l -> l.accept(event));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   834
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   835
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   836
    private synchronized void notifyShutdownEvent(JShell state) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   837
        shutdownListeners.values().forEach(l -> l.accept(state));
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   838
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   839
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   840
    void closeDown() {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   841
        if (!closed) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   842
            // Send only once
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   843
            closed = true;
38836
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38535
diff changeset
   844
            try {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38535
diff changeset
   845
                notifyShutdownEvent(this);
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38535
diff changeset
   846
            } catch (Throwable thr) {
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38535
diff changeset
   847
                // Don't care about dying exceptions
b09d1cfbf28c 8131029: JShell: recover from VMConnection launch failure
rfield
parents: 38535
diff changeset
   848
            }
43757
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   849
            try {
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   850
                executionControl().close();
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   851
            } catch (Throwable ex) {
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   852
                // don't care about exceptions on close
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   853
            }
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   854
            if (sourceCodeAnalysis != null) {
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   855
                sourceCodeAnalysis.close();
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   856
            }
7193f6ef25db 8173893: JShell: reduce memory leaks
rfield
parents: 42969
diff changeset
   857
            InternalDebugControl.release(this);
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   858
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   859
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   860
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   861
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   862
     * Check if this JShell has been closed
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   863
     * @throws IllegalStateException if it is closed
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   864
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   865
    private void checkIfAlive()  throws IllegalStateException {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   866
        if (closed) {
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   867
            throw new IllegalStateException(messageFormat("jshell.exc.closed", this));
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   868
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   869
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   870
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   871
    /**
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   872
     * Check a Snippet parameter coming from the API user
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   873
     * @param sn the Snippet to check
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   874
     * @throws NullPointerException if Snippet parameter is null
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   875
     * @throws IllegalArgumentException if Snippet is not from this JShell
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   876
     * @return the input Snippet (for chained calls)
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   877
     */
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   878
    private Snippet checkValidSnippet(Snippet sn) {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   879
        if (sn == null) {
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   880
            throw new NullPointerException(messageFormat("jshell.exc.null"));
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   881
        } else {
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   882
            if (sn.key().state() != this) {
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   883
                throw new IllegalArgumentException(messageFormat("jshell.exc.alien"));
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   884
            }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   885
            return sn;
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   886
        }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   887
    }
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   888
36990
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   889
    /**
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   890
     * Format using resource bundle look-up using MessageFormat
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   891
     *
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   892
     * @param key the resource key
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   893
     * @param args
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   894
     */
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   895
    String messageFormat(String key, Object... args) {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   896
        if (outputRB == null) {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   897
            try {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   898
                outputRB = ResourceBundle.getBundle(L10N_RB_NAME);
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   899
            } catch (MissingResourceException mre) {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   900
                throw new InternalError("Cannot find ResourceBundle: " + L10N_RB_NAME);
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   901
            }
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   902
        }
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   903
        String s;
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   904
        try {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   905
            s = outputRB.getString(key);
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   906
        } catch (MissingResourceException mre) {
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   907
            throw new InternalError("Missing resource: " + key + " in " + L10N_RB_NAME);
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   908
        }
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   909
        return MessageFormat.format(s, args);
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   910
    }
ec0b843a7af5 8147515: JShell: Internationalize
rfield
parents: 36160
diff changeset
   911
33362
65ec6de1d6b4 8134254: JShell API/tool: REPL for Java into JDK9
jlahoda
parents:
diff changeset
   912
}