Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2015-10-01 02:37:24 +02:00
23 changed files with 587 additions and 248 deletions
@@ -18,10 +18,10 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.SmartHashSet;
import com.sun.jdi.request.EventRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
public class SuspendManagerUtil {
@@ -38,7 +38,7 @@ public class SuspendManagerUtil {
public static SuspendContextImpl findContextByThread(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) {
for (SuspendContextImpl context : ((SuspendManagerImpl)suspendManager).getPausedContexts()) {
if (context.getThread() == thread) {
if (context.getThread() == thread || context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
return context;
}
}
@@ -45,7 +45,7 @@ public abstract class DebuggerContextCommandImpl extends SuspendContextCommandIm
@Override
public SuspendContextImpl getSuspendContext() {
if (myCustomThread != null) {
return SuspendManagerUtil.getSuspendingContext(myDebuggerContext.getDebugProcess().getSuspendManager(), myCustomThread);
return SuspendManagerUtil.findContextByThread(myDebuggerContext.getDebugProcess().getSuspendManager(), getThread());
}
return super.getSuspendContext();
}
@@ -259,12 +259,15 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
final JavaParameters params = new JavaParameters();
params.setUseClasspathJar(true);
final JavaRunConfigurationModule module = myConfiguration.getConfigurationModule();
final int classPathType = JavaParametersUtil.getClasspathType(module,
myConfiguration.MAIN_CLASS_NAME,
false);
final String jreHome = myConfiguration.ALTERNATIVE_JRE_PATH_ENABLED ? myConfiguration.ALTERNATIVE_JRE_PATH : null;
JavaParametersUtil.configureModule(module, params, classPathType, jreHome);
if (module.getModule() != null) {
final int classPathType = JavaParametersUtil.getClasspathType(module, myConfiguration.MAIN_CLASS_NAME, false);
JavaParametersUtil.configureModule(module, params, classPathType, jreHome);
}
else {
JavaParametersUtil.configureProject(module.getProject(), params, JavaParameters.JDK_AND_CLASSES_AND_TESTS, jreHome);
}
params.setMainClass(myConfiguration.MAIN_CLASS_NAME);
setupJavaParameters(params);
@@ -20,34 +20,37 @@ import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.configurations.ConfigurationUtil;
import com.intellij.execution.impl.JavaScratchRunConfigurationExtension;
import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiMethodUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
public class ApplicationConfigurationProducer extends JavaRunConfigurationProducerBase<ApplicationConfiguration> {
public class ApplicationConfigurationProducer<T extends ApplicationConfiguration> extends JavaRunConfigurationProducerBase<T> {
public ApplicationConfigurationProducer() {
super(ApplicationConfigurationType.getInstance());
public ApplicationConfigurationProducer(final ApplicationConfigurationType configurationType) {
super(configurationType);
}
@Override
protected boolean setupConfigurationFromContext(ApplicationConfiguration configuration,
ConfigurationContext context,
Ref<PsiElement> sourceElement) {
Location location = JavaExecutionUtil.stepIntoSingleClass(context.getLocation());
if (location == null) return false;
protected boolean setupConfigurationFromContext(T configuration, ConfigurationContext context, Ref<PsiElement> 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;
@@ -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<Integer> 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 <T extends RunConfigurationBase> 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 <P extends RunConfigurationBase> SettingsEditor<P> createEditor(@NotNull P configuration) {
return null;
}
@Nullable
protected String getEditorTitle() {
return null;
}
protected boolean isApplicableFor(@NotNull RunConfigurationBase configuration) {
return configuration instanceof ApplicationConfiguration;
}
}
@@ -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<String> options = new ArrayList<String>();
options.add("-g"); // always compile with debug info
@@ -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);
}
}
@@ -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<JavaScratchConfiguration>(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<? extends RunConfiguration> 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);
}
}
@@ -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<JavaScratchConfiguration> {
public JavaScratchConfigurationProducer() {
super(JavaScratchConfigurationType.getInstance());
}
@Override
protected boolean setupConfigurationFromContext(JavaScratchConfiguration configuration, ConfigurationContext context, Ref<PsiElement> 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;
}
}
@@ -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);
}
}
@@ -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;
@@ -94,7 +94,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
List<PsiClass> targetClasses = getTargetClasses(element);
if (targetClasses.isEmpty()) return;
if (targetClasses.size() == 1) {
if (targetClasses.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
doInvoke(project, targetClasses.get(0));
} else {
chooseTargetClass(targetClasses, editor);
@@ -379,10 +379,6 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
return Collections.emptyList();
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
return Collections.singletonList(psiClass);
}
if (!allowOuterClasses || !isAllowOuterTargetClass()) {
final ArrayList<PsiClass> classes = new ArrayList<PsiClass>();
collectSupers(psiClass, classes);
@@ -120,7 +120,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
PsiMethodCallExpression call = getMethodCall();
if (call == null) return Collections.emptyList();
for (PsiClass target : targets) {
if (target.isInterface() && shouldCreateStaticMember(call.getMethodExpression(), target) && !PsiUtil.isLanguageLevel8OrHigher(target)) continue;
if (shouldCreateStaticMember(call.getMethodExpression(), target)){
if (target.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(target)) continue;
if (target.getContainingClass() != null && !target.hasModifierProperty(PsiModifier.STATIC)) continue;
}
if (!isMethodSignatureExists(call, target)) {
result.add(target);
}
@@ -20,13 +20,11 @@ import com.intellij.ide.DataManager
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.actionSystem.EditorActionManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier
import com.intellij.psi.util.PsiTreeUtil
/**
* @author ven
*/
@@ -132,6 +130,47 @@ class Usage {
state.gotoEnd()
}
public void "test prefer outer class when static is not applicable for inner"() {
configureFromFileText "a.java", """
class A {
int x;
A(int x) { this.x = x; }
class B extends A{
B(int x) { super(f<caret>oo(x)); }
}
}
"""
TemplateManagerImpl.setTemplateTesting(project, testRootDisposable);
doAction("Create method 'foo'")
def state = TemplateManagerImpl.getTemplateState(getEditor())
def document = getEditor().getDocument()
def offset = getEditor().getCaretModel().getOffset()
ApplicationManager.application.runWriteAction {
def method = PsiTreeUtil.getParentOfType(getFile().findElementAt(offset), PsiMethod.class)
method.getModifierList().setModifierProperty(PsiModifier.STATIC, false)
PsiDocumentManager.getInstance(getFile().project).commitDocument(document)
}
state.gotoEnd()
checkResultByText """
class A {
int x;
A(int x) { this.x = x; }
class B extends A{
B(int x) { super(foo(x)); }
}
private int foo(int x) {
return 0;
}
}
"""
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage";
@@ -127,18 +127,18 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
return getSymbolReplacementTarget(el) != null;
}
@SuppressWarnings({"ConstantConditions"})
private void handleModifierList(final PsiElement el, final PsiElement replacement) throws IncorrectOperationException {
// We want to copy all comments, including doc comments and modifier lists
@SuppressWarnings("ConstantConditions")
private void copyUnmatchedElements(final PsiElement original, final PsiElement replacement) {
// We want to copy all comments, including doc comments, modifier lists and method bodies
// that are present in matched nodes but not present in search/replace
Map<String, String> newNameToSearchPatternNameMap = myContext.getNewName2PatternNameMap();
Map<String, PsiNamedElement> originalNamedElements = Collector.collectNamedElements(el);
Map<String, PsiNamedElement> originalNamedElements = Collector.collectNamedElements(original);
Map<String, PsiNamedElement> replacedNamedElements = Collector.collectNamedElements(replacement);
if (originalNamedElements.size() == 0 && replacedNamedElements.size() == 0) {
Replacer.handleComments(el, replacement, myContext);
Replacer.handleComments(original, replacement, myContext);
return;
}
@@ -149,7 +149,7 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
PsiNamedElement replacementNamedElement = replacedNamedElements.get(name);
String key = newNameToSearchPatternNameMap.get(name);
if (key == null) key = name;
PsiNamedElement searchNamedElement = searchedNamedElements.get(key);
PsiNamedElement searchedNamedElement = searchedNamedElements.get(key);
if (replacementNamedElement == null && originalNamedElements.size() == 1 && replacedNamedElements.size() == 1) {
replacementNamedElement = replacedNamedElements.entrySet().iterator().next().getValue();
@@ -170,7 +170,7 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
}
}
if (replacementNamedElement != null && searchNamedElement != null) {
if (replacementNamedElement != null && searchedNamedElement != null) {
Replacer.handleComments(originalNamedElement, replacementNamedElement, myContext);
}
@@ -191,8 +191,8 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
) {
PsiModifierList modifierList = ((PsiModifierListOwner)originalNamedElements.get(name)).getModifierList();
if (searchNamedElement instanceof PsiModifierListOwner) {
PsiModifierList modifierListOfSearchedElement = ((PsiModifierListOwner)searchNamedElement).getModifierList();
if (searchedNamedElement instanceof PsiModifierListOwner) {
PsiModifierList modifierListOfSearchedElement = ((PsiModifierListOwner)searchedNamedElement).getModifierList();
final PsiModifierListOwner modifierListOwner = ((PsiModifierListOwner)replacementNamedElement);
PsiModifierList modifierListOfReplacement = modifierListOwner.getModifierList();
@@ -215,6 +215,18 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
}
}
}
if (originalNamedElement instanceof PsiMethod &&
searchedNamedElement instanceof PsiMethod &&
replacementNamedElement instanceof PsiMethod) {
final PsiMethod searchedMethod = (PsiMethod)searchedNamedElement;
final PsiMethod replacementMethod = (PsiMethod)replacementNamedElement;
if (searchedMethod.getBody() == null && replacementMethod.getBody() == null) {
final PsiMethod originalMethod = (PsiMethod)originalNamedElement;
final PsiCodeBlock originalBody = originalMethod.getBody();
replacementMethod.add(originalBody);
}
}
}
}
@@ -267,12 +279,12 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
if (listContext) {
if (statements.length > 1) {
final PsiElement replacement = elementParent.addRangeBefore(statements[0], statements[statements.length - 1], elementToReplace);
handleModifierList(elementToReplace, replacement);
copyUnmatchedElements(elementToReplace, replacement);
}
else if (statements.length == 1) {
PsiElement replacement = getMatchExpr(statements[0], elementToReplace);
handleModifierList(elementToReplace, replacement);
copyUnmatchedElements(elementToReplace, replacement);
replacement = handleSymbolReplacement(replacement, elementToReplace);
if (replacement instanceof PsiTryStatement) {
@@ -337,7 +349,7 @@ public class JavaReplaceHandler extends StructuralReplaceHandler {
}
else {
// preserve comments
handleModifierList(elementToReplace, replacement);
copyUnmatchedElements(elementToReplace, replacement);
if (replacement instanceof PsiClass) {
final PsiStatement[] searchStatements = getCodeBlock().getStatements();
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
@@ -118,6 +119,11 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
this(chars, false);
}
/**
* NOTE: if client sets forUseInNonAWTThread to true it's supposed that client will completely control document and its listeners.
* The noticable peculiarity of DocumentImpl behavior in this mode is that DocumentImpl will survive after ProcessCancelledException
* thrown from listeners during changedUpdate event, the exception will be rethrown and rest of the listeners WON'T be notified.
*/
public DocumentImpl(@NotNull CharSequence chars, boolean forUseInNonAWTThread) {
this(chars, false, forUseInNonAWTThread);
}
@@ -756,6 +762,14 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
try {
listener.documentChanged(event);
}
catch (ProcessCanceledException e) {
if (!myAssertThreading) {
throw e;
}
else {
LOG.error("ProceeCanceledException shouldn't be thrown from document listeners on real document");
}
}
catch (Throwable e) {
LOG.error(e);
}
@@ -360,7 +360,7 @@ public class FindDialog extends DialogWrapper {
navigateToSelectedUsage(myResultsPreviewTable);
}
}
}.registerCustomShortcutSet(CommonShortcuts.getEditSource(), comboBox);
}.registerCustomShortcutSet(CommonShortcuts.getEditSource(), comboBox, myDisposable);
}
}
@@ -216,6 +216,9 @@ public abstract class BaseRefactoringProcessor implements Runnable {
}
}
if (isPreview) {
for (UsageInfo usage : usages) {
LOG.assertTrue(usage != null, getClass());
}
previewRefactoring(usages);
}
else {
@@ -237,6 +237,10 @@ public final class SwingCleanuper implements ApplicationComponent{
private static boolean isCAccessible(Object resource) {
final String name = resource.getClass().getName();
return isCAccessible(name);
}
static boolean isCAccessible(String name) {
return name.equals("apple.awt.CAccessible") || name.equals("sun.lwawt.macosx.CAccessible");
}
@@ -188,7 +188,7 @@ public class ToolkitBugsProcessor {
@Override
public boolean process(Throwable e, StackTraceElement[] stack) {
if (e instanceof NullPointerException && stack.length > 1) {
return stack[0].getClassName().equals("apple.awt.CAccessible") && stack[0].getMethodName().equals("getAccessibleContext");
return SwingCleanuper.isCAccessible(stack[0].getClassName()) && stack[0].getMethodName().equals("getAccessibleContext");
}
return false;
}
@@ -2389,4 +2389,19 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
options.clearVariableDefinitions();
}
public void testMethodContentReplacement() {
final String in = "class A extends TestCase {\n" +
" void testOne() {\n" +
" System.out.println();\n" +
" }\n" +
"}\n";
final String what = "class '_A { void '_b:[regex( test.* )](); }";
final String by = "class $A$ {\n @java.lang.Override void $b$();\n}";
assertEquals("class A extends TestCase {\n" +
" @Override void testOne(){\n" +
" System.out.println();\n" +
" }\n" +
"}\n", replacer.testReplace(in, what, by, options));
}
}
@@ -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();
+3 -2
View File
@@ -68,7 +68,7 @@
</component>
<component>
<implementation-class>com.intellij.execution.impl.JavaScratchCompilationSupport</implementation-class>
<implementation-class>com.intellij.execution.scratch.JavaScratchCompilationSupport</implementation-class>
</component>
</project-components>
@@ -1326,8 +1326,10 @@
<configurationProducer implementation="com.intellij.execution.applet.AppletConfigurationProducer"/>
<configurationType implementation="com.intellij.execution.application.ApplicationConfigurationType"/>
<configurationType implementation="com.intellij.execution.jar.JarApplicationConfigurationType"/>
<configurationType implementation="com.intellij.execution.scratch.JavaScratchConfigurationType"/>
<runConfigurationProducer implementation="com.intellij.execution.jar.JarApplicationConfigurationProducer"/>
<runConfigurationProducer implementation="com.intellij.execution.application.ApplicationConfigurationProducer"/>
<runConfigurationProducer implementation="com.intellij.execution.scratch.JavaScratchConfigurationProducer"/>
<configurationType implementation="com.intellij.execution.remote.RemoteConfigurationType"/>
<runLineMarkerContributor language="JAVA" implementationClass="com.intellij.execution.application.ApplicationRunLineMarkerProvider"/>
@@ -1619,7 +1621,6 @@
<applicationService serviceImplementation="com.intellij.execution.JavaRunConfigurationExtensionManager"/>
<runConfigurationExtension implementation="com.intellij.execution.testDiscovery.TestDiscoveryExtension"/>
<runConfigurationExtension implementation="com.intellij.execution.impl.JavaScratchRunConfigurationExtension"/>
<regExpLanguageHost forClass="com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl"
implementationClass="com.intellij.psi.impl.JavaRegExpHost"/>