From c457b017cd47c72ff458a7ec7b0f1127ae4f3728 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 10 Jul 2017 14:44:46 +0200 Subject: [PATCH] configurable context for jshell: module and alternative JRE; support jshell's addToClasspath() feature in communication protocol. --- .../execution/jshell/ExecuteJShellAction.java | 8 +- .../execution/jshell/JShellHandler.java | 86 +++++++--- .../jshell/LaunchJShellConsoleAction.java | 18 ++- .../jshell/SnippetEditorDecorator.java | 150 ++++++++++++++++-- .../ui/ConfigurationModuleSelector.java | 18 ++- .../execution/jshell/frontend/Main.java | 29 +++- .../execution/jshell/protocol/Request.java | 21 +++ .../execution/jshell/protocol/Response.java | 1 - .../JShellMessageMarshallingTest.java | 7 + lib/jshell-frontend.jar | Bin 6848 -> 7116 bytes 10 files changed, 288 insertions(+), 50 deletions(-) diff --git a/java/execution/impl/src/com/intellij/execution/jshell/ExecuteJShellAction.java b/java/execution/impl/src/com/intellij/execution/jshell/ExecuteJShellAction.java index fbb8c625e295..9df5c10f1c37 100644 --- a/java/execution/impl/src/com/intellij/execution/jshell/ExecuteJShellAction.java +++ b/java/execution/impl/src/com/intellij/execution/jshell/ExecuteJShellAction.java @@ -19,12 +19,13 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -65,7 +66,10 @@ class ExecuteJShellAction extends AnAction{ try { JShellHandler handler = JShellHandler.getAssociatedHandler(vFile); if (handler == null) { - handler = JShellHandler.create(project, vFile, e.getData(LangDataKeys.MODULE)); + final SnippetEditorDecorator.ConfigurationPane config = SnippetEditorDecorator.getJShellConfiguration(e.getDataContext()); + final Module module = config != null ? config.getContextModule() : null; + final Sdk sdk = config != null ? config.getRuntimeSdk() : null; + handler = JShellHandler.create(project, vFile, module, sdk); } if (handler != null) { handler.toFront(); diff --git a/java/execution/impl/src/com/intellij/execution/jshell/JShellHandler.java b/java/execution/impl/src/com/intellij/execution/jshell/JShellHandler.java index d597a3034f3e..0a252a1d6a34 100644 --- a/java/execution/impl/src/com/intellij/execution/jshell/JShellHandler.java +++ b/java/execution/impl/src/com/intellij/execution/jshell/JShellHandler.java @@ -57,12 +57,11 @@ import java.awt.*; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.LinkedHashSet; +import java.util.*; import java.util.List; -import java.util.Set; -import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicReference; /** * @author Eugene Zhuravlev @@ -84,6 +83,7 @@ public class JShellHandler { private final MessageReader myMessageReader; private final MessageWriter myMessageWriter; private final ExecutorService myTaskQueue = new SequentialTaskExecutor("JShell Command Queue", PooledThreadExecutor.INSTANCE); + private final AtomicReference> myEvalClasspathRef = new AtomicReference<>(null); private JShellHandler(@NotNull Project project, RunContentDescriptor descriptor, @@ -145,14 +145,29 @@ public class JShellHandler { return contentFile != null? contentFile.getUserData(MARKER_KEY) : null; } - public static JShellHandler create(@NotNull final Project project, @NotNull final VirtualFile contentFile, @Nullable Module module) throws Exception{ - final OSProcessHandler processHandler = launchProcess(project, module); + public static JShellHandler create(@NotNull final Project project, + @NotNull final VirtualFile contentFile, + @Nullable Module module, + @Nullable Sdk alternateSdk) throws Exception{ + final OSProcessHandler processHandler = launchProcess(project, module, alternateSdk); + final String title = "JShell " + contentFile.getNameWithoutExtension(); final ConsoleViewImpl consoleView = new MyConsoleView(project); final RunContentDescriptor descriptor = new RunContentDescriptor(consoleView, processHandler, new JPanel(new BorderLayout()), title); final JShellHandler jshellHandler = new JShellHandler(project, descriptor, consoleView, contentFile, processHandler); + // init classpath for evaluation + final Set cp = new LinkedHashSet<>(); + final Computable orderEnumerator = module != null ? () -> ModuleRootManager.getInstance(module).orderEntries() + : () -> ProjectRootManager.getInstance(project).orderEntries(); + ApplicationManager.getApplication().runReadAction(() -> { + cp.addAll(orderEnumerator.compute().librariesOnly().recursively().withoutSdk().getPathsList().getPathList()); + }); + if (!cp.isEmpty()) { + jshellHandler.myEvalClasspathRef.set(cp); + } + // must call getComponent before createConsoleActions() final JComponent consoleViewComponent = consoleView.getComponent(); @@ -186,8 +201,12 @@ public class JShellHandler { // todo: do we need to include project's compiled classes into the classpath or libraries only? // todo: if we include project classes, make sure they are compiled - private static OSProcessHandler launchProcess(@NotNull Project project, @Nullable Module module) throws Exception{ - final Sdk sdk = module != null? ModuleRootManager.getInstance(module).getSdk() : ProjectRootManager.getInstance(project).getProjectSdk(); + private static OSProcessHandler launchProcess(@NotNull Project project, + @Nullable Module module, + @Nullable Sdk alternateSdk) throws Exception{ + final Sdk sdk = alternateSdk != null? alternateSdk : + module != null? ModuleRootManager.getInstance(module).getSdk() : + ProjectRootManager.getInstance(project).getProjectSdk(); if (sdk == null || !(sdk.getSdkType() instanceof JavaSdkType)) { throw new ExecException( (sdk != null ? "Expected Java SDK" : " SDK is not configured") + @@ -232,17 +251,41 @@ public class JShellHandler { cmdLine.addParameter(launchCp.toString()); } cmdLine.addParameter("com.intellij.execution.jshell.frontend.Main"); - final Set cp = new LinkedHashSet<>(); - final Computable orderEnumerator = module != null ? () -> ModuleRootManager.getInstance(module).orderEntries() - : () -> ProjectRootManager.getInstance(project).orderEntries(); - ApplicationManager.getApplication().runReadAction(() -> { - for (String s : orderEnumerator.compute().librariesOnly().recursively().withoutSdk().getPathsList().getPathList()) { - cp.add(new File(s)); - } - }); - cmdLine.addParameter("--class-path"); - cmdLine.addParameter(StringUtil.join(cp, File.pathSeparator)); - return new OSProcessHandler(cmdLine); + + // init classpath for evaluation + //final Set cp = new LinkedHashSet<>(); + //final Computable orderEnumerator = module != null ? () -> ModuleRootManager.getInstance(module).orderEntries() + // : () -> ProjectRootManager.getInstance(project).orderEntries(); + //ApplicationManager.getApplication().runReadAction(() -> { + // cp.addAll(orderEnumerator.compute().librariesOnly().recursively().withoutSdk().getPathsList().getPathList()); + //}); + + //final File cpFile; + //if (!cp.isEmpty()) { + // cpFile = FileUtilRt.createTempFile("_jshell_classpath_", "", true); + // try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(cpFile), StandardCharsets.UTF_8))) { + // for (String path : cp) { + // writer.write(path); + // writer.newLine(); + // } + // } + // cmdLine.addParameter("--@class-path"); + // cmdLine.addParameter(cpFile.getAbsolutePath()); + //} + //else { + // cpFile = null; + //} + + final OSProcessHandler processHandler = new OSProcessHandler(cmdLine); + //if (cpFile != null) { + // processHandler.addProcessListener(new ProcessAdapter() { + // @Override + // public void processTerminated(ProcessEvent event) { + // FileUtil.delete(cpFile); + // } + // }); + //} + return processHandler; } private static String findFrontEndLibrary() { @@ -280,6 +323,13 @@ public class JShellHandler { private Response sendInput(final Request request) { final boolean alive = !myProcess.isProcessTerminating() && !myProcess.isProcessTerminated(); if (alive) { + // consume evaluation classpath, if any + final Collection cp = myEvalClasspathRef.getAndSet(null); + if (cp != null) { + for (String path : cp) { + request.addClasspathItem(path); + } + } myConsoleView.performWhenNoDeferredOutput(() -> { try { myMessageWriter.send(request); diff --git a/java/execution/impl/src/com/intellij/execution/jshell/LaunchJShellConsoleAction.java b/java/execution/impl/src/com/intellij/execution/jshell/LaunchJShellConsoleAction.java index ca656844f2dd..ce9d5b42397e 100644 --- a/java/execution/impl/src/com/intellij/execution/jshell/LaunchJShellConsoleAction.java +++ b/java/execution/impl/src/com/intellij/execution/jshell/LaunchJShellConsoleAction.java @@ -19,9 +19,11 @@ import com.intellij.execution.console.ConsoleHistoryController; import com.intellij.ide.scratch.ScratchFileService; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.vfs.VirtualFile; /** @@ -46,8 +48,18 @@ public class LaunchJShellConsoleAction extends AnAction{ ); assert contentFile != null; try { - FileEditorManager.getInstance(project).openFile(contentFile, true); - JShellHandler.create(project, contentFile, e.getData(LangDataKeys.MODULE)); + final FileEditor[] editors = FileEditorManager.getInstance(project).openFile(contentFile, true); + Sdk alternateSdk = null; + Module module = null; + for (FileEditor editor : editors) { + final SnippetEditorDecorator.ConfigurationPane config = SnippetEditorDecorator.getJShellConfiguration(editor); + if (config != null) { + alternateSdk = config.getRuntimeSdk(); + module = config.getContextModule(); + break; + } + } + JShellHandler.create(project, contentFile, module, alternateSdk); } catch (Exception ex) { JShellDiagnostic.notifyError(ex, project); diff --git a/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java b/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java index 2646244dd9bd..01ba4a4f42dc 100644 --- a/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java +++ b/java/execution/impl/src/com/intellij/execution/jshell/SnippetEditorDecorator.java @@ -15,48 +15,166 @@ */ package com.intellij.execution.jshell; +import com.intellij.ProjectTopics; +import com.intellij.application.options.ModulesComboBox; +import com.intellij.execution.ui.ConfigurationModuleSelector; +import com.intellij.execution.ui.DefaultJreSelector; +import com.intellij.execution.ui.JrePathEditor; import com.intellij.ide.scratch.RootType; import com.intellij.ide.scratch.ScratchFileService; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionToolbar; -import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.impl.EditorHeaderComponent; import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.ModuleListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.JavaSdk; +import com.intellij.openapi.projectRoots.ProjectJdkTable; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorNotifications; +import com.intellij.util.Alarm; +import com.intellij.util.Function; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; +import java.util.List; /** * @author Eugene Zhuravlev * Date: 06-Jun-17 */ -public class SnippetEditorDecorator extends EditorNotifications.Provider{ - public static final Key CONTEXT_KEY = Key.create("jshell.editor.toolbar"); +public class SnippetEditorDecorator extends EditorNotifications.Provider{ + public static final Key CONTEXT_KEY = Key.create("jshell.editor.toolbar"); + private final Project myProject; + public SnippetEditorDecorator(Project project) { + myProject = project; + } + + public static class ConfigurationPane extends EditorHeaderComponent { + private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private final JrePathEditor myJreEditor; + private final ConfigurationModuleSelector myModuleSelector; + private MessageBusConnection myBusConnection; + + ConfigurationPane(Project project) { + final DefaultActionGroup actions = new DefaultActionGroup(ExecuteJShellAction.getSharedInstance(), DropJShellStateAction.getSharedInstance()); + final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("JShellSnippetEditor", actions, true); + + myJreEditor = new JrePathEditor(DefaultJreSelector.projectSdk(project)); + myJreEditor.setToolTipText("Alternative JRE to run JShell"); + myJreEditor.setPathOrName(null, true); + + LabeledComponent modulePane = new LabeledComponent<>(); + ModulesComboBox modulesCombo = new ModulesComboBox(); + modulePane.setComponent(modulesCombo); + modulePane.setLabelLocation(BorderLayout.WEST); + modulePane.setText("Use classpath of:"); + myModuleSelector = new ConfigurationModuleSelector(project, modulesCombo, ""); + + JPanel mainPane = new JPanel(new GridBagLayout()); + mainPane.add(toolbar.getComponent(), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, JBUI.insets(2, 3, 0, 0), 0, 0)); + mainPane.add(modulePane, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, JBUI.insets(2, 3, 0, 0), 0, 0)); + mainPane.add(myJreEditor, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, JBUI.insets(2, 15, 0, 0), 0, 0)); + add(mainPane, BorderLayout.CENTER); + } + + @Override + public void addNotify() { + super.addNotify(); + myBusConnection = myModuleSelector.getProject().getMessageBus().connect(); + myBusConnection.subscribe(ProjectTopics.MODULES, new ModuleListener() { + @Override + public void moduleAdded(@NotNull Project project, @NotNull Module module) { + reloadModules(); + } + + @Override + public void moduleRemoved(@NotNull Project project, @NotNull Module module) { + reloadModules(); + } + + @Override + public void modulesRenamed(@NotNull Project project, @NotNull List modules, @NotNull Function oldNameProvider) { + reloadModules(); + } + }); + reloadModules(); + } + + @Override + public void removeNotify() { + super.removeNotify(); + final MessageBusConnection conn = myBusConnection; + if (conn != null) { + myBusConnection = null; + conn.disconnect(); + myUpdateAlarm.cancelAllRequests(); + } + } + + private void reloadModules() { + myUpdateAlarm.cancelAllRequests(); + myUpdateAlarm.addRequest(()->myModuleSelector.reset(), 300L); + } + + @Nullable + public Module getContextModule() { + return myModuleSelector.getModule(); + } + + @Nullable + public Sdk getRuntimeSdk() { + final String pathOrName = myJreEditor.getJrePathOrName(); + if (pathOrName != null) { + final JavaSdk javaSdkType = JavaSdk.getInstance(); + final ProjectJdkTable jdkTable = ProjectJdkTable.getInstance(); + final Sdk sdkByName = jdkTable.findJdk(pathOrName, javaSdkType.getName()); + if (sdkByName != null) { + return sdkByName; + } + // assuming we have sdk home path + for (Sdk sdk : jdkTable.getSdksOfType(javaSdkType)) { + if (FileUtil.pathsEqual(pathOrName, sdk.getHomePath())) { + return sdk; + } + } + } + return null; + } + } + @NotNull @Override - public Key getKey() { + public Key getKey() { return CONTEXT_KEY; } @Nullable @Override - public JComponent createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) { + public ConfigurationPane createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) { final RootType root = ScratchFileService.getInstance().getRootType(file); - - if ((root instanceof JShellRootType)) { - final DefaultActionGroup actions = new DefaultActionGroup(ExecuteJShellAction.getSharedInstance(), DropJShellStateAction.getSharedInstance()); - final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("JShellSnippetEditor", actions, true); - - final EditorHeaderComponent header = new EditorHeaderComponent(); - header.add(toolbar.getComponent()); - return header; + if (!(root instanceof JShellRootType)) { + return null; } + return new ConfigurationPane(myProject); + } - return null; + @Nullable + public static ConfigurationPane getJShellConfiguration(DataContext context) { + return getJShellConfiguration(PlatformDataKeys.FILE_EDITOR.getData(context)); + } + + @Nullable + public static ConfigurationPane getJShellConfiguration(FileEditor fileEditor) { + return CONTEXT_KEY.get(fileEditor); } } diff --git a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java index 243d67511f28..996982bb63f8 100644 --- a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java +++ b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java @@ -104,12 +104,7 @@ public class ConfigurationModuleSelector { } public void reset(final ModuleBasedConfiguration configuration) { - final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); - final List list = new ArrayList<>(); - for (final Module module : modules) { - if (isModuleAccepted(module)) list.add(module); - } - setModules(list); + reset(); if (myModulesList != null) { myModulesList.setSelectedItem(configuration.getConfigurationModule().getModule()); } @@ -118,6 +113,17 @@ public class ConfigurationModuleSelector { } } + public void reset() { + final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); + final List list = new ArrayList<>(); + for (final Module module : modules) { + if (isModuleAccepted(module)) { + list.add(module); + } + } + setModules(list); + } + public boolean isModuleAccepted(final Module module) { return ModuleTypeManager.getInstance().isClasspathProvider(ModuleType.get(module)); } diff --git a/java/execution/jshell-frontend/src/com/intellij/execution/jshell/frontend/Main.java b/java/execution/jshell-frontend/src/com/intellij/execution/jshell/frontend/Main.java index a1110a16c1a9..c1a31167c509 100644 --- a/java/execution/jshell-frontend/src/com/intellij/execution/jshell/frontend/Main.java +++ b/java/execution/jshell-frontend/src/com/intellij/execution/jshell/frontend/Main.java @@ -3,9 +3,8 @@ package com.intellij.execution.jshell.frontend; import com.intellij.execution.jshell.protocol.*; import jdk.jshell.*; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -20,6 +19,7 @@ import java.util.function.Consumer; */ public class Main { private static final String ARG_CLASSPATH = "--class-path"; + private static final String ARG_CLASSPATH_FILE = "--@class-path"; private static final Consumer NULL_CONSUMER = s -> {}; //private static Request createTestRequest() { @@ -47,6 +47,14 @@ public class Main { response.setUid(request.getUid()); try { + // first, handle eval classpath if any + final List cp = request.getClassPath(); + if (cp != null && !cp.isEmpty()) { + for (String path : cp) { + shell.addToClasspath(path); + } + } + if (command == Request.Command.DROP_STATE) { shell.snippets().forEach(snippet -> exportEvents(shell, shell.drop(snippet), response)); } @@ -124,13 +132,17 @@ public class Main { } } - private static void configureJShell(String[] args, JShell shell) { + private static void configureJShell(String[] args, JShell shell) throws IOException { // todo: add more parameters if needed boolean cpFound = false; + boolean cpFileFound = false; for (String arg : args) { if (ARG_CLASSPATH.equals(arg)) { cpFound = true; } + else if (ARG_CLASSPATH_FILE.equals(arg)) { + cpFileFound = true; + } else { if (cpFound) { cpFound = false; @@ -138,6 +150,15 @@ public class Main { shell.addToClasspath(path); } } + else if (cpFileFound) { + cpFileFound = false; + final File cpFile = new File(arg); + try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(cpFile), StandardCharsets.UTF_8))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + shell.addToClasspath(line); + } + } + } } } } diff --git a/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Request.java b/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Request.java index 37503e1b4648..195fb54cf9b5 100644 --- a/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Request.java +++ b/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Request.java @@ -3,6 +3,8 @@ package com.intellij.execution.jshell.protocol; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlEnum; import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.List; /** * @author Eugene Zhuravlev @@ -12,6 +14,7 @@ import javax.xml.bind.annotation.XmlRootElement; public class Request extends Message{ private Command myCommand; private String myCodeText; + private List myClassPath; @XmlEnum public enum Command{ @@ -44,4 +47,22 @@ public class Request extends Message{ public void setCodeText(String codeText) { myCodeText = codeText; } + + public List getClassPath() { + return myClassPath; + } + + @XmlElement(name = "cp") + public void setClassPath(List classPath) { + myClassPath = classPath; + } + + public void addClasspathItem(String path) { + List cp = myClassPath; + if (cp == null) { + cp = new ArrayList<>(); + myClassPath = cp; + } + cp.add(path); + } } diff --git a/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Response.java b/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Response.java index 5097ae2659ac..2c872f570d36 100644 --- a/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Response.java +++ b/java/execution/jshell-protocol/src/com/intellij/execution/jshell/protocol/Response.java @@ -23,7 +23,6 @@ public class Response extends Message{ Collections.addAll(myEvents = new ArrayList<>(), events); } - @XmlElement public List getEvents() { return myEvents; } diff --git a/java/execution/jshell-protocol/testStrc/com/intellij/execution/jshell/protocol/JShellMessageMarshallingTest.java b/java/execution/jshell-protocol/testStrc/com/intellij/execution/jshell/protocol/JShellMessageMarshallingTest.java index 069a59cca081..8b4d4a1ef79e 100644 --- a/java/execution/jshell-protocol/testStrc/com/intellij/execution/jshell/protocol/JShellMessageMarshallingTest.java +++ b/java/execution/jshell-protocol/testStrc/com/intellij/execution/jshell/protocol/JShellMessageMarshallingTest.java @@ -4,6 +4,7 @@ import junit.framework.TestCase; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.util.List; import java.util.UUID; /** @@ -28,10 +29,16 @@ public class JShellMessageMarshallingTest extends TestCase { final Request request = new Request(UUID.randomUUID().toString(), Request.Command.EVAL, "System.out.println(\"Hello, World!\");\n int var = 7 + 7;"); + request.addClasspathItem("C:/work/path1"); + request.addClasspathItem("C:/work/path2"); + final List requestClasspath = request.getClassPath(); + clientWriter.send(request); final Request receivedRequest = serverReader.receive(s -> {}); assertEquals(request.getUid(), receivedRequest.getUid()); assertEquals(request.getCodeText(), receivedRequest.getCodeText()); + final List receivedClasspath = receivedRequest.getClassPath(); + assertEquals(requestClasspath, receivedClasspath); final CodeSnippet snippet = new CodeSnippet("code-snippet-id", CodeSnippet.Kind.EXPRESSION, CodeSnippet.SubKind.OTHER_EXPRESSION_SUBKIND, "a+b", "expression:a+b"); final Event event1 = new Event(null, null, CodeSnippet.Status.UNKNOWN, CodeSnippet.Status.NONEXISTENT, null); diff --git a/lib/jshell-frontend.jar b/lib/jshell-frontend.jar index afa91957e0dd60ec52d601d25971b1bc678fb64d..a7eab2889253278e7a0c091d1a02502b2389feed 100644 GIT binary patch delta 6383 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 literal 6848 zcmb7JcRZW#-c}T~sjbxBd+$+2ji7eT+NCA6sa4c0V((FEmQ<|}t5wtvB8pfk($;E8 ztyHQn=bX>4J?DLU&UvpV&nI_2_kCUW_j&Gb{<$s_0|G)iJQ5NTJk9V8eZ1d5hewD9 z&^Ff;)icr&2WT4U>1dmoive`bM)B~z0mjD+4MfGJDGWq~VB?c5rV4}IzOmD#^XUE2c^(IC}#^DCwTL3Z9OG1b-As8O%W)(e}0F5y{(69-ChCuO542Ve* zfdPF+=ewJp-zMiZk>cTz;Qg)%BFek@A=ax9Yny$Ha`(?`tZfs?;~ zkIj{E^V!2Q7*BzGLH83T5(N=bCK+KGLd2_kB(XPJ3JBAkpZ0I?k{i0OjT63tytlDw z3u|i|^s0wsidn`%`e}u1L?J=bU%-$y@cCC4I04Lb@; z;CE2PP(QAEDI|V`vLGOc=dikI=isWB%emmt!81hN&KVC2>$Zc*4s6HiV!9Q$su@Ky z%f^hO-x}?|6^(;-SQ*XCa%ojRx-BxJV!D&FDb-JQwNYq%b0^98l7|qgflK2fdL&%Y z;FCW29n_!-@xg=33PZwGrnw1=l}k@S`r2aZIZ6#eF~iW%&w1KP?be@Q-<+F7rlD1# z3PNKC{=J-x0_9{mA6U>)P(R4q^c;s`@%jV*3{J*vKQN^wt7%QFtkT}L2bfXTFX`xg z=)QN|+=nV?h@sewacm?Dg(t?jL@M%T;ZuPOOUf#M`Y!2fhsmD4^i+1}4d_y~aAVd4 zvdi?g18|tNJ47Gy`IC?qK9Y!Ha|)uruzBDd8^GK=@l=!+K6%6?B>do3JELY26RpK7 z_T_yq&_HWynA1oQh^KY;aM(yID3m5+H-6`+LU-igGm1rgt=T?$rS_VAeVKgd#)Jbj zZ3fppn7*xwd2a{RT=|%ziU|UBYb~;>`eijo`O`F`m*cy2(;XKdjpTO5BO#Dn(=BWun(6k8 zyBt-56y=Gth{c}StliiR+*(lp5dIuxOe&z^}Pm#;#ytyMn} zx<~Lh4{p7U4p~}*k+DL8cbJx{MUkvzHjf@7Z*hbJROrN+lVIS9XVNa(4IxYE$G+8K z-a00sestdVsu+_G4)}0R^^3_o0uwh8ucfIO=&I`~IO&Y3Wrm38nIyNj9E4#j&_>So zQfnC+3Z4F0FeOnE)4*rSn@Z%N>coLCjfZ_af;p8Edec{1)>K<*79))clVdAtn)3+F zX3#;NMRIoZrlLk>ey0%YfIMWHjV8x??P%kPyM%PE!Bl6}ot=(-HjD*<=Fa;2v8 z^klq7ac^~4L3Gt18SMQ>L=(NP*?vR5VDFlN@5v)9aX$1)RnkVz_1V3FjX20nj*jP& zQ!WPmZwTVU-=y1;LoHB;Uny-=^EmWnQxIp)=z^D35>|3oOyPvm*r~P3=E{} zz&ozY#?Q6yFeXlf0+X%C*J~ zb?+HEa=!}p;E*F!_QOZ85M-Lo9?O@HQLfLADT9yZHei=?I_8H@Q+ZdlNpIVm#g;9rw!u$;zO(-+EvOg=h# zq^vT*L@}P@9#(ZtNcHWc`6@HHDdj!c1=PA zNxs8&Xyci2MR>}4Sl4htxZR%^DH)7HBC11vo)huUdXF6Q=m@l458f}ElhyUz& z_9*kw?ba?ssO=ZYef#jq0YJw>w(&4O0BUtq08daeQ>&saDJ(ydLeF5B#X{NY^9>xj zw7Rvd*~loc4T8rX+|1PYkBcymkJ!zfPtkbxfq^oGiTuvd?EJ0+H67@0ahS_;jw0EW zg2d=_&IEuW*N^IJ+N-FuAho*GLHxOUrjlp_eH^Ev`*44?3YVjtZft_7kfqgQkLE}Ut~%R09(i9pnyeW3dtMd7{v22(io0OOd?`$ z5}?BQS^}N-Xzi0Z{p5Ow;A{9~qpuw(Q!zgu!-^F}AKxhNuGPnu2)@o!&&TNU9`N%X zcwot%#_KI1tw${^F3Z9#JSpYSjTnH|nfvJKKBd_i=T8~5W5}IXAsBoKG%tGF4GTiy z%+gogIKh{i+a%FXx`k>L=|vBG0!f(bN|QYHu3GdzR>BY}E(S#7x^8|s?y!@wvdTpr z$UOP(1HjjMv*7o0_>g9EZoogp;W?+9pg+JWZEV7*Zc~a5FltRzS?(q0=yJJVi&w+< z9qHYTOEwKm;?0O131fCujhAEhJ24^nZyutHUgFQu_2HbZ)>9>bUuty7y`Qbmv;X;! z_kIJgv!O23CF_HbjC~C>nS9RN27I4|nQz1yOR9+jgD1eUD$@aTDS|$8n{i(8#P+>3 zk&E4dUGzL%Ia$zIvQgu+QP?)BZaKRkYG}huvv1h1z+!Fhrs}#E2Tf`!$y-m;Z>eF2 zCQ>f%b-W@G5l*fLUGYdaH?(OxV7a&82|SZaIAO*>TI}Aa*jTp=q=?c6(^4HN`zbrSelD zJgb*8B?2&VQ#-}@Y{p5&i!=F7uBzl&#*lJ&TOrvrK%w0e(XNUU$mQ1+XvqYPs&ga7j~k)HAs zRLYO7u`&PK_Wmvgv9Fh3ySYT1c8YqRy?Z1pP?S99O-hMzPyJT8{fX2iL?KRq<zZd%!#Ej<%~Cj#~A`W!_#s*B$m- zzl$HvwcVEop1d$pH8(yG%N9J78Yr!U6z(&lV)n}@9E2@9`zO$lJe8?Ez<5iR=#?4egf&rbMT__;Dp7is+@$ zprN;4jq9qQrIc!tyHu!gjMd|6jrKDp#-<{X0%2wV-_+ue=D zYi-^`>bzYtB@Je`jKZHF7G0cdcIL{Wh8yokEKY&iJ;?}5rABQNzTH)_(|IpjKj^$g zv%uDL4-~8DJN(K&Lnj#onY%(iX#IK@up~)M!FbGrDRT3Maqu8^?Cfg09|n^Y-#|wl0@Nn zHL#(q-?Dokx_JIfm*Yir39_OEJ<#FiVzrI`;UTLqjZl;8ctwAM85fu>dr0@}t8odw zG1aqJw^>4d3A>z_%lw0^v7ZJW<|i=hTtdAy>}LD=7^M>ypg1J|!98u&6SR6c>qqdq zDy}zAdiFt_w-HuzIFfZE0@t}a;@n;4ICJR@@k6pjyQO3*+T>wH9~c8Z##G&|=zB)n zCSEfYSIuw)wT_m$O7R%F_?QEeJRUm?RCyA^S2rTosPsgTp4cRRz>})qK5Km}^x79S z=u}?T&D*JqpVS`LotoSUyyo$}8RYWFf_CP+MBBSPx6>4!>f^pC!A!BjjDgM5QzsuK zlIwF6ypqyMcl2G3)W$iMiiOI22|e%bw$Yx}J|35K~13yaO8PuLVKYq*$b>1+&H9uQzo|ufjd|}9z4wPZSkIg0oj#U9X zRY^L;XgxsbiRF1r2~GOpSkoL`PsRP7pS2NVm$m~>sN24x)AH7XmXcK9^81pVe(Z`{ z{X@QtDjVBkOA}B#JCQM8Dm6{22Yk9^JWq;hu)=C_#{C*q;rL~J9(O=0T3416COHj$ z&>ervej^jgPUWorqtm?f?WOS2Gu&m^ByV=h93wQ3Am>_)(ydypO4CF|0y>|x=zbzQ zA{C-ECIp?)-4~aR@l+?6+TM8*9N(Cq7{e65xk2zzIN#~n>KkWXclVnT0S=nvOYSDR z17EMB6pbm7=oFP1N1gpEmsP*h>c6MK@rKw>jE>qw1~}u@l;0iqEsjD4p0J~^E%DDD z8z|Ph8itQRwEDCVtCIRtX=w;(pXA=dxZQPtg&>u>Nsiy%x6OUu2F|JCpYU+U&MzSM zzq++Lg^j2cFMRI|A`;xS@RvWO%sRZnJtrWy)FHUH3Zc(4Bx zUo?SQVvqo(HqAk zbYDsA)AEVh^Ta&swv$U?K4@inw$>WB>n>pVj9T3f$Ii&*@tC#Kn^ECLnZkHIWl1DM z$&N*!dm1r{m12)p{$Q&ype}jc+q^=^MGw0!QAtI1+T>&wO3R83)}H2Dd>e@Cte6Oj zl0LP{z5aHaYK?-5lC4BCe$|#q30Uk1ZR{Z{=!a80#uiSR#|ydAr-pAo*RuSE zNEvpQAAXZ8whR+avOv%1wq--``xjgyYI9pP<*uc?tG|~2H#CXK{r%WebDRt)Q z%c@e~vudDgz)$M+?`$bQ%UlPpw^Clcd?FaBvneu&4Pj9CXv~$XTG`~Xyc8Mjh^$!7 z<3rX-xHELeTqY7B*miiggYS505O=NgI=qYf<7I>gQ0sEe*DWodIDOYoqYLD!^eruo z`p#C@$%dEvYeZgUP-Zo9r>Omq%kyWuAqTW6fDJb8WCpVUKFpl}Mjf7}N8n>+j9wRO zL?fDY<0GFk7M~cB=K*Ruiu+n(?CkwXfZ?y2Dn0{{nRas88OFYfeT~DEGD9a3Pg+2k zP3v;fGkQ7(XvTfz#n9yaFkJM!BU97SPS;?-ag*?3|10qM0|btB)>5!x$yW|5lixvPDN`* z{T=Q>Cg@ef9!w@ltR;}V>sTIF(jCI&a^_^9f9Hs6oABf9G_2xAZtx;q`=Q|M$DHjm z`6;&ClwSSfJP2ULMvf9@o^<4DoZ_m<|nzm*T)6n z?)q!xv(ueq$BU0Q37eTZvOf!-B$mu~cL4PFo!ZZ?pP4TCHi2O4@6;fm4}#%wyZZ4I z-ttZ1i=#o(w%g8SI9B6LYX_&Xru)(LOM!CXQbhs68QlKXPf9pFM(ys9WNaZiw8h$o zlug%zN4w6*E^O$4NwPIwdOSSJbDQw0I*gJ~)FE2lz}fv6@6JRN7mthlKqMnJ z;F;q%l^+djM0ZEmZXh>2@ouSm+!#H$3T^Gk}`uc`|Q%R&k7sc;iqB_NcLk|5CI zBVzcQy`Iv!RuX((^^^1a&*u4+^Vz>Fe-ndC_;h%`vVq?n`ipGfpYa#%Uy_0g6;ixE zyZOIVvd@Qq_xAtHxN!G>0dhXPVEpFw|CxH>_W#0%^Wi^HfA{|XEOO!g{{q9MKZ^X7 z1^ij-A`SQj)BmXTTQ>0PU@p>u-+T5V9r%U3|6cT0R`C0|U&#O7Iv0)q3#{kw^barb tAJ6|+%>buge}jM55*Ho#3*XK+_^Yu@3@#I0OkFv@((&=|SePz;{SWobD^CCb