--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Jun 09 19:06:36 2016 +0000
@@ -93,7 +93,7 @@
.collect(Collectors.toList());
in.setHistory(history = new EditingHistory(in, persistenHistory) {
@Override protected boolean isComplete(CharSequence input) {
- return repl.analysis.analyzeCompletion(input.toString()).completeness.isComplete;
+ return repl.analysis.analyzeCompletion(input.toString()).completeness().isComplete();
}
});
in.setBellEnabled(true);
@@ -117,24 +117,24 @@
boolean smart = allowSmart &&
suggestions.stream()
- .anyMatch(s -> s.isSmart);
+ .anyMatch(s -> s.matchesType());
lastTest = test;
lastCursor = cursor;
allowSmart = !allowSmart;
suggestions.stream()
- .filter(s -> !smart || s.isSmart)
- .map(s -> s.continuation)
+ .filter(s -> !smart || s.matchesType())
+ .map(s -> s.continuation())
.forEach(result::add);
boolean onlySmart = suggestions.stream()
- .allMatch(s -> s.isSmart);
+ .allMatch(s -> s.matchesType());
if (smart && !onlySmart) {
Optional<String> prefix =
suggestions.stream()
- .map(s -> s.continuation)
+ .map(s -> s.continuation())
.reduce(ConsoleIOContext::commonPrefix);
String prefixStr = prefix.orElse("").substring(cursor - anchor[0]);
@@ -215,6 +215,7 @@
} catch (Exception ex) {
throw new IOException(ex);
}
+ input.shutdown();
}
private void bind(String shortcut, Object action) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Jun 09 19:06:36 2016 +0000
@@ -637,7 +637,7 @@
.out(userout)
.err(usererr)
.tempVariableNameGenerator(()-> "$" + currentNameSpace.tidNext())
- .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive)
+ .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive())
? currentNameSpace.tid(sn)
: errorNamespace.tid(sn))
.remoteVMOptions(remoteVMOptions.toArray(new String[remoteVMOptions.size()]))
@@ -1026,7 +1026,7 @@
List<PersistentSnippet> dropableSnippets() {
return state.snippets().stream()
- .filter(sn -> state.status(sn).isActive && sn instanceof PersistentSnippet)
+ .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet)
.map(sn -> (PersistentSnippet) sn)
.collect(toList());
}
@@ -1164,7 +1164,7 @@
}
}
- return result.sorted((s1, s2) -> s1.continuation.compareTo(s2.continuation))
+ return result.sorted((s1, s2) -> s1.continuation().compareTo(s2.continuation()))
.collect(Collectors.toList());
}
@@ -1530,7 +1530,7 @@
}
private boolean isActive(Snippet sn) {
- return state.status(sn).isActive;
+ return state.status(sn).isActive();
}
private boolean mainActive(Snippet sn) {
@@ -1739,18 +1739,18 @@
boolean failed = false;
while (true) {
CompletionInfo an = analysis.analyzeCompletion(s);
- if (!an.completeness.isComplete) {
+ if (!an.completeness().isComplete()) {
break;
}
- String tsrc = trimNewlines(an.source);
+ String tsrc = trimNewlines(an.source());
if (!failed && !currSrcs.contains(tsrc)) {
failed = processCompleteSource(tsrc);
}
nextSrcs.add(tsrc);
- if (an.remaining.isEmpty()) {
+ if (an.remaining().isEmpty()) {
break;
}
- s = an.remaining;
+ s = an.remaining();
}
currSrcs = nextSrcs;
} catch (IllegalStateException ex) {
@@ -2096,14 +2096,14 @@
private String processSource(String srcInput) throws IllegalStateException {
while (true) {
CompletionInfo an = analysis.analyzeCompletion(srcInput);
- if (!an.completeness.isComplete) {
- return an.remaining;
+ if (!an.completeness().isComplete()) {
+ return an.remaining();
}
- boolean failed = processCompleteSource(an.source);
- if (failed || an.remaining.isEmpty()) {
+ boolean failed = processCompleteSource(an.source());
+ if (failed || an.remaining().isEmpty()) {
return "";
}
- srcInput = an.remaining;
+ srcInput = an.remaining();
}
}
//where
@@ -2119,7 +2119,7 @@
// If any main snippet is active, this should be replayable
// also ignore var value queries
isActive |= e.causeSnippet() == null &&
- e.status().isActive &&
+ e.status().isActive() &&
e.snippet().subKind() != VAR_VALUE_SUBKIND;
}
// If this is an active snippet and it didn't cause the backend to die,
@@ -2235,7 +2235,7 @@
case VALID:
case RECOVERABLE_DEFINED:
case RECOVERABLE_NOT_DEFINED:
- if (previousStatus.isActive) {
+ if (previousStatus.isActive()) {
act = isSignatureChange
? FormatAction.REPLACED
: FormatAction.MODIFIED;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Thu Jun 09 19:06:36 2016 +0000
@@ -61,11 +61,14 @@
//an external editor is running. At the same time, it needs to run while the
//user's code is running (so Ctrl-C is detected). Hence waiting here until
//there is a confirmed need for input.
- waitInputNeeded();
+ StopDetectingInputStream.State currentState = waitInputNeeded();
+ if (currentState == StopDetectingInputStream.State.CLOSED) {
+ break;
+ }
if ((read = input.read()) == (-1)) {
break;
}
- if (read == 3 && state == StopDetectingInputStream.State.BUFFER) {
+ if (read == 3 && currentState == StopDetectingInputStream.State.BUFFER) {
stop.run();
} else {
write(read);
@@ -74,7 +77,9 @@
} catch (IOException ex) {
errorHandler.accept(ex);
} finally {
- state = StopDetectingInputStream.State.CLOSED;
+ synchronized (StopDetectingInputStream.this) {
+ state = StopDetectingInputStream.State.CLOSED;
+ }
}
}
};
@@ -107,6 +112,11 @@
}
}
+ public synchronized void shutdown() {
+ state = State.CLOSED;
+ notifyAll();
+ }
+
public synchronized void write(int b) {
if (state != State.BUFFER) {
state = State.WAIT;
@@ -134,7 +144,7 @@
notifyAll();
}
- private synchronized void waitInputNeeded() {
+ private synchronized State waitInputNeeded() {
while (state == State.WAIT) {
try {
wait();
@@ -142,6 +152,8 @@
//ignore
}
}
+
+ return state;
}
public enum State {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Thu Jun 09 19:06:36 2016 +0000
@@ -47,8 +47,10 @@
public final static long NOPOS = Diagnostic.NOPOS;
/**
- * Is this diagnostic an error (as opposed to a warning or note)
- * @return true if this diagnostic is an error
+ * Indicates whether this diagnostic is an error (as opposed to a warning or
+ * note).
+ *
+ * @return {@code true} if this diagnostic is an error; otherwise {@code false}
*/
public abstract boolean isError();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Jun 09 19:06:36 2016 +0000
@@ -440,7 +440,7 @@
ins.add(c);
Set<Unit> outs = compileAndLoad(ins);
- if (!si.status().isDefined
+ if (!si.status().isDefined()
&& si.diagnostics().isEmpty()
&& si.unresolved().isEmpty()) {
// did not succeed, but no record of it, extract from others
@@ -452,7 +452,7 @@
// If appropriate, execute the snippet
String value = null;
JShellException exception = null;
- if (si.status().isDefined) {
+ if (si.status().isDefined()) {
if (si.isExecutable()) {
try {
value = state.executionControl().invoke(si.classFullName(), DOIT_METHOD_NAME);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java Thu Jun 09 19:06:36 2016 +0000
@@ -31,7 +31,7 @@
* Snippet for an import declaration.
* The Kind is {@link jdk.jshell.Snippet.Kind#IMPORT}.
* <p>
- * <code>ImportSnippet</code> is immutable: an access to
+ * {@code ImportSnippet} is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
* @jls 8.3: importDeclaration.
@@ -85,8 +85,10 @@
}
/**
- * When this snippet represent static import, this method returns true.
- * @return true when this snippet represent static import, otherwise false
+ * Indicates whether this snippet represents a static import.
+ *
+ * @return {@code true} if this snippet represents a static import;
+ * otherwise {@code false}
*/
public boolean isStatic() {
return isStatic;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Jun 09 19:06:36 2016 +0000
@@ -54,13 +54,13 @@
/**
* The JShell evaluation state engine. This is the central class in the JShell
- * API. A <code>JShell</code> instance holds the evolving compilation and
+ * API. A {@code JShell} instance holds the evolving compilation and
* execution state. The state is changed with the instance methods
* {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
* {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop(PersistentSnippet)} and
* {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
* The majority of methods query the state.
- * A <code>JShell</code> instance also allows registering for events with
+ * A {@code JShell} instance also allows registering for events with
* {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer) onSnippetEvent(Consumer)}
* and {@link jdk.jshell.JShell#onShutdown(java.util.function.Consumer) onShutdown(Consumer)}, which
* are unregistered with
@@ -70,8 +70,8 @@
* When complete the instance should be closed to free resources --
* {@link jdk.jshell.JShell#close()}.
* <p>
- * An instance of <code>JShell</code> is created with
- * <code>JShell.create()</code>.
+ * An instance of {@code JShell} is created with
+ * {@code JShell.create()}.
* <p>
* This class is not thread safe, except as noted, all access should be through
* a single thread.
@@ -126,22 +126,22 @@
}
/**
- * Builder for <code>JShell</code> instances.
- * Create custom instances of <code>JShell</code> by using the setter
+ * Builder for {@code JShell} instances.
+ * Create custom instances of {@code JShell} by using the setter
* methods on this class. After zero or more of these, use the
- * {@link #build()} method to create a <code>JShell</code> instance.
+ * {@link #build()} method to create a {@code JShell} instance.
* These can all be chained. For example, setting the remote output and
* error streams:
* <pre>
- * <code>
+ * {@code
* JShell myShell =
* JShell.builder()
* .out(myOutStream)
* .err(myErrStream)
- * .build(); </code> </pre>
+ * .build(); } </pre>
* If no special set-up is needed, just use
- * <code>JShell.builder().build()</code> or the short-cut equivalent
- * <code>JShell.create()</code>.
+ * {@code JShell.builder().build()} or the short-cut equivalent
+ * {@code JShell.create()}.
*/
public static class Builder {
@@ -221,16 +221,16 @@
* <p>
* The callback is sent during the processing of the snippet, the
* JShell state is not stable. No calls whatsoever on the
- * <code>JShell</code> instance may be made from the callback.
+ * {@code JShell} instance may be made from the callback.
* <p>
* The generated name must be unique within active snippets.
* <p>
- * The default behavior (if this is not set or <code>generator</code>
+ * The default behavior (if this is not set or {@code generator}
* is null) is to generate the name as a sequential number with a
* prefixing dollar sign ("$").
*
- * @param generator the <code>Supplier</code> to generate the temporary
- * variable name string or <code>null</code>
+ * @param generator the {@code Supplier} to generate the temporary
+ * variable name string or {@code null}
* @return the {@code Builder} instance (for use in chained
* initialization)
*/
@@ -247,7 +247,7 @@
* The generator will be used for newly created Snippet instances. The
* identifying name (id) is accessed with
* {@link jdk.jshell.Snippet#id()} and can be seen in the
- * <code>StackTraceElement.getFileName()</code> for a
+ * {@code StackTraceElement.getFileName()} for a
* {@link jdk.jshell.EvalException} and
* {@link jdk.jshell.UnresolvedReferenceException}.
* <p>
@@ -259,15 +259,15 @@
* Snippet and the state as a whole are not stable. No calls to change
* system state (including Snippet state) should be made. Queries of
* Snippet may be made except to {@link jdk.jshell.Snippet#id()}. No
- * calls on the <code>JShell</code> instance may be made from the
+ * calls on the {@code JShell} instance may be made from the
* callback, except to
* {@link #status(jdk.jshell.Snippet) status(Snippet)}.
* <p>
- * The default behavior (if this is not set or <code>generator</code>
+ * The default behavior (if this is not set or {@code generator}
* is null) is to generate the id as the integer converted to a string.
*
- * @param generator the <code>BiFunction</code> to generate the id
- * string or <code>null</code>
+ * @param generator the {@code BiFunction} to generate the id
+ * string or {@code null}
* @return the {@code Builder} instance (for use in chained
* initialization)
*/
@@ -317,22 +317,22 @@
/**
* Create a new JShell state engine.
- * That is, create an instance of <code>JShell</code>.
+ * That is, create an instance of {@code JShell}.
* <p>
* Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
- * @return an instance of <code>JShell</code>.
+ * @return an instance of {@code JShell}.
*/
public static JShell create() {
return builder().build();
}
/**
- * Factory method for <code>JShell.Builder</code> which, in-turn, is used
- * for creating instances of <code>JShell</code>.
- * Create a default instance of <code>JShell</code> with
- * <code>JShell.builder().build()</code>. For more construction options
+ * Factory method for {@code JShell.Builder} which, in-turn, is used
+ * for creating instances of {@code JShell}.
+ * Create a default instance of {@code JShell} with
+ * {@code JShell.builder().build()}. For more construction options
* see {@link jdk.jshell.JShell.Builder}.
- * @return an instance of <code>Builder</code>.
+ * @return an instance of {@code Builder}.
* @see jdk.jshell.JShell.Builder
*/
public static Builder builder() {
@@ -341,9 +341,9 @@
/**
* Access to source code analysis functionality.
- * An instance of <code>JShell</code> will always return the same
- * <code>SourceCodeAnalysis</code> instance from
- * <code>sourceCodeAnalysis()</code>.
+ * An instance of {@code JShell} will always return the same
+ * {@code SourceCodeAnalysis} instance from
+ * {@code sourceCodeAnalysis()}.
* @return an instance of {@link SourceCodeAnalysis SourceCodeAnalysis}
* which can be used for source analysis such as completion detection and
* completion suggestions.
@@ -378,11 +378,11 @@
* occur for dropped, rejected, or already overwritten declarations.
* <p>
* The execution environment is out of process. If the evaluated code
- * causes the execution environment to terminate, this <code>JShell</code>
+ * causes the execution environment to terminate, this {@code JShell}
* instance will be closed but the calling process and VM remain valid.
* @param input The input String to evaluate
* @return the list of events directly or indirectly caused by this evaluation.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @see SourceCodeAnalysis#analyzeCompletion(String)
* @see JShell#onShutdown(java.util.function.Consumer)
*/
@@ -408,9 +408,9 @@
* @param snippet The snippet to remove
* @return The list of events from updating declarations dependent on the
* dropped snippet.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with
- * this <code>JShell</code> instance.
+ * this {@code JShell} instance.
*/
public List<SnippetEvent> drop(PersistentSnippet snippet) throws IllegalStateException {
checkIfAlive();
@@ -476,77 +476,77 @@
/**
* Returns the active variable snippets.
- * This convenience method is equivalent to <code>snippets()</code> filtered for
- * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
- * <code>&& snippet.kind() == Kind.VARIABLE</code>
- * and cast to <code>VarSnippet</code>.
+ * This convenience method is equivalent to {@code snippets()} filtered for
+ * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
+ * {@code && snippet.kind() == Kind.VARIABLE}
+ * and cast to {@code VarSnippet}.
* @return the active declared variables.
* @throws IllegalStateException if this JShell instance is closed.
*/
public List<VarSnippet> variables() throws IllegalStateException {
return snippets().stream()
- .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.VAR)
+ .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR)
.map(sn -> (VarSnippet) sn)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
/**
* Returns the active method snippets.
- * This convenience method is equivalent to <code>snippets()</code> filtered for
- * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
- * <code>&& snippet.kind() == Kind.METHOD</code>
+ * This convenience method is equivalent to {@code snippets()} filtered for
+ * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
+ * {@code && snippet.kind() == Kind.METHOD}
* and cast to MethodSnippet.
* @return the active declared methods.
* @throws IllegalStateException if this JShell instance is closed.
*/
public List<MethodSnippet> methods() throws IllegalStateException {
return snippets().stream()
- .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.METHOD)
+ .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD)
.map(sn -> (MethodSnippet)sn)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
/**
* Returns the active type declaration (class, interface, annotation type, and enum) snippets.
- * This convenience method is equivalent to <code>snippets()</code> filtered for
- * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
- * <code>&& snippet.kind() == Kind.TYPE_DECL</code>
+ * This convenience method is equivalent to {@code snippets()} filtered for
+ * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
+ * {@code && snippet.kind() == Kind.TYPE_DECL}
* and cast to TypeDeclSnippet.
* @return the active declared type declarations.
* @throws IllegalStateException if this JShell instance is closed.
*/
public List<TypeDeclSnippet> types() throws IllegalStateException {
return snippets().stream()
- .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.TYPE_DECL)
+ .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL)
.map(sn -> (TypeDeclSnippet) sn)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
/**
* Returns the active import snippets.
- * This convenience method is equivalent to <code>snippets()</code> filtered for
- * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
- * <code>&& snippet.kind() == Kind.IMPORT</code>
+ * This convenience method is equivalent to {@code snippets()} filtered for
+ * {@link jdk.jshell.Snippet.Status#isActive() status(snippet).isActive()}
+ * {@code && snippet.kind() == Kind.IMPORT}
* and cast to ImportSnippet.
* @return the active declared import declarations.
* @throws IllegalStateException if this JShell instance is closed.
*/
public List<ImportSnippet> imports() throws IllegalStateException {
return snippets().stream()
- .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.IMPORT)
+ .filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT)
.map(sn -> (ImportSnippet) sn)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
/**
* Return the status of the snippet.
- * This is updated either because of an explicit <code>eval()</code> call or
+ * This is updated either because of an explicit {@code eval()} call or
* an automatic update triggered by a dependency.
- * @param snippet the <code>Snippet</code> to look up
+ * @param snippet the {@code Snippet} to look up
* @return the status corresponding to this snippet
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with
- * this <code>JShell</code> instance.
+ * this {@code JShell} instance.
*/
public Status status(Snippet snippet) {
return checkValidSnippet(snippet).status();
@@ -554,14 +554,14 @@
/**
* Return the diagnostics of the most recent evaluation of the snippet.
- * The evaluation can either because of an explicit <code>eval()</code> call or
+ * The evaluation can either because of an explicit {@code eval()} call or
* an automatic update triggered by a dependency.
- * @param snippet the <code>Snippet</code> to look up
+ * @param snippet the {@code Snippet} to look up
* @return the diagnostics corresponding to this snippet. This does not
- * include unresolvedDependencies references reported in <code>unresolvedDependencies()</code>.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * include unresolvedDependencies references reported in {@code unresolvedDependencies()}.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with
- * this <code>JShell</code> instance.
+ * this {@code JShell} instance.
*/
public List<Diag> diagnostics(Snippet snippet) {
return Collections.unmodifiableList(checkValidSnippet(snippet).diagnostics());
@@ -573,13 +573,13 @@
* declarations, the names of current unresolved dependencies for
* the snippet.
* The returned value of this method, for a given method may change when an
- * <code>eval()</code> or <code>drop()</code> of another snippet causes
+ * {@code eval()} or {@code drop()} of another snippet causes
* an update of a dependency.
- * @param snippet the declaration <code>Snippet</code> to look up
+ * @param snippet the declaration {@code Snippet} to look up
* @return the list of symbol names that are currently unresolvedDependencies.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with
- * this <code>JShell</code> instance.
+ * this {@code JShell} instance.
*/
public List<String> unresolvedDependencies(DeclarationSnippet snippet) {
return Collections.unmodifiableList(checkValidSnippet(snippet).unresolved());
@@ -589,9 +589,9 @@
* Get the current value of a variable.
* @param snippet the variable Snippet whose value is queried.
* @return the current value of the variable referenced by snippet.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
* @throws IllegalArgumentException if the snippet is not associated with
- * this <code>JShell</code> instance.
+ * this {@code JShell} instance.
* @throws IllegalArgumentException if the variable's status is anything but
* {@link jdk.jshell.Snippet.Status#VALID}.
*/
@@ -611,7 +611,7 @@
* Each call adds a new subscription.
* @param listener Action to perform when the Status changes.
* @return A token which can be used to {@linkplain JShell#unsubscribe unsubscribe} this subscription.
- * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+ * @throws IllegalStateException if this {@code JShell} instance is closed.
*/
public Subscription onSnippetEvent(Consumer<SnippetEvent> listener)
throws IllegalStateException {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Thu Jun 09 19:06:36 2016 +0000
@@ -36,9 +36,9 @@
* An instance of Snippet (including its subclasses) is immutable: an access to
* any of its methods will always return the same result.
* For information about the current state of the snippet within the JShell
- * state engine, query <code>JShell</code> passing the Snippet.
+ * state engine, query {@code JShell} passing the Snippet.
* <p>
- * Because it is immutable, <code>Snippet</code> (and subclasses) is thread-safe.
+ * Because it is immutable, {@code Snippet} (and subclasses) is thread-safe.
* @author Robert Field
* @see jdk.jshell.JShell#status
*/
@@ -46,20 +46,21 @@
/**
* Describes the general kind of snippet.
- * The <code>Kind</code> is an immutable property of a Snippet.
+ * The {@code Kind} is an immutable property of a Snippet.
* It is accessed with {@link jdk.jshell.Snippet#kind()}.
- * The <code>Kind</code> can be used to determine which
+ * The {@code Kind} can be used to determine which
* subclass of Snippet it is. For example,
* {@link jdk.jshell.JShell#eval eval("int three() { return 3; }")} will
- * return a snippet creation event. The <code>Kind</code> of that Snippet
- * will be <code>METHOD</code>, from which you know that the subclass
- * of <code>Snippet</code> is <code>MethodSnippet</code> and it can be
+ * return a snippet creation event. The {@code Kind} of that Snippet
+ * will be {@code METHOD}, from which you know that the subclass
+ * of {@code Snippet} is {@code MethodSnippet} and it can be
* cast as such.
*/
public enum Kind {
/**
- * An import declaration: <code>import</code> ...
+ * An import declaration: {@code import} ...
* The snippet is an instance of {@link jdk.jshell.ImportSnippet}.
+ * <P>
* An import can be a single type import
* ({@link jdk.jshell.Snippet.SubKind#SINGLE_TYPE_IMPORT_SUBKIND}),
* a static single import
@@ -69,7 +70,10 @@
* or a static on-demand type import
* ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}) --
* use {@link jdk.jshell.Snippet#subKind()} to distinguish.
+ * <P>
* @jls 8.3: importDeclaration.
+ * <P>
+ * An import declaration is {@linkplain Kind#isPersistent() persistent}.
*/
IMPORT(true),
@@ -78,19 +82,26 @@
* Which includes: NormalClassDeclaration, EnumDeclaration,
* NormalInterfaceDeclaration, and AnnotationTypeDeclaration.
* The snippet is an instance of {@link jdk.jshell.TypeDeclSnippet}.
+ * <P>
* A type declaration may be an interface
* {@link jdk.jshell.Snippet.SubKind#INTERFACE_SUBKIND},
* classes {@link jdk.jshell.Snippet.SubKind#CLASS_SUBKIND}, enums, and
* annotation interfaces -- see {@link jdk.jshell.Snippet.SubKind} to
* differentiate.
+ * <P>
* @jls 7.6: TypeDeclaration.
+ * <P>
+ * A type declaration is {@linkplain Kind#isPersistent() persistent}.
*/
TYPE_DECL(true),
/**
* A method declaration.
* The snippet is an instance of {@link jdk.jshell.MethodSnippet}.
+ * <P>
* @jls 8.4: MethodDeclaration.
+ * <P>
+ * A method declaration is {@linkplain Kind#isPersistent() persistent}.
*/
METHOD(true),
@@ -98,20 +109,28 @@
* One variable declaration.
* Corresponding to one <i>VariableDeclarator</i>.
* The snippet is an instance of {@link jdk.jshell.VarSnippet}.
+ * <P>
* The variable may be with or without initializer, or be a temporary
* variable representing an expression -- see
* {@link jdk.jshell.Snippet.SubKind}to differentiate.
+ * <P>
* @jls 8.3: FieldDeclaration.
+ * <P>
+ * A variable declaration is {@linkplain Kind#isPersistent() persistent}.
*/
VAR(true),
/**
* An expression, with or without side-effects.
* The snippet is an instance of {@link jdk.jshell.ExpressionSnippet}.
+ * <P>
* The expression is currently either a simple named reference to a
* variable ({@link jdk.jshell.Snippet.SubKind#VAR_VALUE_SUBKIND}) or an
* assignment (both of which have natural referencing
* names) -- see {@link jdk.jshell.Snippet.SubKind} to differentiate.
+ * All other expression forms (operators, method calls, ...) generate a
+ * scratch variable and so are instead of the VAR Kind.
+ * <P>
* @jls 15: Expression.
*/
EXPRESSION(false),
@@ -119,6 +138,7 @@
/**
* A statement.
* The snippet is an instance of {@link jdk.jshell.StatementSnippet}.
+ * <P>
* @jls 14.5: Statement.
*/
STATEMENT(false),
@@ -130,15 +150,27 @@
*/
ERRONEOUS(false);
- /**
- * True if this kind of snippet adds a declaration or declarations
- * which are visible to subsequent evaluations.
- */
- public final boolean isPersistent;
+ private final boolean isPersistent;
Kind(boolean isPersistent) {
this.isPersistent = isPersistent;
}
+
+ /**
+ * Indicates whether this {@code Kind} of Snippet is persistent. Only
+ * declarations are persistent because they influence future Snippets.
+ * <p>
+ * Note that though the {@code Kind} of
+ * a Snippet may be persistent, that does not mean that the Snippet will
+ * persist; For example it may be invalid or have been dropped. See:
+ * {@link jdk.jshell.Snippet.Status#isDefined()}.
+ *
+ * @return {@code true} if this {@code Kind} of {@code Snippet} is
+ * visible to subsequent evaluations; otherwise {@code false}
+ */
+ public boolean isPersistent() {
+ return isPersistent;
+ }
}
/**
@@ -178,41 +210,41 @@
/**
* A class declaration.
- * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+ * A {@code SubKind} of {@link Kind#TYPE_DECL}.
* @jls 8.1. NormalClassDeclaration.
*/
CLASS_SUBKIND(Kind.TYPE_DECL),
/**
* An interface declaration.
- * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+ * A {@code SubKind} of {@link Kind#TYPE_DECL}.
* @jls 9.1. NormalInterfaceDeclaration.
*/
INTERFACE_SUBKIND(Kind.TYPE_DECL),
/**
* An enum declaration.
- * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+ * A {@code SubKind} of {@link Kind#TYPE_DECL}.
* @jls 8.9. EnumDeclaration.
*/
ENUM_SUBKIND(Kind.TYPE_DECL),
/**
- * An annotation interface declaration. A <code>SubKind</code> of
+ * An annotation interface declaration. A {@code SubKind} of
* {@link Kind#TYPE_DECL}.
* @jls 9.6. AnnotationTypeDeclaration.
*/
ANNOTATION_TYPE_SUBKIND(Kind.TYPE_DECL),
/**
- * A method. The only <code>SubKind</code> for {@link Kind#METHOD}.
+ * A method. The only {@code SubKind} for {@link Kind#METHOD}.
* @jls 8.4. MethodDeclaration.
*/
METHOD_SUBKIND(Kind.METHOD),
/**
* A variable declaration without initializer.
- * A <code>SubKind</code> of {@link Kind#VAR}.
+ * A {@code SubKind} of {@link Kind#VAR}.
* @jls 8.3. VariableDeclarator without VariableInitializer in
* FieldDeclaration.
*/
@@ -220,7 +252,7 @@
/**
* A variable declaration with an initializer expression. A
- * <code>SubKind</code> of {@link Kind#VAR}.
+ * {@code SubKind} of {@link Kind#VAR}.
* @jls 8.3. VariableDeclarator with VariableInitializer in
* FieldDeclaration.
*/
@@ -228,20 +260,20 @@
/**
* An expression whose value has been stored in a temporary variable. A
- * <code>SubKind</code> of {@link Kind#VAR}.
+ * {@code SubKind} of {@link Kind#VAR}.
* @jls 15. Primary.
*/
TEMP_VAR_EXPRESSION_SUBKIND(Kind.VAR, true, true),
/**
- * A simple variable reference expression. A <code>SubKind</code> of
+ * A simple variable reference expression. A {@code SubKind} of
* {@link Kind#EXPRESSION}.
* @jls 15.11. Field Access as 3.8. Identifier.
*/
VAR_VALUE_SUBKIND(Kind.EXPRESSION, true, true),
/**
- * An assignment expression. A <code>SubKind</code> of
+ * An assignment expression. A {@code SubKind} of
* {@link Kind#EXPRESSION}.
* @jls 15.26. Assignment.
*/
@@ -249,18 +281,18 @@
/**
* An expression which has not been wrapped in a temporary variable
- * (reserved). A <code>SubKind</code> of {@link Kind#EXPRESSION}.
+ * (reserved). A {@code SubKind} of {@link Kind#EXPRESSION}.
*/
OTHER_EXPRESSION_SUBKIND(Kind.EXPRESSION, true, true),
/**
- * A statement. The only <code>SubKind</code> for {@link Kind#STATEMENT}.
+ * A statement. The only {@code SubKind} for {@link Kind#STATEMENT}.
* @jls 14.5. Statement.
*/
STATEMENT_SUBKIND(Kind.STATEMENT, true, false),
/**
- * An unknown snippet. The only <code>SubKind</code> for
+ * An unknown snippet. The only {@code SubKind} for
* {@link Kind#ERRONEOUS}.
*/
UNKNOWN_SUBKIND(Kind.ERRONEOUS, false, false);
@@ -282,27 +314,30 @@
}
/**
- * Is this <code>SubKind</code> executable?
+ * Indicates whether this {@code SubKind} is executable.
*
- * @return true if this <code>SubKind</code> can be executed.
+ * @return {@code true} if this {@code SubKind} can
+ * be executed; otherwise {@code false}
*/
public boolean isExecutable() {
return isExecutable;
}
/**
- * Is this <code>SubKind</code> executable and is non-<code>void</code>.
+ * Indicates whether this {@code SubKind} is executable and
+ * is non-{@code void}.
*
- * @return true if this <code>SubKind</code> has a value.
+ * @return {@code true} if this {@code SubKind} has
+ * a value; otherwise {@code false}
*/
public boolean hasValue() {
return hasValue;
}
/**
- * The {@link Snippet.Kind} that corresponds to this <code>SubKind</code>.
+ * The {@link Snippet.Kind} that corresponds to this {@code SubKind}.
*
- * @return the fixed <code>Kind</code> for this <code>SubKind</code>
+ * @return the fixed {@code Kind} for this {@code SubKind}
*/
public Kind kind() {
return kind;
@@ -313,104 +348,112 @@
* Describes the current state of a Snippet.
* This is a dynamic property of a Snippet within the JShell state --
* thus is retrieved with a {@linkplain
- * jdk.jshell.JShell#status(jdk.jshell.Snippet) query on <code>JShell</code>}.
+ * jdk.jshell.JShell#status(jdk.jshell.Snippet) query on {@code JShell}}.
* <p>
- * The <code>Status</code> changes as the state changes.
+ * The {@code Status} changes as the state changes.
* For example, creation of another snippet with
* {@link jdk.jshell.JShell#eval(java.lang.String) eval}
* may resolve dependencies of this Snippet (or invalidate those dependencies), or
* {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwrite}
* this Snippet changing its
- * <code>Status</code>.
+ * {@code Status}.
* <p>
- * Important properties associated with <code>Status</code> are:
- * {@link jdk.jshell.Snippet.Status#isDefined}, if it is visible to other
+ * Important properties associated with {@code Status} are:
+ * {@link jdk.jshell.Snippet.Status#isDefined()}, if it is visible to other
* existing and new snippets; and
- * {@link jdk.jshell.Snippet.Status#isActive}, if, as the
+ * {@link jdk.jshell.Snippet.Status#isActive()}, if, as the
* JShell state changes, the snippet will update, possibly
- * changing <code>Status</code>.
+ * changing {@code Status}.
* An executable Snippet can only be executed if it is in the the
- * {@link jdk.jshell.Snippet.Status#VALID} <code>Status</code>.
+ * {@link jdk.jshell.Snippet.Status#VALID} {@code Status}.
* @see JShell#status(jdk.jshell.Snippet)
*/
public enum Status {
/**
* The snippet is a valid snippet
- * (in the context of current <code>JShell</code> state).
- * Only snippets with <code>VALID</code>
- * <code>Status</code> can be executed (though not all
- * <code>VALID</code> snippets have executable code).
- * If the snippet is a declaration or import, it is visible to other
- * snippets ({@link Status#isDefined isDefined} <code> == true</code>).
+ * (in the context of current {@code JShell} state).
+ * Only snippets with {@code VALID}
+ * {@code Status} can be executed (though not all
+ * {@code VALID} snippets have executable code).
+ * <p>
+ * The snippet is defined
+ * ({@link Status#isDefined() isDefined() == true}).
+ * If the snippet is a declaration or import
+ * ({@link Snippet.Kind#isPersistent()}),
+ * it is visible to other snippets
* <p>
* The snippet will update as dependents change
- * ({@link Status#isActive isActive} <code> == true</code>), its
- * status could become <code>RECOVERABLE_DEFINED</code>, <code>RECOVERABLE_NOT_DEFINED</code>,
- * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+ * ({@link Status#isActive() isActive() == true}), its
+ * status could become {@code RECOVERABLE_DEFINED}, {@code RECOVERABLE_NOT_DEFINED},
+ * {@code DROPPED}, or {@code OVERWRITTEN}.
*/
VALID(true, true),
/**
* The snippet is a declaration snippet with potentially recoverable
* unresolved references or other issues in its body
- * (in the context of current <code>JShell</code> state).
+ * (in the context of current {@code JShell} state).
* Only a {@link jdk.jshell.DeclarationSnippet} can have this
- * <code>Status</code>.
+ * {@code Status}.
+ * <p>
* The snippet has a valid signature and it is visible to other
- * snippets ({@link Status#isDefined isDefined} <code> == true</code>)
+ * snippets
+ * ({@link Status#isDefined() isDefined() == true})
* and thus can be referenced in existing or new snippets
* but the snippet cannot be executed.
* An {@link UnresolvedReferenceException} will be thrown on an attempt
* to execute it.
* <p>
* The snippet will update as dependents change
- * ({@link Status#isActive isActive} <code> == true</code>), its
- * status could become <code>VALID</code>, <code>RECOVERABLE_NOT_DEFINED</code>,
- * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+ * ({@link Status#isActive() isActive() == true}), its
+ * status could become {@code VALID}, {@code RECOVERABLE_NOT_DEFINED},
+ * {@code DROPPED}, or {@code OVERWRITTEN}.
* <p>
- * Note: both <code>RECOVERABLE_DEFINED</code> and <code>RECOVERABLE_NOT_DEFINED</code>
+ * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED}
* indicate potentially recoverable errors, they differ in that, for
- * <code>RECOVERABLE_DEFINED</code>, the snippet is
- * {@linkplain Status#isDefined defined}.
+ * {@code RECOVERABLE_DEFINED}, the snippet is
+ * {@linkplain Status#isDefined() defined}.
*/
RECOVERABLE_DEFINED(true, true),
/**
* The snippet is a declaration snippet with potentially recoverable
* unresolved references or other issues
- * (in the context of current <code>JShell</code> state).
+ * (in the context of current {@code JShell} state).
* Only a {@link jdk.jshell.DeclarationSnippet} can have this
- * <code>Status</code>.
+ * {@code Status}.
+ * <p>
* The snippet has an invalid signature or the implementation is
* otherwise unable to define it.
* The snippet it is not visible to other snippets
- * ({@link Status#isDefined isDefined} <code> == false</code>)
+ * ({@link Status#isDefined() isDefined() == false})
* and thus cannot be referenced or executed.
* <p>
* The snippet will update as dependents change
- * ({@link Status#isActive isActive} <code> == true</code>), its
- * status could become <code>VALID</code>, <code>RECOVERABLE_DEFINED</code>,
- * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+ * ({@link Status#isActive() isActive() == true}), its
+ * status could become {@code VALID}, {@code RECOVERABLE_DEFINED},
+ * {@code DROPPED}, or {@code OVERWRITTEN}.
* <p>
- * Note: both <code>RECOVERABLE_DEFINED</code> and <code>RECOVERABLE_NOT_DEFINED</code>
+ * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED}
* indicate potentially recoverable errors, they differ in that, for
- * <code>RECOVERABLE_DEFINED</code>, the snippet is
- * {@linkplain Status#isDefined defined}.
+ * {@code RECOVERABLE_DEFINED}, the snippet is
+ * {@linkplain Status#isDefined() defined}.
*/
RECOVERABLE_NOT_DEFINED(true, false),
/**
* The snippet is inactive because of an explicit call to
- * the {@link JShell#drop(jdk.jshell.PersistentSnippet)}.
+ * the {@link JShell#drop(PersistentSnippet)}.
* Only a {@link jdk.jshell.PersistentSnippet} can have this
- * <code>Status</code>.
+ * {@code Status}.
+ * <p>
* The snippet is not visible to other snippets
- * ({@link Status#isDefined isDefined} <code> == false</code>)
+ * ({@link Status#isDefined() isDefined() == false})
* and thus cannot be referenced or executed.
* <p>
* The snippet will not update as dependents change
- * ({@link Status#isActive isActive} <code> == false</code>), its
- * <code>Status</code> will never change again.
+ * ({@link Status#isActive() isActive() == false}), its
+ * {@code Status} will never change again.
*/
DROPPED(false, false),
@@ -418,29 +461,30 @@
* The snippet is inactive because it has been replaced by a new
* snippet. This occurs when the new snippet added with
* {@link jdk.jshell.JShell#eval} matches a previous snippet.
- * A <code>TypeDeclSnippet</code> will match another
- * <code>TypeDeclSnippet</code> if the names match.
- * For example <code>class X { }</code> will overwrite
- * <code>class X { int ii; }</code> or
- * <code>interface X { }</code>.
- * A <code>MethodSnippet</code> will match another
- * <code>MethodSnippet</code> if the names and parameter types
+ * A {@code TypeDeclSnippet} will match another
+ * {@code TypeDeclSnippet} if the names match.
+ * For example {@code class X { }} will overwrite
+ * {@code class X { int ii; }} or
+ * {@code interface X { }}.
+ * A {@code MethodSnippet} will match another
+ * {@code MethodSnippet} if the names and parameter types
* match.
- * For example <code>void m(int a) { }</code> will overwrite
- * <code>int m(int a) { return a+a; }</code>.
- * A <code>VarSnippet</code> will match another
- * <code>VarSnippet</code> if the names match.
- * For example <code>double z;</code> will overwrite
- * <code>long z = 2L;</code>.
+ * For example {@code void m(int a) { }} will overwrite
+ * {@code int m(int a) { return a+a; }}.
+ * A {@code VarSnippet} will match another
+ * {@code VarSnippet} if the names match.
+ * For example {@code double z;} will overwrite
+ * {@code long z = 2L;}.
* Only a {@link jdk.jshell.PersistentSnippet} can have this
- * <code>Status</code>.
+ * {@code Status}.
+ * <p>
* The snippet is not visible to other snippets
- * ({@link Status#isDefined isDefined} <code> == false</code>)
+ * ({@link Status#isDefined() isDefined() == false})
* and thus cannot be referenced or executed.
* <p>
* The snippet will not update as dependents change
- * ({@link Status#isActive isActive} <code> == false</code>), its
- * <code>Status</code> will never change again.
+ * ({@link Status#isActive() isActive() == false}), its
+ * {@code Status} will never change again.
*/
OVERWRITTEN(false, false),
@@ -448,13 +492,14 @@
* The snippet is inactive because it failed compilation on initial
* evaluation and it is not capable of becoming valid with further
* changes to the JShell state.
+ * <p>
* The snippet is not visible to other snippets
- * ({@link Status#isDefined isDefined} <code> == false</code>)
+ * ({@link Status#isDefined() isDefined() == false})
* and thus cannot be referenced or executed.
* <p>
* The snippet will not update as dependents change
- * ({@link Status#isActive isActive} <code> == false</code>), its
- * <code>Status</code> will never change again.
+ * ({@link Status#isActive() isActive() == false}), its
+ * {@code Status} will never change again.
*/
REJECTED(false, false),
@@ -463,35 +508,47 @@
* Used only in {@link SnippetEvent#previousStatus} for new
* snippets.
* {@link jdk.jshell.JShell#status(jdk.jshell.Snippet) JShell.status(Snippet)}
- * will never return this <code>Status</code>.
- * Vacuously, {@link Status#isDefined isDefined} and
- * {@link Status#isActive isActive} are both defined <code>false</code>.
+ * will never return this {@code Status}.
+ * <p>
+ * Vacuously, {@link Status#isDefined() isDefined()} and
+ * {@link Status#isActive() isActive()} are both defined {@code false}.
*/
NONEXISTENT(false, false);
- /**
- * Is the Snippet active, that is, will the snippet
- * be re-evaluated when a new
- * {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet)
- * JShell.drop(PersistentSnippet)} that could change
- * its status is invoked? This is more broad than
- * {@link Status#isDefined} since a Snippet which is
- * {@link Status#RECOVERABLE_NOT_DEFINED}
- * will be updated.
- */
- public final boolean isActive;
-
- /**
- * Is the snippet currently part of the defined state of the JShell?
- * Is it visible to compilation of other snippets?
- */
- public final boolean isDefined;
+ private final boolean isActive;
+ private final boolean isDefined;
Status(boolean isActive, boolean isDefined) {
this.isActive = isActive;
this.isDefined = isDefined;
}
+
+ /**
+ * Indicates whether the Snippet is active, that is,
+ * will the snippet be re-evaluated when a new
+ * {@link JShell#eval(java.lang.String) JShell.eval(String)} or
+ * {@link JShell#drop(jdk.jshell.PersistentSnippet)
+ * JShell.drop(PersistentSnippet)} that could change
+ * its status is invoked. This is more broad than
+ * {@link Status#isDefined()} since a Snippet which is
+ * {@link Status#RECOVERABLE_NOT_DEFINED}
+ * will be updated.
+ *
+ * @return {@code true} if the Snippet is active; otherwise {@code false}
+ */
+ public boolean isActive() {
+ return isActive;
+ }
+
+ /**
+ * Indicates whether the snippet is currently part of the defined state
+ * of the JShell. Is it visible to compilation of other snippets?
+ * @return {@code true} if the Snippet is defined; otherwise
+ * {@code false}
+ */
+ public boolean isDefined() {
+ return isDefined;
+ }
}
private final Key key;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Thu Jun 09 19:06:36 2016 +0000
@@ -33,9 +33,9 @@
* {@link JShell#drop(jdk.jshell.PersistentSnippet) JShell.drop(PersistentSnippet)},
* or indirectly by these same methods as
* dependencies change or Snippets are overwritten. For direct changes, the
- * {@link SnippetEvent#causeSnippet()} is <code>null</code>.
+ * {@link SnippetEvent#causeSnippet()} is {@code null}.
* <p>
- * <code>SnippetEvent</code> is immutable: an access to
+ * {@code SnippetEvent} is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
* @author Robert Field
@@ -64,7 +64,7 @@
/**
* The Snippet which has changed
- * @return the return the Snippet whose <code>Status</code> has changed.
+ * @return the return the Snippet whose {@code Status} has changed.
*/
public Snippet snippet() {
return snippet;
@@ -81,7 +81,7 @@
/**
* The after status. Note: this may be the same as the previous status (not
- * all changes cause a <code>Status</code> change.
+ * all changes cause a {@code Status} change.
* @return the status
*/
public Status status() {
@@ -89,12 +89,14 @@
}
/**
- * Has the signature changed? Coming in or out of definition
- * (status.isDefined) is always a signature change. An overwritten Snippet
+ * Indicates whether the signature has changed. Coming in or out of
+ * {@linkplain Status#isDefined() definition} is always a signature change.
+ * An overwritten Snippet
* {@link jdk.jshell.Snippet.Status#OVERWRITTEN (status == OVERWRITTEN)}
- * is always <code>false</code> as responsibility for the
+ * is always {@code false} as responsibility for the
* definition has passed to the overwriting definition.
- * @return <code>true</code> if the signature changed.
+ *
+ * @return {@code true} if the signature changed; otherwise {@code false}
*/
public boolean isSignatureChange() {
return isSignatureChange;
@@ -102,13 +104,13 @@
/**
* Either the snippet whose change caused this update or
- * <code>null</code>. This returns <code>null</code> if this change is the
+ * {@code null}. This returns {@code null} if this change is the
* creation of a new Snippet via
* {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
* explicit drop of a Snippet with
* {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop}.
*
- * @return the Snippet which caused this change or <code>null</code> if
+ * @return the Snippet which caused this change or {@code null} if
* directly caused by an API action.
*/
public Snippet causeSnippet() {
@@ -118,8 +120,8 @@
/**
* An instance of {@link jdk.jshell.UnresolvedReferenceException}, if an unresolved reference was
* encountered, or an instance of {@link jdk.jshell.EvalException} if an exception was thrown
- * during execution, otherwise <code>null</code>.
- * @return the exception or <code>null</code>.
+ * during execution, otherwise {@code null}.
+ * @return the exception or {@code null}.
*/
public JShellException exception() {
return exception;
@@ -128,7 +130,7 @@
/**
* The result value of successful run. The value is null if not executed
* or an exception was thrown.
- * @return the value or <code>null</code>.
+ * @return the value or {@code null}.
*/
public String value() {
return value;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java Thu Jun 09 19:06:36 2016 +0000
@@ -82,7 +82,7 @@
Snippet getSnippet(int ki) {
Snippet sn = getSnippetDeadOrAlive(ki);
- return (sn != null && !sn.status().isActive)
+ return (sn != null && !sn.status().isActive())
? null
: sn;
}
@@ -102,7 +102,7 @@
StringBuilder sb = new StringBuilder();
sb.append("package ").append(REPL_PACKAGE).append(";\n");
for (Snippet si : keyIndexToSnippet) {
- if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
+ if (si != null && si.status().isDefined() && (except == null || !except.contains(si.key()))) {
sb.append(si.importLine(state));
}
}
@@ -114,7 +114,7 @@
}
List<Snippet> getDependents(Snippet snip) {
- if (!snip.kind().isPersistent) {
+ if (!snip.kind().isPersistent()) {
return Collections.emptyList();
}
Set<Integer> depset;
@@ -190,6 +190,6 @@
private Stream<ImportSnippet> importSnippets() {
return state.keyMap.importKeys()
.map(key -> (ImportSnippet)getSnippet(key))
- .filter(sn -> sn != null && state.status(sn).isDefined);
+ .filter(sn -> sn != null && state.status(sn).isDefined());
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Thu Jun 09 19:06:36 2016 +0000
@@ -51,7 +51,7 @@
/**
* Compute possible follow-ups for the given input.
- * Uses information from the current <code>JShell</code> state, including
+ * Uses information from the current {@code JShell} state, including
* type information, to filter the suggestions.
* @param input the user input, so far
* @param cursor the current position of the cursors in the given {@code input} text
@@ -97,11 +97,16 @@
SourceCodeAnalysis() {}
/**
- * The result of <code>analyzeCompletion(String input)</code>.
+ * The result of {@code analyzeCompletion(String input)}.
* Describes the completeness and position of the first snippet in the given input.
*/
public static class CompletionInfo {
+ private final Completeness completeness;
+ private final int unitEndPos;
+ private final String source;
+ private final String remaining;
+
CompletionInfo(Completeness completeness, int unitEndPos, String source, String remaining) {
this.completeness = completeness;
this.unitEndPos = unitEndPos;
@@ -111,25 +116,42 @@
/**
* The analyzed completeness of the input.
+ *
+ * @return an enum describing the completeness of the input string.
*/
- public final Completeness completeness;
+ public Completeness completeness() {
+ return completeness;
+ }
/**
- * The end of the first unit of source.
+ * Input remaining after the complete part of the source.
+ *
+ * @return the portion of the input string that remains after the
+ * complete Snippet
*/
- public final int unitEndPos;
+ public String remaining() {
+ return remaining;
+ }
/**
- * Source code for the first unit of code input. For example, first
- * statement, or first method declaration. Trailing semicolons will
- * be added, as needed
+ * Source code for the first Snippet of code input. For example, first
+ * statement, or first method declaration. Trailing semicolons will be
+ * added, as needed.
+ *
+ * @return the source of the first encountered Snippet
*/
- public final String source;
+ public String source() {
+ return source;
+ }
/**
- * Input remaining after the source
+ * The end of the first Snippet of source.
+ *
+ * @return the position of the end of the first Snippet in the input.
*/
- public final String remaining;
+ public int unitEndPos() {
+ return unitEndPos;
+ }
}
/**
@@ -181,16 +203,24 @@
*/
UNKNOWN(true);
- /**
- * Is the first snippet of source complete. For example, "x=" is not
- * complete, but "x=2" is complete, even though a subsequent line could
- * make it "x=2+2". Already erroneous code is marked complete.
- */
- public final boolean isComplete;
+ private final boolean isComplete;
Completeness(boolean isComplete) {
this.isComplete = isComplete;
}
+
+ /**
+ * Indicates whether the first snippet of source is complete.
+ * For example, "{@code x=}" is not
+ * complete, but "{@code x=2}" is complete, even though a subsequent line could
+ * make it "{@code x=2+2}". Already erroneous code is marked complete.
+ *
+ * @return {@code true} if the input is or begins a complete Snippet;
+ * otherwise {@code false}
+ */
+ public boolean isComplete() {
+ return isComplete;
+ }
}
/**
@@ -198,27 +228,40 @@
*/
public static class Suggestion {
+ private final String continuation;
+ private final boolean matchesType;
+
/**
* Create a {@code Suggestion} instance.
+ *
* @param continuation a candidate continuation of the user's input
- * @param isSmart is the candidate "smart"
+ * @param matchesType does the candidate match the target type
*/
- public Suggestion(String continuation, boolean isSmart) {
+ public Suggestion(String continuation, boolean matchesType) {
this.continuation = continuation;
- this.isSmart = isSmart;
+ this.matchesType = matchesType;
}
/**
* The candidate continuation of the given user's input.
+ *
+ * @return the continuation string
*/
- public final String continuation;
+ public String continuation() {
+ return continuation;
+ }
/**
- * Is it an input continuation that matches the target type and is thus more
- * likely to be the desired continuation. A smart continuation
- * is preferred.
+ * Indicates whether input continuation matches the target type and is thus
+ * more likely to be the desired continuation. A matching continuation is
+ * preferred.
+ *
+ * @return {@code true} if this suggested continuation matches the
+ * target type; otherwise {@code false}
*/
- public final boolean isSmart;
+ public boolean matchesType() {
+ return matchesType;
+ }
}
/**
@@ -259,22 +302,25 @@
}
/**
- * Whether the result is based on up to date data. The
+ * Indicates whether the result is based on up to date data. The
* {@link SourceCodeAnalysis#listQualifiedNames(java.lang.String, int) listQualifiedNames}
* method may return before the classpath is fully inspected, in which case this method will
* return {@code false}. If the result is based on a fully inspected classpath, this method
* will return {@code true}.
*
- * @return true iff the results is based on up-to-date data
+ * @return {@code true} if the result is based on up-to-date data;
+ * otherwise {@code false}
*/
public boolean isUpToDate() {
return upToDate;
}
/**
- * Whether the given simple name in the original code refers to a resolvable element.
+ * Indicates whether the given simple name in the original code refers
+ * to a resolvable element.
*
- * @return true iff the given simple name in the original code refers to a resolvable element
+ * @return {@code true} if the given simple name in the original code
+ * refers to a resolvable element; otherwise {@code false}
*/
public boolean isResolvable() {
return resolvable;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Jun 09 19:06:36 2016 +0000
@@ -276,8 +276,8 @@
}
String requiredPrefix = identifier;
return computeSuggestions(codeWrap, cursor, anchor).stream()
- .filter(s -> s.continuation.startsWith(requiredPrefix) && !s.continuation.equals(REPL_DOESNOTMATTER_CLASS_NAME))
- .sorted(Comparator.comparing(s -> s.continuation))
+ .filter(s -> s.continuation().startsWith(requiredPrefix) && !s.continuation().equals(REPL_DOESNOTMATTER_CLASS_NAME))
+ .sorted(Comparator.comparing(s -> s.continuation()))
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
}
@@ -1223,9 +1223,9 @@
public String analyzeType(String code, int cursor) {
code = code.substring(0, cursor);
CompletionInfo completionInfo = analyzeCompletion(code);
- if (!completionInfo.completeness.isComplete)
+ if (!completionInfo.completeness().isComplete())
return null;
- if (completionInfo.completeness == Completeness.COMPLETE_WITH_SEMI) {
+ if (completionInfo.completeness() == Completeness.COMPLETE_WITH_SEMI) {
code += ";";
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Thu Jun 09 19:06:36 2016 +0000
@@ -257,7 +257,7 @@
}
boolean isDefined() {
- return status.isDefined;
+ return status.isDefined();
}
/**
@@ -268,7 +268,7 @@
Stream<String> classesToLoad(List<String> classnames) {
toRedefine = new ArrayList<>();
List<String> toLoad = new ArrayList<>();
- if (status.isDefined && !isImport()) {
+ if (status.isDefined() && !isImport()) {
// Classes should only be loaded/redefined if the compile left them
// in a defined state. Imports do not have code and are not loaded.
for (String cn : classnames) {
@@ -312,8 +312,8 @@
}
private boolean sigChanged() {
- return (status.isDefined != prevStatus.isDefined)
- || (status.isDefined && !si.className().equals(classNameInitial))
+ return (status.isDefined() != prevStatus.isDefined())
+ || (status.isDefined() && !si.className().equals(classNameInitial))
|| signatureChanged;
}
@@ -328,7 +328,7 @@
Stream<Unit> dependents() {
return state.maps.getDependents(si)
.stream()
- .filter(xsi -> xsi != si && xsi.status().isActive)
+ .filter(xsi -> xsi != si && xsi.status().isActive())
.map(xsi -> new Unit(state, xsi, si, new DiagList()));
}
@@ -338,7 +338,7 @@
}
private void markOldDeclarationOverwritten() {
- if (si != siOld && siOld != null && siOld.status().isActive) {
+ if (si != siOld && siOld != null && siOld.status().isActive()) {
// Mark the old declaraion as replaced
replaceOldEvent = new SnippetEvent(siOld,
siOld.status(), OVERWRITTEN,
@@ -374,7 +374,7 @@
if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
// Defined methods can overwrite methods of other (equivalent) snippets
- if (isNew && si.kind() == Kind.METHOD && status.isDefined) {
+ if (isNew && si.kind() == Kind.METHOD && status.isDefined()) {
MethodSnippet msi = (MethodSnippet)si;
String oqpt = msi.qualifiedParameterTypes();
String nqpt = computeQualifiedParameterTypes(at, msi);
@@ -399,7 +399,7 @@
// same computed qualified parameter types
Status overwrittenStatus = null;
for (MethodSnippet sn : state.methods()) {
- if (sn != null && sn != msi && sn.status().isActive && sn.name().equals(msi.name())) {
+ if (sn != null && sn != msi && sn.status().isActive() && sn.name().equals(msi.name())) {
if (qpt.equals(sn.qualifiedParameterTypes())) {
overwrittenStatus = sn.status();
SnippetEvent se = new SnippetEvent(
--- a/langtools/test/jdk/jshell/ClassMembersTest.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/test/jdk/jshell/ClassMembersTest.java Thu Jun 09 19:06:36 2016 +0000
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8139829
* @summary Test access to members of user defined class.
* @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng/timeout=600 ClassMembersTest
@@ -61,8 +62,8 @@
String source = input;
while (!source.trim().isEmpty()) {
SourceCodeAnalysis.CompletionInfo info = codeAnalysis.analyzeCompletion(source);
- list.add(info.source);
- source = info.remaining;
+ list.add(info.source());
+ source = info.remaining();
}
return list;
}
--- a/langtools/test/jdk/jshell/CompletenessStressTest.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/test/jdk/jshell/CompletenessStressTest.java Thu Jun 09 19:06:36 2016 +0000
@@ -248,15 +248,15 @@
}
String unit = text.substring(start, end);
SourceCodeAnalysis.CompletionInfo ci = getAnalysis().analyzeCompletion(unit);
- if (ci.completeness != expected) {
- if (expected == COMPLETE_WITH_SEMI && (ci.completeness == CONSIDERED_INCOMPLETE || ci.completeness == EMPTY)) {
+ if (ci.completeness() != expected) {
+ if (expected == COMPLETE_WITH_SEMI && (ci.completeness() == CONSIDERED_INCOMPLETE || ci.completeness() == EMPTY)) {
writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
start, end, unit));
} else {
- String oops = unit.substring(max(0, ci.unitEndPos - 10), ci.unitEndPos) + "|||" +
- unit.substring(ci.unitEndPos, min(unit.length(), ci.unitEndPos + 10));
+ String oops = unit.substring(max(0, ci.unitEndPos() - 10), ci.unitEndPos()) + "|||" +
+ unit.substring(ci.unitEndPos(), min(unit.length(), ci.unitEndPos() + 10));
writer.write(String.format("Expected %s got %s: '%s' row %d, column %d: -- %s\n",
- expected, ci.completeness, oops, row, column, unit));
+ expected, ci.completeness(), oops, row, column, unit));
return false;
}
}
--- a/langtools/test/jdk/jshell/KullaTesting.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/test/jdk/jshell/KullaTesting.java Thu Jun 09 19:06:36 2016 +0000
@@ -139,7 +139,7 @@
public List<Snippet> getActiveKeys() {
return allSnippets.stream()
- .filter(k -> getState().status(k).isActive)
+ .filter(k -> getState().status(k).isActive())
.collect(Collectors.toList());
}
@@ -615,7 +615,7 @@
return (ImportSnippet) key;
}
- private Snippet key(List<SnippetEvent> events) {
+ public Snippet key(List<SnippetEvent> events) {
assertTrue(events.size() >= 1, "Expected at least one event, got none.");
return events.get(0).snippet();
}
@@ -757,12 +757,12 @@
public void assertAnalyze(String input, Completeness status, String source, String remaining, Boolean isComplete) {
CompletionInfo ci = getAnalysis().analyzeCompletion(input);
- if (status != null) assertEquals(ci.completeness, status, "Input : " + input + ", status: ");
- if (source != null) assertEquals(ci.source, source, "Input : " + input + ", source: ");
- if (remaining != null) assertEquals(ci.remaining, remaining, "Input : " + input + ", remaining: ");
+ if (status != null) assertEquals(ci.completeness(), status, "Input : " + input + ", status: ");
+ if (source != null) assertEquals(ci.source(), source, "Input : " + input + ", source: ");
+ if (remaining != null) assertEquals(ci.remaining(), remaining, "Input : " + input + ", remaining: ");
if (isComplete != null) {
boolean isExpectedComplete = isComplete;
- assertEquals(ci.completeness.isComplete, isExpectedComplete, "Input : " + input + ", isComplete: ");
+ assertEquals(ci.completeness().isComplete(), isExpectedComplete, "Input : " + input + ", isComplete: ");
}
}
@@ -794,7 +794,7 @@
List<Snippet> snippets = getState().snippets();
assertEquals(allSnippets.size(), snippets.size());
for (Snippet sn : snippets) {
- if (sn.kind().isPersistent && getState().status(sn).isActive) {
+ if (sn.kind().isPersistent() && getState().status(sn).isActive()) {
MemberInfo actual = getMemberInfo(sn);
MemberInfo exp = expected[index];
assertEquals(actual, exp, String.format("Difference in #%d. Expected: %s, actual: %s",
@@ -812,7 +812,7 @@
public void assertActiveKeys(Snippet... expected) {
int index = 0;
for (Snippet key : getState().snippets()) {
- if (state.status(key).isActive) {
+ if (state.status(key).isActive()) {
assertEquals(expected[index], key, String.format("Difference in #%d. Expected: %s, actual: %s", index, key, expected[index]));
++index;
}
@@ -888,8 +888,8 @@
List<Suggestion> completions =
getAnalysis().completionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
return completions.stream()
- .filter(s -> isSmart == null || isSmart == s.isSmart)
- .map(s -> s.continuation)
+ .filter(s -> isSmart == null || isSmart == s.matchesType())
+ .map(s -> s.continuation())
.distinct()
.collect(Collectors.toList());
}
@@ -1071,7 +1071,7 @@
}
public static STEInfo added(Status status) {
- return new STEInfo(MAIN_SNIPPET, NONEXISTENT, status, status.isDefined, null);
+ return new STEInfo(MAIN_SNIPPET, NONEXISTENT, status, status.isDefined(), null);
}
public static class EventChain {
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Thu Jun 09 19:06:36 2016 +0000
@@ -470,8 +470,8 @@
List<Suggestion> completions =
js.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
return completions.stream()
- .filter(s -> isSmart == s.isSmart)
- .map(s -> s.continuation)
+ .filter(s -> isSmart == s.matchesType())
+ .map(s -> s.continuation())
.distinct()
.collect(Collectors.toList());
}
--- a/langtools/test/jdk/jshell/SnippetTest.java Thu Jun 09 17:28:38 2016 +0000
+++ b/langtools/test/jdk/jshell/SnippetTest.java Thu Jun 09 19:06:36 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8139829
* @summary test accessors of Snippet
* @build KullaTesting TestingInputStream
* @run testng SnippetTest
@@ -32,9 +33,14 @@
import jdk.jshell.DeclarationSnippet;
import org.testng.annotations.Test;
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.Snippet.Status;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import static jdk.jshell.Snippet.Status.VALID;
import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
import static jdk.jshell.Snippet.SubKind.*;
@Test
@@ -147,4 +153,27 @@
method("()double", "f"));
assertActiveKeys();
}
+
+ public void testBooleanSnippetQueries() {
+ Snippet nd = varKey(assertEval("blort x;", added(RECOVERABLE_NOT_DEFINED)));
+ assertTrue(nd.kind().isPersistent(), "nd.isPersistent");
+ Status ndstat = getState().status(nd);
+ assertTrue(ndstat.isActive(), "nd.isActive");
+ assertFalse(ndstat.isDefined(), "nd.isDefined");
+ MethodSnippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
+ assertTrue(g.kind().isPersistent(), "g.isPersistent");
+ Status gstat = getState().status(g);
+ assertTrue(gstat.isActive(), "g.isActive");
+ assertTrue(gstat.isDefined(), "g.isDefined");
+ getState().drop(g);
+ assertTrue(g.kind().isPersistent(), "drop isPersistent");
+ gstat = getState().status(g);
+ assertFalse(gstat.isActive(), "drop isActive");
+ assertFalse(gstat.isDefined(), "drop isDefined");
+ Snippet stmt = key(assertEval("if (true) {}", added(VALID)));
+ assertFalse(stmt.kind().isPersistent(), "stmt isPersistent");
+ Status stmtstat = getState().status(stmt);
+ assertTrue(stmtstat.isActive(), "stmt isActive");
+ assertTrue(stmtstat.isDefined(), "stmt isDefined");
+ }
}