src/jdk.jshell/share/classes/jdk/jshell/Unit.java
Print this page
*** 30,44 ****
--- 30,49 ----
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+ import jdk.jshell.ClassTracker.ClassInfo;
import jdk.jshell.Snippet.Kind;
import jdk.jshell.Snippet.Status;
import jdk.jshell.Snippet.SubKind;
import jdk.jshell.TaskFactory.AnalyzeTask;
import jdk.jshell.TaskFactory.CompileTask;
+ import jdk.jshell.spi.ExecutionControl.ClassBytecodes;
+ import jdk.jshell.spi.ExecutionControl.ClassInstallException;
+ import jdk.jshell.spi.ExecutionControl.EngineTerminationException;
+ import jdk.jshell.spi.ExecutionControl.NotImplementedException;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
*** 73,83 ****
private DiagList recompilationDiagnostics = null;
private List<String> unresolved;
private SnippetEvent replaceOldEvent;
private List<SnippetEvent> secondaryEvents;
private boolean isAttemptingCorral;
! private List<String> toRedefine;
private boolean dependenciesNeeded;
Unit(JShell state, Snippet si, Snippet causalSnippet,
DiagList generatedDiagnostics) {
this.state = state;
--- 78,88 ----
private DiagList recompilationDiagnostics = null;
private List<String> unresolved;
private SnippetEvent replaceOldEvent;
private List<SnippetEvent> secondaryEvents;
private boolean isAttemptingCorral;
! private List<ClassInfo> toRedefine;
private boolean dependenciesNeeded;
Unit(JShell state, Snippet si, Snippet causalSnippet,
DiagList generatedDiagnostics) {
this.state = state;
*** 259,307 ****
boolean isDefined() {
return status.isDefined();
}
/**
! * Process the class information from the last compile.
! * Requires loading of returned list.
* @return the list of classes to load
*/
! Stream<String> classesToLoad(List<String> classnames) {
toRedefine = new ArrayList<>();
! List<String> toLoad = new ArrayList<>();
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) {
! switch (state.executionControl().getClassStatus(cn)) {
! case UNKNOWN:
// If not loaded, add to the list of classes to load.
! toLoad.add(cn);
dependenciesNeeded = true;
- break;
- case NOT_CURRENT:
- // If loaded but out of date, add to the list of classes to attempt redefine.
- toRedefine.add(cn);
- break;
- case CURRENT:
- // Loaded and current, so nothing to do
- break;
}
}
}
return toLoad.stream();
}
/**
! * Redefine classes needing redefine.
! * classesToLoad() must be called first.
* @return true if all redefines succeeded (can be vacuously true)
*/
boolean doRedefines() {
! return toRedefine.isEmpty()
! ? true
! : state.executionControl().redefine(toRedefine);
}
void markForReplacement() {
// increment for replace class wrapper
si.setSequenceNumber(++seq);
--- 264,327 ----
boolean isDefined() {
return status.isDefined();
}
/**
! * Process the class information from the last compile. Requires loading of
! * returned list.
! *
* @return the list of classes to load
*/
! Stream<ClassBytecodes> classesToLoad(List<String> classnames) {
toRedefine = new ArrayList<>();
! List<ClassBytecodes> toLoad = new ArrayList<>();
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) {
! ClassInfo ci = state.classTracker.get(cn);
! if (ci.isLoaded()) {
! if (ci.isCurrent()) {
! // nothing to do
! } else {
! toRedefine.add(ci);
! }
! } else {
// If not loaded, add to the list of classes to load.
! toLoad.add(ci.toClassBytecodes());
dependenciesNeeded = true;
}
}
}
return toLoad.stream();
}
/**
! * Redefine classes needing redefine. classesToLoad() must be called first.
! *
* @return true if all redefines succeeded (can be vacuously true)
*/
boolean doRedefines() {
! if (toRedefine.isEmpty()) {
! return true;
! }
! ClassBytecodes[] cbcs = toRedefine.stream()
! .map(ci -> ci.toClassBytecodes())
! .toArray(size -> new ClassBytecodes[size]);
! try {
! state.executionControl().redefine(cbcs);
! state.classTracker.markLoaded(cbcs);
! return true;
! } catch (ClassInstallException ex) {
! state.classTracker.markLoaded(cbcs, ex.installed());
! return false;
! } catch (EngineTerminationException ex) {
! state.closeDown();
! return false;
! } catch (NotImplementedException ex) {
! return false;
! }
}
void markForReplacement() {
// increment for replace class wrapper
si.setSequenceNumber(++seq);