From 7d97620a9db00b359bc57626a7e50ee739fe10e5 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 30 Sep 2015 19:40:33 +0200 Subject: [PATCH] java scratches run support rewritten to dedicated configuration type --- .../application/ApplicationConfiguration.java | 13 +- .../ApplicationConfigurationProducer.java | 46 ++--- .../JavaScratchRunConfigurationExtension.java | 174 ------------------ .../JavaScratchCompilationSupport.java | 46 +++-- .../scratch/JavaScratchConfigurable.java | 107 +++++++++++ .../scratch/JavaScratchConfiguration.java | 132 +++++++++++++ .../JavaScratchConfigurationProducer.java | 82 +++++++++ .../scratch/JavaScratchConfigurationType.java | 89 +++++++++ .../JavaScratchPositionManager.java | 2 +- .../GroovyScriptRunConfigurationProducer.java | 3 +- resources/src/META-INF/IdeaPlugin.xml | 5 +- 11 files changed, 476 insertions(+), 223 deletions(-) delete mode 100644 java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java rename java/execution/impl/src/com/intellij/execution/{impl => scratch}/JavaScratchCompilationSupport.java (83%) create mode 100644 java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurable.java create mode 100644 java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfiguration.java create mode 100644 java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationProducer.java create mode 100644 java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationType.java rename java/execution/impl/src/com/intellij/execution/{impl => scratch}/JavaScratchPositionManager.java (98%) diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java index a6eb2a1669e5..594c0b0fecbd 100644 --- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java +++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java @@ -259,12 +259,15 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration { +public class ApplicationConfigurationProducer extends JavaRunConfigurationProducerBase { - public ApplicationConfigurationProducer() { - super(ApplicationConfigurationType.getInstance()); + public ApplicationConfigurationProducer(final ApplicationConfigurationType configurationType) { + super(configurationType); } @Override - protected boolean setupConfigurationFromContext(ApplicationConfiguration configuration, - ConfigurationContext context, - Ref sourceElement) { - Location location = JavaExecutionUtil.stepIntoSingleClass(context.getLocation()); - if (location == null) return false; + protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref sourceElement) { + final Location contextLocation = context.getLocation(); + if (contextLocation == null) { + return false; + } + final Location location = JavaExecutionUtil.stepIntoSingleClass(contextLocation); + if (location == null) { + return false; + } final PsiElement element = location.getPsiElement(); - if (!element.isPhysical()) return false; + if (!element.isPhysical()) { + return false; + } PsiElement currentElement = element; PsiMethod method; while ((method = findMain(currentElement)) != null) { @@ -60,15 +63,15 @@ public class ApplicationConfigurationProducer extends JavaRunConfigurationProduc currentElement = method.getParent(); } final PsiClass aClass = ApplicationConfigurationType.getMainClass(element); - if (aClass == null) return false; + if (aClass == null) { + return false; + } sourceElement.set(aClass); setupConfiguration(configuration, aClass, context); return true; } - private void setupConfiguration(ApplicationConfiguration configuration, - final PsiClass aClass, - final ConfigurationContext context) { + private void setupConfiguration(T configuration, final PsiClass aClass, final ConfigurationContext context) { configuration.MAIN_CLASS_NAME = JavaExecutionUtil.getRuntimeQualifiedName(aClass); configuration.setGeneratedName(); setupConfigurationModule(context, configuration); @@ -85,7 +88,7 @@ public class ApplicationConfigurationProducer extends JavaRunConfigurationProduc } @Override - public boolean isConfigurationFromContext(ApplicationConfiguration appConfiguration, ConfigurationContext context) { + public boolean isConfigurationFromContext(T appConfiguration, ConfigurationContext context) { final PsiElement location = context.getPsiLocation(); final PsiClass aClass = ApplicationConfigurationType.getMainClass(location); if (aClass != null && Comparing.equal(JavaExecutionUtil.getRuntimeQualifiedName(aClass), appConfiguration.MAIN_CLASS_NAME)) { @@ -94,15 +97,6 @@ public class ApplicationConfigurationProducer extends JavaRunConfigurationProduc return false; } - // for scratches it is enough to check that the configuration is associated with the same scratch file - final VirtualFile scratchFile = JavaScratchRunConfigurationExtension.getScratchVirtualFile(appConfiguration); - if (scratchFile != null) { - final PsiFile containingFile = aClass.getContainingFile(); - if (containingFile != null && scratchFile.equals(containingFile.getVirtualFile())) { - return true; - } - } - final Module configurationModule = appConfiguration.getConfigurationModule().getModule(); if (Comparing.equal(context.getModule(), configurationModule)) return true; diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java deleted file mode 100644 index cfc93d3f0316..000000000000 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.execution.impl; - -import com.intellij.debugger.DebuggerManager; -import com.intellij.debugger.engine.DebugProcess; -import com.intellij.debugger.engine.DebugProcessAdapter; -import com.intellij.debugger.engine.DebugProcessImpl; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.Location; -import com.intellij.execution.RunConfigurationExtension; -import com.intellij.execution.application.ApplicationConfiguration; -import com.intellij.execution.configurations.*; -import com.intellij.execution.process.ProcessHandler; -import com.intellij.ide.scratch.ScratchFileType; -import com.intellij.lang.java.JavaLanguage; -import com.intellij.openapi.compiler.CompilerManager; -import com.intellij.openapi.options.SettingsEditor; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWithId; -import com.intellij.openapi.vfs.newvfs.ManagingFS; -import com.intellij.psi.PsiFile; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; - -public class JavaScratchRunConfigurationExtension extends RunConfigurationExtension{ - - private static final Key SCRATCH_FILE_ID = Key.create("_scratch_file_id_"); - - public void cleanUserData(RunConfigurationBase configuration) { - super.cleanUserData(configuration); - configuration.putCopyableUserData(SCRATCH_FILE_ID, null); - } - - protected void extendCreatedConfiguration(@NotNull RunConfigurationBase configuration, @NotNull Location location) { - final VirtualFile vFile = location.getVirtualFile(); - if (vFile instanceof VirtualFileWithId && vFile.getFileType() == ScratchFileType.INSTANCE) { - final PsiFile psiFile = location.getPsiElement().getContainingFile(); - if (psiFile != null && psiFile.getLanguage() == JavaLanguage.INSTANCE) { - configuration.putCopyableUserData(SCRATCH_FILE_ID, ((VirtualFileWithId)vFile).getId()); - } - } - } - - protected void validateConfiguration(@NotNull RunConfigurationBase configuration, boolean isExecution) throws Exception { - super.validateConfiguration(configuration, isExecution); - } - - public void updateJavaParameters(T configuration, JavaParameters params, RunnerSettings runnerSettings) throws ExecutionException { - if (getScratchFileId(configuration) >= 0) { - final File scrachesOutput = getScratchOutputDirectory(configuration.getProject()); - if (scrachesOutput != null) { - params.getClassPath().add(scrachesOutput); - } - } - } - - @Override - protected void attachToProcess(@NotNull final RunConfigurationBase configuration, @NotNull final ProcessHandler handler, @Nullable RunnerSettings runnerSettings) { - if (runnerSettings instanceof DebuggingRunnerData && getScratchFileId(configuration) >= 0) { - final VirtualFile vFile = getScratchVirtualFile(configuration); - if (vFile != null) { - DebuggerManager.getInstance(configuration.getProject()).addDebugProcessListener(handler, new DebugProcessAdapter() { - @Override - public void processAttached(DebugProcess process) { - if (vFile.isValid()) { - process.appendPositionManager(new JavaScratchPositionManager((DebugProcessImpl)process, vFile)); - } - process.removeDebugProcessListener(this); - } - }); - } - } - } - - @NotNull - protected String getSerializationId() { - return "java-scratch-properties"; - } - - @Nullable - public static String getScratchFileUrl(RunConfiguration configuration) { - final VirtualFile vFile = getScratchVirtualFile(configuration); - return vFile != null? vFile.getUrl() : null; - } - - @Nullable - public static VirtualFile getScratchVirtualFile(RunConfiguration configuration) { - int id = getScratchFileId(configuration); - if (id < 0) { - return null; - } - return ManagingFS.getInstance().findFileById(id); - } - - private static int getScratchFileId(RunConfiguration configuration) { - final Integer id = - configuration instanceof RunConfigurationBase ? ((RunConfigurationBase)configuration).getCopyableUserData(SCRATCH_FILE_ID) : null; - return id == null? -1 : id.intValue(); - } - - @Nullable - public static File getScratchOutputDirectory(Project project) { - final File root = CompilerManager.getInstance(project).getJavacCompilerWorkingDir(); - return root != null? new File(root, "scratches/out") : null; - } - - @Nullable - public static File getScratchTempDirectory(Project project) { - final File root = CompilerManager.getInstance(project).getJavacCompilerWorkingDir(); - return root != null? new File(root, "scratches/src") : null; - } - - - protected void readExternal(@NotNull RunConfigurationBase runConfiguration, @NotNull Element element) throws InvalidDataException { - final Element sourceElement = element.getChild("source"); - if (sourceElement != null) { - final String idStr = sourceElement.getAttributeValue("fileId"); - if (idStr != null) { - try { - runConfiguration.putCopyableUserData(SCRATCH_FILE_ID, Integer.parseInt(idStr)); - } - catch (NumberFormatException ignored) { - } - } - } - } - - protected void writeExternal(@NotNull RunConfigurationBase runConfiguration, @NotNull Element element) throws WriteExternalException { - final int id = getScratchFileId(runConfiguration); - if (id < 0) { - super.writeExternal(runConfiguration, element); - } - else { - final Element sourceElement = new Element("source"); - sourceElement.setAttribute("fileId", String.valueOf(id)); - element.addContent(sourceElement); - } - } - - @Nullable - protected

SettingsEditor

createEditor(@NotNull P configuration) { - return null; - } - - @Nullable - protected String getEditorTitle() { - return null; - } - - protected boolean isApplicableFor(@NotNull RunConfigurationBase configuration) { - return configuration instanceof ApplicationConfiguration; - } -} diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchCompilationSupport.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchCompilationSupport.java similarity index 83% rename from java/execution/impl/src/com/intellij/execution/impl/JavaScratchCompilationSupport.java rename to java/execution/impl/src/com/intellij/execution/scratch/JavaScratchCompilationSupport.java index 1f8d401b6693..26be9ec53d5f 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchCompilationSupport.java +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchCompilationSupport.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.execution.impl; +package com.intellij.execution.scratch; import com.intellij.compiler.options.CompileStepBeforeRun; -import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; @@ -53,20 +52,34 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT compileManager.addAfterTask(this); } + @Nullable + public static File getScratchOutputDirectory(Project project) { + final File root = CompilerManager.getInstance(project).getJavacCompilerWorkingDir(); + return root != null? new File(root, "scratches/out") : null; + } + + @Nullable + public static File getScratchTempDirectory(Project project) { + final File root = CompilerManager.getInstance(project).getJavacCompilerWorkingDir(); + return root != null? new File(root, "scratches/src") : null; + } + @Override public boolean execute(CompileContext context) { final Project project = context.getProject(); final RunConfiguration configuration = CompileStepBeforeRun.getRunConfiguration(context); - if (!(configuration instanceof ModuleBasedConfiguration)) { + if (!(configuration instanceof JavaScratchConfiguration)) { return true; } - final String scratchUrl = JavaScratchRunConfigurationExtension.getScratchFileUrl(configuration); + final JavaScratchConfiguration scratchConfig = (JavaScratchConfiguration)configuration; + final String scratchUrl = scratchConfig.getScratchFileUrl(); if (scratchUrl == null) { - return true; + context.addMessage(CompilerMessageCategory.ERROR, "Associated scratch file not found", null, -1, -1); + return false; } @Nullable - final Module module = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule(); + final Module module = scratchConfig.getConfigurationModule().getModule(); final Sdk targetSdk = module != null? ModuleRootManager.getInstance(module).getSdk() : ProjectRootManager.getInstance(project).getProjectSdk(); if (targetSdk == null) { final String message = module != null? @@ -83,7 +96,7 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT return true; } - final File outputDir = JavaScratchRunConfigurationExtension.getScratchOutputDirectory(project); + final File outputDir = getScratchOutputDirectory(project); if (outputDir == null) { // should not happen for normal projects return true; } @@ -94,7 +107,7 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT File srcFile = scratchFile; if (!StringUtil.endsWith(srcFile.getName(), ".java")) { - final File srcDir = JavaScratchRunConfigurationExtension.getScratchTempDirectory(project); + final File srcDir = getScratchTempDirectory(project); if (srcDir == null) { // should not happen for normal projects return true; } @@ -150,12 +163,17 @@ public class JavaScratchCompilationSupport implements ProjectComponent, CompileT } }; - for (String s : orderEnumerator.compute().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList().getPathList()) { - cp.add(new File(s)); - } - for (String s : orderEnumerator.compute().compileOnly().sdkOnly().getPathsList().getPathList()) { - platformCp.add(new File(s)); - } + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (String s : orderEnumerator.compute().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList().getPathList()) { + cp.add(new File(s)); + } + for (String s : orderEnumerator.compute().compileOnly().sdkOnly().getPathsList().getPathList()) { + platformCp.add(new File(s)); + } + } + }); final List options = new ArrayList(); options.add("-g"); // always compile with debug info diff --git a/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurable.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurable.java new file mode 100644 index 000000000000..ea2eaca3da5c --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurable.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.scratch; + +import com.intellij.execution.application.ApplicationConfigurable; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.ide.scratch.ScratchFileService; +import com.intellij.ide.scratch.ScratchRootType; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileWithId; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.ui.components.BorderLayoutPanel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Eugene Zhuravlev + * Date: 30-Sep-15 + */ +public class JavaScratchConfigurable extends ApplicationConfigurable{ + + private final TextFieldWithBrowseButton myScratchPathField; + + public JavaScratchConfigurable(final Project project) { + super(project); + myScratchPathField = new TextFieldWithBrowseButton(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + VirtualFile toSelect = getVFileFromEditor(); + if (toSelect == null) { + final String scratchesRoot = ScratchFileService.getInstance().getRootPath(ScratchRootType.getInstance()); + toSelect = LocalFileSystem.getInstance().findFileByPath(scratchesRoot); + } + final VirtualFile file = + FileChooser.chooseFile(FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(), myScratchPathField, project, toSelect); + if (file != null) { + setVFileToEditor(file); + } + } + }, this); + } + + @Override + public void applyEditorTo(ApplicationConfiguration configuration) throws ConfigurationException { + super.applyEditorTo(configuration); + final VirtualFile vFile = getVFileFromEditor(); + ((JavaScratchConfiguration)configuration).SCRATCH_FILE_ID = vFile instanceof VirtualFileWithId ? ((VirtualFileWithId)vFile).getId() : 0; + } + + @Nullable + private VirtualFile getVFileFromEditor() { + final String path = FileUtil.toSystemIndependentName(myScratchPathField.getText()); + return !StringUtil.isEmpty(path) ? LocalFileSystem.getInstance().findFileByPath(path) : null; + } + + @Override + public void resetEditorFrom(ApplicationConfiguration configuration) { + super.resetEditorFrom(configuration); + final JavaScratchConfiguration scratchConfig = (JavaScratchConfiguration)configuration; + final VirtualFile file = scratchConfig.getScratchVirtualFile(); + setVFileToEditor(file); + } + + private void setVFileToEditor(VirtualFile file) { + if (file != null) { + myScratchPathField.setText(FileUtil.toSystemDependentName(file.getPath())); + } + else { + myScratchPathField.setText(""); + } + } + + @NotNull + @Override + public JComponent createEditor() { + final JPanel panel = new JPanel(new GridBagLayout()); + panel.add(new JBLabel("Path to scratch file: "), new GridBagConstraints(0, 0, 1, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(20,0,0,10), 0, 0)); + panel.add(myScratchPathField, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(20, 0, 0, 0), 0, 0)); + return new BorderLayoutPanel().addToCenter(super.createEditor()).addToBottom(panel); + } +} diff --git a/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfiguration.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfiguration.java new file mode 100644 index 000000000000..b3f2f7e827c3 --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfiguration.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.scratch; + +import com.intellij.debugger.DebuggerManager; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebugProcessAdapter; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.execution.ExecutionBundle; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.JavaRunConfigurationExtensionManager; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.configurations.*; +import com.intellij.execution.filters.TextConsoleBuilderFactory; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.util.JavaParametersUtil; +import com.intellij.execution.util.ProgramParametersUtil; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.ManagingFS; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +/** + * @author Eugene Zhuravlev + * Date: 29-Sep-15 + */ +public class JavaScratchConfiguration extends ApplicationConfiguration { + public int SCRATCH_FILE_ID; + + protected JavaScratchConfiguration(String name, Project project, ConfigurationFactory factory) { + super(name, project, factory); + } + + @Override + public void checkConfiguration() throws RuntimeConfigurationException { + JavaParametersUtil.checkAlternativeJRE(this); + final String className = MAIN_CLASS_NAME; + if (className == null || className.length() == 0) { + throw new RuntimeConfigurationError(ExecutionBundle.message("no.main.class.specified.error.text")); + } + if (SCRATCH_FILE_ID <= 0) { + throw new RuntimeConfigurationError("No scratch file associated with configuration"); + } + if (getScratchVirtualFile() == null) { + throw new RuntimeConfigurationError("Associated scratch file not found"); + } + ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), getConfigurationModule().getModule()); + JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this); + } + + @Override + public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + final JavaCommandLineState state = new JavaApplicationCommandLineState(this, env) { + @Override + protected void setupJavaParameters(JavaParameters params) throws ExecutionException { + super.setupJavaParameters(params); + final File scrachesOutput = JavaScratchCompilationSupport.getScratchOutputDirectory(getProject()); + if (scrachesOutput != null) { + params.getClassPath().add(scrachesOutput); + } + } + + @NotNull + @Override + protected OSProcessHandler startProcess() throws ExecutionException { + final OSProcessHandler handler = super.startProcess(); + if (getRunnerSettings() instanceof DebuggingRunnerData) { + final VirtualFile vFile = getConfiguration().getScratchVirtualFile(); + if (vFile != null) { + DebuggerManager.getInstance(getProject()).addDebugProcessListener(handler, new DebugProcessAdapter() { + @Override + public void processAttached(DebugProcess process) { + if (vFile.isValid()) { + process.appendPositionManager(new JavaScratchPositionManager((DebugProcessImpl)process, vFile)); + } + process.removeDebugProcessListener(this); + } + }); + } + } + return handler; + } + }; + state.setConsoleBuilder(TextConsoleBuilderFactory.getInstance().createBuilder(getProject(), getConfigurationModule().getSearchScope())); + return state; + } + + @NotNull + @Override + public SettingsEditor getConfigurationEditor() { + return new JavaScratchConfigurable(getProject()); + } + + @Override + public boolean isCompileBeforeLaunchAddedByDefault() { + return true; + } + + @Nullable + public String getScratchFileUrl() { + final VirtualFile vFile = getScratchVirtualFile(); + return vFile != null? vFile.getUrl() : null; + } + + @Nullable + public VirtualFile getScratchVirtualFile() { + final int id = SCRATCH_FILE_ID; + if (id <= 0) { + return null; + } + return ManagingFS.getInstance().findFileById(id); + } +} diff --git a/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationProducer.java new file mode 100644 index 000000000000..6e716b31e13b --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationProducer.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.scratch; + +import com.intellij.execution.JavaExecutionUtil; +import com.intellij.execution.Location; +import com.intellij.execution.actions.ConfigurationContext; +import com.intellij.execution.actions.ConfigurationFromContext; +import com.intellij.execution.application.ApplicationConfigurationProducer; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.ide.scratch.ScratchFileType; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileWithId; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +/** + * @author Eugene Zhuravlev + * Date: 29-Sep-15 + */ +public class JavaScratchConfigurationProducer extends ApplicationConfigurationProducer { + + public JavaScratchConfigurationProducer() { + super(JavaScratchConfigurationType.getInstance()); + } + + @Override + protected boolean setupConfigurationFromContext(JavaScratchConfiguration configuration, ConfigurationContext context, Ref sourceElement) { + final Location location = context.getLocation(); + if (location != null) { + final VirtualFile vFile = location.getVirtualFile(); + if (vFile instanceof VirtualFileWithId && vFile.getFileType() == ScratchFileType.INSTANCE) { + final PsiFile psiFile = location.getPsiElement().getContainingFile(); + if (psiFile != null && psiFile.getLanguage() == JavaLanguage.INSTANCE) { + configuration.SCRATCH_FILE_ID = ((VirtualFileWithId)vFile).getId(); + return super.setupConfigurationFromContext(configuration, context, sourceElement); + } + } + } + return false; + } + + @Override + public boolean shouldReplace(ConfigurationFromContext self, ConfigurationFromContext other) { + return other.isProducedBy(ApplicationConfigurationProducer.class) && !other.isProducedBy(JavaScratchConfigurationProducer.class); + } + + @Override + public boolean isConfigurationFromContext(JavaScratchConfiguration configuration, ConfigurationContext context) { + final PsiElement location = context.getPsiLocation(); + final PsiClass aClass = ApplicationConfigurationType.getMainClass(location); + if (aClass != null && Comparing.equal(JavaExecutionUtil.getRuntimeQualifiedName(aClass), configuration.MAIN_CLASS_NAME)) { + // for scratches it is enough to check that the configuration is associated with the same scratch file + final VirtualFile scratchFile = configuration.getScratchVirtualFile(); + if (scratchFile != null) { + final PsiFile containingFile = aClass.getContainingFile(); + if (containingFile != null && scratchFile.equals(containingFile.getVirtualFile())) { + return true; + } + } + } + return false; + } + +} diff --git a/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationType.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationType.java new file mode 100644 index 000000000000..4f6f67b0cd56 --- /dev/null +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchConfigurationType.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.scratch; + +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.execution.configuration.ConfigurationFactoryEx; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationTypeUtil; +import com.intellij.execution.configurations.ModuleBasedConfiguration; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.project.Project; +import com.intellij.ui.LayeredIcon; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author Eugene Zhuravlev + * Date: 29-Sep-15 + */ +public class JavaScratchConfigurationType extends ApplicationConfigurationType{ + private final ConfigurationFactory myFactory; + + public JavaScratchConfigurationType() { + myFactory = new ConfigurationFactoryEx(this) { + @Override + public boolean isApplicable(@NotNull Project project) { + return false; + } + + @NotNull + @Override + public RunConfiguration createTemplateConfiguration(@NotNull Project project) { + return new JavaScratchConfiguration("", project, this); + } + + @Override + public void onNewConfigurationCreated(@NotNull RunConfiguration configuration) { + ((ModuleBasedConfiguration)configuration).onNewConfigurationCreated(); + } + }; + } + + @NotNull + @Override + public String getId() { + return "Java Scratch"; + } + + @Override + public String getDisplayName() { + return "Java Scratch"; + } + + @Override + public String getConfigurationTypeDescription() { + return "Configuration for java scratch files"; + } + + @Override + public Icon getIcon() { + return LayeredIcon.create(super.getIcon(), AllIcons.Actions.Scratch); // todo + } + + @Override + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[] {myFactory}; + } + + /** @noinspection MethodOverridesStaticMethodOfSuperclass*/ + @NotNull + public static JavaScratchConfigurationType getInstance() { + return ConfigurationTypeUtil.findConfigurationType(JavaScratchConfigurationType.class); + } +} diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchPositionManager.java similarity index 98% rename from java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java rename to java/execution/impl/src/com/intellij/execution/scratch/JavaScratchPositionManager.java index 86318a45ddf9..46756fc35048 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchPositionManager.java +++ b/java/execution/impl/src/com/intellij/execution/scratch/JavaScratchPositionManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.execution.impl; +package com.intellij.execution.scratch; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.PositionManagerImpl; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationProducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationProducer.java index f2f68b717e88..6fda6aea8d6f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationProducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfigurationProducer.java @@ -22,6 +22,7 @@ import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.actions.ConfigurationFromContext; import com.intellij.execution.application.ApplicationConfigurationProducer; +import com.intellij.execution.application.ApplicationConfigurationType; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunConfigurationModule; import com.intellij.execution.junit.RuntimeConfigurationProducer; @@ -75,7 +76,7 @@ public class GroovyScriptRunConfigurationProducer extends RuntimeConfigurationPr } if (file.getText().contains("@Grab")) { - ApplicationConfigurationProducer producer = new ApplicationConfigurationProducer(); + ApplicationConfigurationProducer producer = new ApplicationConfigurationProducer(ApplicationConfigurationType.getInstance()); ConfigurationFromContext settings = producer.createConfigurationFromContext(context); if (settings != null) { PsiElement src = settings.getSourceElement(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 7083ed3dea88..61721eea2f8d 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -68,7 +68,7 @@ - com.intellij.execution.impl.JavaScratchCompilationSupport + com.intellij.execution.scratch.JavaScratchCompilationSupport @@ -1326,8 +1326,10 @@ + + @@ -1619,7 +1621,6 @@ -