diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 13d9be0b5623..506580c351a4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -928,6 +928,7 @@ public class BuildManager implements ApplicationComponent{ launcherCp.add(ClasspathBootstrap.getResourcePath(launcherClass)); launcherCp.add(compilerPath); ClasspathBootstrap.appendJavaCompilerClasspath(launcherCp); + launcherCp.addAll(BuildProcessClasspathManager.getLauncherClasspath(project)); cmdLine.addParameter("-classpath"); cmdLine.addParameter(classpathToString(launcherCp)); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java index 434633f3da47..1da1b5c26631 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildProcessParametersProvider.java @@ -27,10 +27,23 @@ import java.util.List; public abstract class BuildProcessParametersProvider { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.buildProcess.parametersProvider"); + /** + * Override this method to include additional jars to the build process classpath + * @return list of paths to additional jars to be included to the build process classpath + */ public @NotNull List getClassPath() { return Collections.emptyList(); } - + + /** + * Override this method to include additional jars to the build process launcher classpath. This may be needed if the plugin provides + * custom implementation of Java compiler which must be loaded by the same classloader as tools.jar + * @return list of paths to additional jars to be included to the build process launcher classpath + */ + public @NotNull List getLauncherClassPath() { + return Collections.emptyList(); + } + public @NotNull List getVMArguments() { return Collections.emptyList(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java index 2c06c2fb9eeb..5cef06dbab94 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/impl/BuildProcessClasspathManager.java @@ -141,4 +141,12 @@ public class BuildProcessClasspathManager { } return classpath; } + + public static List getLauncherClasspath(Project project) { + final List classpath = ContainerUtil.newArrayList(); + for (BuildProcessParametersProvider provider : project.getExtensions(BuildProcessParametersProvider.EP_NAME)) { + classpath.addAll(provider.getLauncherClassPath()); + } + return classpath; + } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index cc1b2ae059cd..2e15ac48f7f3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -506,12 +506,16 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { final String text = isNullLiteralExpression(expr) ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable", presentableNullable) : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable", presentableNullable); - holder.registerProblem(expr, text, new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())){ - @Override - public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) { - return 1; - } - }); + final LocalQuickFix[] fixes = + PsiTreeUtil.skipParentsOfType(expr, PsiCodeBlock.class, PsiReturnStatement.class) instanceof PsiLambdaExpression + ? LocalQuickFix.EMPTY_ARRAY + : new LocalQuickFix[]{ new AnnotateMethodFix(defaultNullable, ArrayUtil.toStringArray(manager.getNotNulls())) { + @Override + public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) { + return 1; + } + }}; + holder.registerProblem(expr, text, fixes); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java index b647e7d1b37f..f8c395ce17fd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java @@ -81,6 +81,13 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { } } + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element); + if (interfaceMethod != null) { + final Icon icon = AllIcons.Gutter.ImplementingMethod; + final MarkerType type = MarkerType.OVERRIDING_METHOD; + return new ArrowUpLineMarkerInfo(element, icon, type); + } + if (myDaemonSettings.SHOW_METHOD_SEPARATORS && element.getFirstChild() == null) { PsiElement element1 = element; boolean isMember = false; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java index 12b1788dcea7..72e8eca35fa6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java @@ -53,27 +53,27 @@ public class MarkerType { public static final MarkerType OVERRIDING_METHOD = new MarkerType(new NullableFunction() { @Override public String fun(PsiElement element) { - PsiElement parent = element.getParent(); + PsiElement parent = getParentMethod(element); if (!(parent instanceof PsiMethod)) return null; PsiMethod method = (PsiMethod)parent; - return calculateOverridingMethodTooltip(method); + return calculateOverridingMethodTooltip(method, method != element.getParent()); } }, new LineMarkerNavigator(){ @Override public void browse(MouseEvent e, PsiElement element) { - PsiElement parent = element.getParent(); + PsiElement parent = getParentMethod(element); if (!(parent instanceof PsiMethod)) return; PsiMethod method = (PsiMethod)parent; - navigateToOverridingMethod(e, method); + navigateToOverridingMethod(e, method, method != element.getParent()); } }); @Nullable - public static String calculateOverridingMethodTooltip(PsiMethod method) { - PsiMethod[] superMethods = method.findSuperMethods(false); - if (superMethods.length == 0) return null; + public static String calculateOverridingMethodTooltip(PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf); + if (superMethods == null) return null; PsiMethod superMethod = superMethods[0]; boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); @@ -90,9 +90,9 @@ public class MarkerType { return GutterIconTooltipHelper.composeText(superMethods, "", DaemonBundle.message(key)); } - public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method) { - PsiMethod[] superMethods = method.findSuperMethods(false); - if (superMethods.length == 0) return; + public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf); + if (superMethods == null) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(superMethods); PsiElementListNavigator.openTargets(e, superMethods, DaemonBundle.message("navigation.title.super.method", method.getName()), @@ -100,6 +100,22 @@ public class MarkerType { new MethodCellRenderer(showMethodNames)); } + @Nullable + private static PsiMethod[] composeSuperMethods(PsiMethod method, boolean acceptSelf) { + PsiMethod[] superMethods = method.findSuperMethods(false); + if (acceptSelf) { + superMethods = ArrayUtil.prepend(method, superMethods); + } + if (superMethods.length == 0) return null; + return superMethods; + } + + private static PsiElement getParentMethod(PsiElement element) { + final PsiElement parent = element.getParent(); + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element); + return interfaceMethod != null ? interfaceMethod : parent; + } + public static final String SEARCHING_FOR_OVERRIDING_METHODS = "Searching for overriding methods"; public static final MarkerType OVERRIDEN_METHOD = new MarkerType(new NullableFunction() { @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java index 94ddb7ae863e..55d82a987001 100644 --- a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoSuperHandler.java @@ -30,6 +30,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.FindSuperElementsHelper; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,20 +66,27 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler { @Nullable private PsiElement[] findSuperElements(PsiFile file, int offset) { - PsiNameIdentifierOwner parent = getElement(file, offset); - if (parent == null) return null; + PsiElement element = getElement(file, offset); + if (element == null) return null; + + final PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class, PsiMethodReferenceExpression.class); + if (expression != null) { + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(expression); + if (interfaceMethod != null) { + return ArrayUtil.prepend(interfaceMethod, interfaceMethod.findSuperMethods(false)); + } + } + + final PsiNameIdentifierOwner parent = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethod.class, PsiClass.class); + if (parent == null) { + return null; + } return FindSuperElementsHelper.findSuperElements(parent); } - protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) { - PsiElement element = file.findElementAt(offset); - if (element == null) return null; - - PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class); - if (parent == null) - return null; - return parent; + protected PsiElement getElement(PsiFile file, int offset) { + return file.findElementAt(offset); } @Override diff --git a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java index 04c48bc71e40..966a7a3422ea 100644 --- a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java +++ b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java @@ -16,9 +16,8 @@ package com.intellij.spi; import com.intellij.codeInsight.navigation.JavaGotoSuperHandler; -import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiNameIdentifierOwner; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.spi.psi.SPIClassProviderReferenceElement; @@ -27,11 +26,11 @@ import com.intellij.spi.psi.SPIClassProviderReferenceElement; */ public class SPIGotoSuperHandler extends JavaGotoSuperHandler { @Override - protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) { + protected PsiElement getElement(PsiFile file, int offset) { final SPIClassProviderReferenceElement - providerElement = PsiTreeUtil.getParentOfType(file.findElementAt(offset), SPIClassProviderReferenceElement.class); + providerElement = PsiTreeUtil.getParentOfType(super.getElement(file, offset), SPIClassProviderReferenceElement.class); if (providerElement != null) { - return (PsiClass)providerElement.resolve(); + return providerElement.resolve(); } return null; diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index aefa768bd2b4..54bd0241e64e 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -60,6 +60,16 @@ public class LambdaUtil { return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(functionalInterfaceType)); } + public static PsiMethod getFunctionalInterfaceMethod(@Nullable PsiElement element) { + if (element instanceof PsiLambdaExpression || element instanceof PsiMethodReferenceExpression) { + final PsiType samType = element instanceof PsiLambdaExpression + ? ((PsiLambdaExpression)element).getFunctionalInterfaceType() + : ((PsiMethodReferenceExpression)element).getFunctionalInterfaceType(); + return getFunctionalInterfaceMethod(samType); + } + return null; + } + @Nullable public static PsiMethod getFunctionalInterfaceMethod(PsiClassType.ClassResolveResult result) { final PsiClass psiClass = result.getElement(); diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java new file mode 100644 index 000000000000..2fe10c280c86 --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.after.java @@ -0,0 +1,9 @@ +interface I { + void run(); +} + +class Foo { + { + I i = () -> {}; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/gotosuper/Lambda.java b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java new file mode 100644 index 000000000000..26c024317a1d --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/Lambda.java @@ -0,0 +1,9 @@ +interface I { + void run(); +} + +class Foo { + { + I i = () -> {}; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java new file mode 100644 index 000000000000..26c024317a1d --- /dev/null +++ b/java/java-tests/testData/codeInsight/gotosuper/LambdaMarker.java @@ -0,0 +1,9 @@ +interface I { + void run(); +} + +class Foo { + { + I i = () -> {}; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java new file mode 100644 index 000000000000..313720456ae5 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/JavaGotoSuperTest.java @@ -0,0 +1,52 @@ +package com.intellij.codeInsight.navigation; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; +import com.intellij.lang.CodeInsightActions; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.editor.Document; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase { + @NotNull + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + protected String getBasePath() { + return "/codeInsight/gotosuper/"; + } + + public void testLambda() throws Throwable { + doTest(); + } + + public void testLambdaMarker() throws Exception { + configureByFile(getBasePath() + getTestName(false) + ".java"); + int offset = myEditor.getCaretModel().getOffset(); + + doHighlighting(); + Document document = getEditor().getDocument(); + List markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, getProject()); + for (LineMarkerInfo info : markers) { + if (info.endOffset >= offset && info.startOffset <= offset) { + assertEquals("Overrides method in 'I'", info.getLineMarkerTooltip()); + return; + } + } + fail("Gutter expected"); + } + + private void doTest() throws Throwable { + configureByFile(getBasePath() + getTestName(false) + ".java"); + final CodeInsightActionHandler handler = CodeInsightActions.GOTO_SUPER.forLanguage(JavaLanguage.INSTANCE); + handler.invoke(getProject(), getEditor(), getFile()); + checkResultByFile(getBasePath() + getTestName(false) + ".after.java"); + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java index a223fcb40b41..bea32c02b013 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/EclipseCompilerTool.java @@ -86,4 +86,9 @@ public class EclipseCompilerTool extends JavaCompilingTool { } } } + + @Override + public List getDefaultCompilerOptions() { + return Collections.singletonList("-noExit"); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java index 0db6933e8976..976e750fe15d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/java/JavacCompilerTool.java @@ -74,4 +74,9 @@ public class JavacCompilerTool extends JavaCompilingTool { public List getAdditionalClasspath() { return Collections.emptyList(); } + + @Override + public List getDefaultCompilerOptions() { + return Collections.singletonList("-implicit:class"); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java index 0afb45bda93b..6728cf3c4a20 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaCompilingTool.java @@ -21,6 +21,8 @@ import org.jetbrains.jps.incremental.CompileContext; import javax.tools.*; import java.io.File; +import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -46,4 +48,11 @@ public abstract class JavaCompilingTool { public void processCompilerOptions(@NotNull CompileContext context, @NotNull List options) { } + + public void prepareCompilationTask(@NotNull JavaCompiler.CompilationTask task, @NotNull Collection options) { + } + + public List getDefaultCompilerOptions() { + return Collections.emptyList(); + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index 610a51d2d775..450dea158675 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -47,8 +47,7 @@ public class JavacMain { "-d", "-classpath", "-cp", "-bootclasspath" )); private static final Set FILTERED_SINGLE_OPTIONS = new HashSet(Arrays.asList( - /*javac options*/ "-verbose", "-proc:only", "-implicit:class", "-implicit:none", "-Xprefer:newer", "-Xprefer:source", - /*eclipse options*/"-noExit" + /*javac options*/ "-verbose", "-proc:only", "-implicit:class", "-implicit:none", "-Xprefer:newer", "-Xprefer:source" )); public static boolean compile(Collection options, @@ -81,7 +80,7 @@ public class JavacMain { fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff fileManager.handleOption("-endorseddirs", Collections.singleton("").iterator()); // this will clear cached stuff - final Collection _options = prepareOptions(options, usingJavac); + final Collection _options = prepareOptions(options, compilingTool); try { fileManager.setOutputDirectories(outputDirToRoots); @@ -148,6 +147,7 @@ public class JavacMain { final JavaCompiler.CompilationTask task = compiler.getTask( out, fileManager, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources) ); + compilingTool.prepareCompilationTask(task, _options); //if (!IS_VM_6_VERSION) { //todo! // // Do not add the processor for JDK 1.6 because of the bugs in javac @@ -200,14 +200,9 @@ public class JavacMain { return false; } - private static Collection prepareOptions(final Collection options, boolean usingJavac) { + private static Collection prepareOptions(final Collection options, @NotNull JavaCompilingTool compilingTool) { final List result = new ArrayList(); - if (usingJavac) { - result.add("-implicit:class"); // the option supported by javac only - } - else { // is Eclipse - result.add("-noExit"); - } + result.addAll(compilingTool.getDefaultCompilerOptions()); boolean skip = false; for (String option : options) { if (FILTERED_OPTIONS.contains(option)) { @@ -215,7 +210,7 @@ public class JavacMain { continue; } if (!skip) { - if (!FILTERED_SINGLE_OPTIONS.contains(option)) { + if (!FILTERED_SINGLE_OPTIONS.contains(option) && !compilingTool.getDefaultCompilerOptions().contains(option)) { result.add(option); } } diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java index 7a6a0cf04361..1d1540910539 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -21,13 +21,14 @@ import com.intellij.openapi.project.PossiblyDumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.SmartList; import org.intellij.lang.annotations.JdkConstants; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; +import java.util.List; /** * Represents an entity that has a state, a presentation and can be performed. @@ -143,9 +144,10 @@ public abstract class AnAction implements PossiblyDumbAware { public final void registerCustomShortcutSet(@NotNull ShortcutSet shortcutSet, @Nullable JComponent component){ myShortcutSet = shortcutSet; if (component != null){ - @SuppressWarnings("unchecked") ArrayList actionList = (ArrayList)component.getClientProperty(ourClientProperty); + @SuppressWarnings("unchecked") + List actionList = (List)component.getClientProperty(ourClientProperty); if (actionList == null){ - actionList = new ArrayList(1); + actionList = new SmartList(); component.putClientProperty(ourClientProperty, actionList); } if (!actionList.contains(this)){ @@ -170,7 +172,8 @@ public abstract class AnAction implements PossiblyDumbAware { public final void unregisterCustomShortcutSet(JComponent component){ if (component != null){ - @SuppressWarnings("unchecked") ArrayList actionList = (ArrayList)component.getClientProperty(ourClientProperty); + @SuppressWarnings("unchecked") + List actionList = (List)component.getClientProperty(ourClientProperty); if (actionList != null){ actionList.remove(this); } diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java index 9f8900eacbdd..a63d1c0a3949 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -110,23 +111,28 @@ public class ConsoleExecuteAction extends DumbAwareAction { myExecuteActionHandler.runExecuteAction(myConsole, myConsoleView); } - protected boolean isEnabled() { + public boolean isEnabled() { return myEnabledCondition.value(myConsole); } + public void execute(@NotNull TextRange range, @NotNull String text, @NotNull EditorEx editor) { + myConsole.addTextRangeToHistory(range, editor, myExecuteActionHandler.myPreserveMarkup); + myExecuteActionHandler.addToCommandHistoryAndExecute(myConsole, myConsoleView, text); + } + static abstract class ConsoleExecuteActionHandler { - private final ConsoleHistoryModel myConsoleHistoryModel; + private final ConsoleHistoryModel myCommandHistoryModel; private boolean myAddToHistory = true; final boolean myPreserveMarkup; public ConsoleExecuteActionHandler(boolean preserveMarkup) { - myConsoleHistoryModel = new ConsoleHistoryModel(); + myCommandHistoryModel = new ConsoleHistoryModel(); myPreserveMarkup = preserveMarkup; } public ConsoleHistoryModel getConsoleHistoryModel() { - return myConsoleHistoryModel; + return myCommandHistoryModel; } public boolean isEmptyCommandExecutionAllowed() { @@ -139,10 +145,12 @@ public class ConsoleExecuteAction extends DumbAwareAction { final void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) { String text = console.prepareExecuteAction(myAddToHistory, myPreserveMarkup, true); - ((UndoManagerImpl)UndoManager.getInstance(console.getProject())).invalidateActionsFor(DocumentReferenceManager.getInstance().create(console.getCurrentEditor().getDocument())); + addToCommandHistoryAndExecute(console, consoleView, text); + } - myConsoleHistoryModel.addToHistory(text); + private void addToCommandHistoryAndExecute(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView, @NotNull String text) { + myCommandHistoryModel.addToHistory(text); doExecute(text, console, consoleView); } diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index d1bb588f5980..b564df1105af 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -489,7 +489,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { } @NotNull - protected String addTextRangeToHistory(@NotNull TextRange textRange, @NotNull EditorEx consoleEditor, boolean preserveMarkup) { + protected String addTextRangeToHistory(@NotNull TextRange textRange, @NotNull EditorEx inputEditor, boolean preserveMarkup) { doAddPromptToHistory(); final Document history = myHistoryViewer.getDocument(); @@ -497,16 +497,16 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { final int localStartOffset = textRange.getStartOffset(); String text; EditorHighlighter highlighter; - if (consoleEditor instanceof EditorWindow) { - PsiFile file = ((EditorWindow)consoleEditor).getInjectedFile(); + if (inputEditor instanceof EditorWindow) { + PsiFile file = ((EditorWindow)inputEditor).getInjectedFile(); highlighter = HighlighterFactory.createHighlighter(file.getVirtualFile(), EditorColorsManager.getInstance().getGlobalScheme(), getProject()); String fullText = InjectedLanguageUtil.getUnescapedText(file, null, null); highlighter.setText(fullText); text = textRange.substring(fullText); } else { - text = consoleEditor.getDocument().getText(textRange); - highlighter = consoleEditor.getHighlighter(); + text = inputEditor.getDocument().getText(textRange); + highlighter = inputEditor.getHighlighter(); } //offset can be changed after text trimming after insert due to buffer constraints int offset = appendToHistoryDocument(history, text); @@ -528,9 +528,9 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { iterator.advance(); } if (preserveMarkup) { - duplicateHighlighters(markupModel, DocumentMarkupModel.forDocument(consoleEditor.getDocument(), myProject, true), offset, textRange); + duplicateHighlighters(markupModel, DocumentMarkupModel.forDocument(inputEditor.getDocument(), myProject, true), offset, textRange); // don't copy editor markup model, i.e. brace matcher, spell checker, etc. - // duplicateHighlighters(markupModel, consoleEditor.getMarkupModel(), offset, textRange); + // duplicateHighlighters(markupModel, inputEditor.getMarkupModel(), offset, textRange); } if (!text.endsWith("\n")) { appendToHistoryDocument(history, "\n"); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java index 4ae67c9da5d7..9e53c35f7cac 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/EmptyAction.java @@ -15,11 +15,11 @@ */ package com.intellij.openapi.actionSystem; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; /** * This class purpose is to reserve action-id in a plugin.xml so the action appears in Keymap. @@ -74,13 +74,8 @@ public final class EmptyAction extends AnAction { } public static void registerActionShortcuts(JComponent component, final JComponent fromComponent) { - @SuppressWarnings("unchecked") - final ArrayList actionList = - (ArrayList)fromComponent.getClientProperty(ourClientProperty); - if (actionList != null) { - for (AnAction anAction : actionList) { - anAction.registerCustomShortcutSet(anAction.getShortcutSet(), component); - } + for (AnAction anAction : ActionUtil.getActions(fromComponent)) { + anAction.registerCustomShortcutSet(anAction.getShortcutSet(), component); } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java index 8132f9e65990..e0dc548fd452 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java @@ -27,7 +27,9 @@ import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import javax.swing.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ActionUtil { @@ -166,5 +168,10 @@ public class ActionUtil { } } - + @NotNull + public static List getActions(@NotNull JComponent component) { + Object property = component.getClientProperty(AnAction.ourClientProperty); + //noinspection unchecked + return property == null ? Collections.emptyList() : (List)property; + } } diff --git a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java index cf959586f60b..9933dd59f46a 100644 --- a/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/process/ScriptRunnerUtil.java @@ -227,6 +227,9 @@ public final class ScriptRunnerUtil { long millisTimeout, @Nullable String commandLine) { if (processHandler.isProcessTerminated()) { + if (commandLine == null && processHandler instanceof BaseOSProcessHandler) { + commandLine = ((BaseOSProcessHandler) processHandler).getCommandLine(); + } LOG.warn("Process '" + commandLine + "' is already terminated!"); return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index 77e55ea28d26..817cdaa5e458 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -651,8 +651,8 @@ public final class IdeKeyEventDispatcher implements Disposable { if (!(component instanceof JComponent)) { continue; } - ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); - if (listOfActions == null) { + List listOfActions = ActionUtil.getActions((JComponent)component); + if (listOfActions.isEmpty()) { continue; } for (Object listOfAction : listOfActions) { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java index b8095397e016..94f72f6da840 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -19,6 +19,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.actionSystem.impl.PresentationFactory; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; @@ -78,21 +79,16 @@ public final class IdeMouseEventDispatcher { // here we try to find "local" shortcuts if (component instanceof JComponent) { - @SuppressWarnings("unchecked") - final ArrayList listOfActions = (ArrayList)((JComponent)component).getClientProperty(AnAction.ourClientProperty); - if (listOfActions != null) { - for (AnAction action : listOfActions) { - final Shortcut[] shortcuts = action.getShortcutSet().getShortcuts(); - for (Shortcut shortcut : shortcuts) { - if (mouseShortcut.equals(shortcut) && !myActions.contains(action)) { - myActions.add(action); - } + for (AnAction action : ActionUtil.getActions((JComponent)component)) { + for (Shortcut shortcut : action.getShortcutSet().getShortcuts()) { + if (mouseShortcut.equals(shortcut) && !myActions.contains(action)) { + myActions.add(action); } } - // once we've found a proper local shortcut(s), we exit - if (! myActions.isEmpty()) { - return; - } + } + // once we've found a proper local shortcut(s), we exit + if (!myActions.isEmpty()) { + return; } } diff --git a/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java b/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java new file mode 100644 index 000000000000..5f8d33b8302b --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/MutableRemoteCredentials.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2013 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.remote; + +import org.jetbrains.annotations.Nullable; + +/** + * @author traff + */ +public interface MutableRemoteCredentials extends RemoteCredentials { + void setHost(String host); + + void setPort(int port); + + void setUserName(String userName); + + void setPassword(@Nullable String password); + + void setStorePassword(boolean storePassword); + + void setStorePassphrase(boolean storePassphrase); + + void setAnonymous(boolean anonymous); + + void setPrivateKeyFile(String privateKeyFile); + + void setKnownHostsFile(String knownHostsFile); + + void setPassphrase(@Nullable String passphrase); + + void setUseKeyPair(boolean useKeyPair); +} diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java b/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java new file mode 100644 index 000000000000..da38b1a56fa7 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteCancelledException.java @@ -0,0 +1,10 @@ +package com.intellij.remote; + +/** + * @author traff + */ +public class RemoteCancelledException extends RemoteSdkException { + public RemoteCancelledException(String s) { + super(s); + } +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteConnectionCredentialsWrapper.java b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java similarity index 96% rename from platform/platform-impl/src/com/intellij/remotesdk2/RemoteConnectionCredentialsWrapper.java rename to platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java index b51c9fb10b8f..a90f4a4df214 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteConnectionCredentialsWrapper.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java @@ -13,13 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolderBase; -import com.intellij.remotesdk.RemoteCredentials; -import com.intellij.remotesdk.RemoteCredentialsHolder; -import com.intellij.remotesdk.RemoteSdkCredentialsHolder; import org.jdom.Element; import org.jetbrains.annotations.NotNull; diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java b/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java new file mode 100644 index 000000000000..74f1be780ea8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteCredentials.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 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.remote; + +import com.intellij.util.xmlb.annotations.Transient; + +/** + * @author traff + */ +public interface RemoteCredentials { + String getHost(); + + int getPort(); + + @Transient + String getUserName(); + + String getPassword(); + + @Transient + String getPassphrase(); + + boolean isUseKeyPair(); + + boolean isAnonymous(); + + String getPrivateKeyFile(); + + boolean isStorePassword(); + + boolean isStorePassphrase(); + + String getKnownHostsFile(); +} diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java new file mode 100644 index 000000000000..5f5efb7276ae --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialsHolder.java @@ -0,0 +1,260 @@ +/* + * Copyright 2000-2013 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.remote; + +import com.intellij.openapi.util.PasswordUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.remote.MutableRemoteCredentials; +import com.intellij.remote.RemoteCredentials; +import com.intellij.remote.RemoteSdkCredentials; +import com.intellij.util.xmlb.annotations.Transient; +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; + +/** + * @author michael.golubev + */ +public class RemoteCredentialsHolder implements MutableRemoteCredentials { + + public static final String HOST = "HOST"; + public static final String PORT = "PORT"; + public static final String ANONYMOUS = "ANONYMOUS"; + public static final String USERNAME = "USERNAME"; + public static final String PASSWORD = "PASSWORD"; + public static final String USE_KEY_PAIR = "USE_KEY_PAIR"; + public static final String PRIVATE_KEY_FILE = "PRIVATE_KEY_FILE"; + public static final String KNOWN_HOSTS_FILE = "MY_KNOWN_HOSTS_FILE"; + public static final String PASSPHRASE = "PASSPHRASE"; + + private String myHost; + private int myPort; + private boolean myAnonymous; + private String myUserName; + private String myPassword; + private boolean myUseKeyPair; + private String myPrivateKeyFile; + private String myKnownHostsFile; + private String myPassphrase; + private boolean myStorePassword; + private boolean myStorePassphrase; + + @Override + public String getHost() { + return myHost; + } + + public void setHost(String host) { + myHost = host; + } + + @Override + public int getPort() { + return myPort; + } + + public void setPort(int port) { + myPort = port; + } + + @Override + @Transient + public String getUserName() { + return myUserName; + } + + public void setUserName(String userName) { + myUserName = userName; + } + + @Override + public String getPassword() { + return myPassword; + } + + public void setPassword(String password) { + myPassword = password; + } + + public void setStorePassword(boolean storePassword) { + myStorePassword = storePassword; + } + + public void setStorePassphrase(boolean storePassphrase) { + myStorePassphrase = storePassphrase; + } + + @Override + public boolean isStorePassword() { + return myStorePassword; + } + + @Override + public boolean isStorePassphrase() { + return myStorePassphrase; + } + + @Override + public boolean isAnonymous() { + return myAnonymous; + } + + public void setAnonymous(boolean anonymous) { + myAnonymous = anonymous; + } + + @Override + public String getPrivateKeyFile() { + return myPrivateKeyFile; + } + + public void setPrivateKeyFile(String privateKeyFile) { + myPrivateKeyFile = privateKeyFile; + } + + @Override + public String getKnownHostsFile() { + return myKnownHostsFile; + } + + public void setKnownHostsFile(String knownHostsFile) { + myKnownHostsFile = knownHostsFile; + } + + @Override + @Transient + public String getPassphrase() { + return myPassphrase; + } + + public void setPassphrase(String passphrase) { + myPassphrase = passphrase; + } + + @Override + public boolean isUseKeyPair() { + return myUseKeyPair; + } + + public void setUseKeyPair(boolean useKeyPair) { + myUseKeyPair = useKeyPair; + } + + public String getSerializedUserName() { + if (myAnonymous || myUserName == null) return ""; + return myUserName; + } + + public void setSerializedUserName(String userName) { + if (StringUtil.isEmpty(userName)) { + myUserName = null; + } + else { + myUserName = userName; + } + } + + public String getSerializedPassword() { + if (myAnonymous) return ""; + + if (myStorePassword) { + return PasswordUtil.encodePassword(myPassword); + } + else { + return ""; + } + } + + public void setSerializedPassword(String serializedPassword) { + if (!StringUtil.isEmpty(serializedPassword)) { + myPassword = PasswordUtil.decodePassword(serializedPassword); + myStorePassword = true; + } + else { + myPassword = null; + } + } + + @Nullable + public String getSerializedPassphrase() { + if (myStorePassphrase) { + return PasswordUtil.encodePassword(myPassphrase); + } + else { + return ""; + } + } + + public void setSerializedPassphrase(String serializedPassphrase) { + if (!StringUtil.isEmpty(serializedPassphrase)) { + myPassphrase = PasswordUtil.decodePassword(serializedPassphrase); + myStorePassphrase = true; + } + else { + myPassphrase = null; + myStorePassphrase = false; + } + } + + public void copyRemoteCredentialsTo(RemoteSdkCredentials to) { + to.setHost(getHost()); + to.setPort(getPort()); + to.setAnonymous(isAnonymous()); + to.setUserName(getUserName()); + to.setPassword(getPassword()); + to.setUseKeyPair(isUseKeyPair()); + to.setPrivateKeyFile(getPrivateKeyFile()); + to.setKnownHostsFile(getKnownHostsFile()); + to.setStorePassword(isStorePassword()); + to.setStorePassphrase(isStorePassphrase()); + } + + public void load(Element element) { + setHost(element.getAttributeValue(HOST)); + setPort(StringUtil.parseInt(element.getAttributeValue(PORT), 22)); + setAnonymous(StringUtil.parseBoolean(element.getAttributeValue(ANONYMOUS), false)); + setSerializedUserName(element.getAttributeValue(USERNAME)); + setSerializedPassword(element.getAttributeValue(PASSWORD)); + setPrivateKeyFile(StringUtil.nullize(element.getAttributeValue(PRIVATE_KEY_FILE))); + setKnownHostsFile(StringUtil.nullize(element.getAttributeValue(KNOWN_HOSTS_FILE))); + setSerializedPassphrase(element.getAttributeValue(PASSPHRASE)); + setUseKeyPair(StringUtil.parseBoolean(element.getAttributeValue(USE_KEY_PAIR), false)); + } + + public void save(Element rootElement) { + rootElement.setAttribute(HOST, StringUtil.notNullize(getHost())); + rootElement.setAttribute(PORT, Integer.toString(getPort())); + rootElement.setAttribute(ANONYMOUS, Boolean.toString(isAnonymous())); + rootElement.setAttribute(USERNAME, getSerializedUserName()); + rootElement.setAttribute(PASSWORD, getSerializedPassword()); + rootElement.setAttribute(PRIVATE_KEY_FILE, StringUtil.notNullize(getPrivateKeyFile())); + rootElement.setAttribute(KNOWN_HOSTS_FILE, StringUtil.notNullize(getKnownHostsFile())); + rootElement.setAttribute(PASSPHRASE, getSerializedPassphrase()); + rootElement.setAttribute(USE_KEY_PAIR, Boolean.toString(isUseKeyPair())); + } + + public void copyFrom(RemoteCredentials from) { + setHost(from.getHost()); + setPort(from.getPort()); + setAnonymous(from.isAnonymous()); + setUserName(from.getUserName()); + setPassword(from.getPassword()); + setUseKeyPair(from.isUseKeyPair()); + setPrivateKeyFile(from.getPrivateKeyFile()); + setKnownHostsFile(from.getKnownHostsFile()); + setStorePassword(from.isStorePassword()); + setStorePassphrase(from.isStorePassphrase()); + } +} diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteFile.java b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java new file mode 100644 index 000000000000..4a2e11379364 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java @@ -0,0 +1,110 @@ +package com.intellij.remote; + +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author traff + */ +public class RemoteFile { + + private final boolean myWin; + private final String myPath; + + public RemoteFile(@NotNull String path, boolean isWin) { + myPath = toSystemDependent(path, isWin); + myWin = isWin; + } + + public RemoteFile(@NotNull String parent, String child) { + this(resolveChild(parent, child, isWindowsPath(parent)), isWindowsPath(parent)); + } + + public RemoteFile(@NotNull String parent, String child, boolean isWin) { + this(resolveChild(parent, child, isWin), isWin); + } + + @Nullable + public String getName() { + int ind = myPath.lastIndexOf(getSeparator(myWin)); + if (ind != -1 && ind < myPath.length() - 1) { //not last char + return myPath.substring(ind + 1); + } + else { + return null; + } + } + + private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) { + String separator = getSeparator(win); + + String path; + if (parent.endsWith(separator)) { + path = parent + child; + } + else { + path = parent + separator + child; + } + return path; + } + + private static String getSeparator(boolean win) { + String separator; + if (win) { + separator = "\\"; + } + else { + separator = "/"; + } + return separator; + } + + + public String getPath() { + return myPath; + } + + public boolean isWin() { + return isWindowsPath(myPath); + } + + public static boolean isWindowsPath(@NotNull String path) { + path = RemoteSdkCredentialsHolder.getInterpreterPathFromFullPath(path); + + return (path.length() > 1 && path.charAt(1) == ':'); + } + + private static String toSystemDependent(@NotNull String path, boolean isWin) { + char separator = isWin ? '\\' : '/'; + return FileUtil.toSystemIndependentName(path).replace('/', separator); + } + + public static RemoteFileBuilder detectSystemByPath(@NotNull String path) { + return new RemoteFileBuilder(isWindowsPath(path)); + } + + public static RemoteFile createRemoteFile(String path, String script) { + return detectSystemByPath(path).createRemoteFile(path, script); + } + + public static RemoteFile createRemoteFile(final String path, final String script, final boolean isWindows) { + return new RemoteFileBuilder(isWindows).createRemoteFile(path, script); + } + + public static class RemoteFileBuilder { + private final boolean isWin; + + private RemoteFileBuilder(boolean win) { + isWin = win; + } + + public RemoteFile createRemoteFile(String path) { + return new RemoteFile(path, isWin); + } + + public RemoteFile createRemoteFile(String path, String child) { + return new RemoteFile(path, child, isWin); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java b/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java new file mode 100644 index 000000000000..efeb9bf176e6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteProcessHandlerBase.java @@ -0,0 +1,20 @@ +package com.intellij.remote; + +import com.intellij.openapi.util.Pair; +import com.intellij.remote.RemoteSdkException; +import com.intellij.util.PathMappingSettings; + +import java.util.List; + +/** + * @author traff + */ +public interface RemoteProcessHandlerBase { + PathMappingSettings getMappingSettings(); + + Pair obtainRemoteSocket() throws RemoteSdkException; + + void addRemoteForwarding(int remotePort, int localPort); + + List getFileMappings(); +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java similarity index 83% rename from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java index c295a42c9598..dca7f1a6e7d3 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkAdditionalData2.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java @@ -13,18 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; import com.intellij.openapi.projectRoots.SdkAdditionalData; -import com.intellij.remotesdk.RemoteSdkCredentials; -import com.intellij.remotesdk.RemoteSdkCredentialsHolder; -import com.intellij.remotesdk.RemoteSdkProperties; import org.jetbrains.annotations.NotNull; /** * @author traff */ -public interface RemoteSdkAdditionalData2 +public interface RemoteSdkAdditionalData extends SdkAdditionalData, RemoteSdkProducer, RemoteSdkProperties { void completeInitialization(); diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java similarity index 54% rename from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java index 8d094aea8c46..876f82771025 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentials.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java @@ -1,4 +1,7 @@ -package com.intellij.remotesdk; +package com.intellij.remote; + +import com.intellij.remote.MutableRemoteCredentials; +import com.intellij.remote.RemoteSdkProperties; /** * @author traff diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java similarity index 98% rename from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java index 57ea1136527b..59e9cf02d7ba 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsBuilder.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk; +package com.intellij.remote; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java similarity index 98% rename from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java index 6a2e5c2a485b..e936686e0840 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkCredentialsHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java @@ -1,6 +1,5 @@ -package com.intellij.remotesdk; +package com.intellij.remote; -import com.intellij.remotesdk2.RemoteConnectionCredentialsWrapper; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java new file mode 100644 index 000000000000..fd6f5440b782 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkException.java @@ -0,0 +1,49 @@ +package com.intellij.remote; + +import com.intellij.execution.ExecutionException; + +import java.net.NoRouteToHostException; + +/** + * @author traff + */ +public class RemoteSdkException extends ExecutionException { + private final boolean myNoRouteToHost; + private final boolean myAuthFailed; + + public RemoteSdkException(String s, Throwable throwable) { + super(s, throwable); + myNoRouteToHost = throwable instanceof NoRouteToHostException; + myAuthFailed = false; + } + + public RemoteSdkException(String s) { + super(s); + myAuthFailed = false; + myNoRouteToHost = false; + } + + public boolean isNoRouteToHost() { + return myNoRouteToHost; + } + + public boolean isAuthFailed() { + return myAuthFailed; + } + + public String getMessage() { + if (myNoRouteToHost) { + return getCause().getMessage(); + } + else if (myAuthFailed) { + return "Authentication failed"; + } + else { + return super.getMessage(); + } + } + + public static RemoteSdkException cantObtainRemoteCredentials(Throwable e) { + return new RemoteSdkException("Cant obtain remote credentials", e); + } +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java similarity index 85% rename from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java index cc3d06af7770..dc28679937fe 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkFactory2.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkFactory.java @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.remotesdk.RemoteInterpreterException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,9 +26,9 @@ import java.util.Collection; /** * @author traff */ -public interface RemoteSdkFactory2 { +public interface RemoteSdkFactory { Sdk createRemoteSdk(@Nullable Project project, @NotNull T data, @Nullable String sdkName, Collection existingSdks) - throws RemoteInterpreterException; + throws RemoteSdkException; Sdk createUnfinished(T data, Collection existingSdks); diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java similarity index 91% rename from platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java index 0178ab8a2752..cd5c00ed9e2a 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/RemoteSdkProducer.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; -import com.intellij.remotesdk.RemoteSdkCredentials; import com.intellij.util.Consumer; /** diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java similarity index 97% rename from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java index ed7fe6bd00c0..7d132578a6d4 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkProperties.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk; +package com.intellij.remote; import java.util.List; diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java similarity index 99% rename from platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java rename to platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java index 5b63720a5d50..bc5fad1e4fff 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkPropertiesHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk; +package com.intellij.remote; import com.intellij.openapi.util.JDOMExternalizer; import com.intellij.openapi.util.text.StringUtil; diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java new file mode 100644 index 000000000000..b9090bcd3ee8 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSshProcess.java @@ -0,0 +1,22 @@ +package com.intellij.remote; + +import com.intellij.execution.process.SelfKiller; + +/** + * @author traff + */ +abstract public class RemoteSshProcess extends Process implements SelfKiller { + /** + * Makes host:localPort server which is available on local side available on remote side as localhost:remotePort. + */ + public abstract void addRemoteTunnel(int remotePort, String host, int localPort) throws RemoteSdkException; + + /** + * Makes host:remotePort server which is available on remote side available on local side as localhost:localPort. + */ + public abstract void addLocalTunnel(int localPort, String host, int remotePort) throws RemoteSdkException; + + public abstract boolean hasPty(); + + public abstract boolean sendCtrlC(); +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/VagrantBasedCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java similarity index 94% rename from platform/platform-impl/src/com/intellij/remotesdk2/VagrantBasedCredentialsHolder.java rename to platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java index 8e9d36f058d1..d5f867c5836d 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/VagrantBasedCredentialsHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/VagrantBasedCredentialsHolder.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; -import com.intellij.openapi.util.text.StringUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; diff --git a/platform/platform-impl/src/com/intellij/remotesdk2/WebDeploymentCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java similarity index 93% rename from platform/platform-impl/src/com/intellij/remotesdk2/WebDeploymentCredentialsHolder.java rename to platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java index d43d0cb4ece3..5db969a6592c 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk2/WebDeploymentCredentialsHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/WebDeploymentCredentialsHolder.java @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk2; +package com.intellij.remote; -import com.intellij.remotesdk.RemoteCredentials; -import com.intellij.remotesdk.RemoteCredentialsHolder; import org.jdom.Element; import org.jetbrains.annotations.NotNull; diff --git a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java index e52d8d3337fb..0b630fec6a8b 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,31 +15,9 @@ */ package com.intellij.remotesdk; -import org.jetbrains.annotations.Nullable; - /** + * @deprecated Remove in IDEA 14 * @author traff */ -public interface MutableRemoteCredentials extends RemoteCredentials { - void setHost(String host); - - void setPort(int port); - - void setUserName(String userName); - - void setPassword(@Nullable String password); - - void setStorePassword(boolean storePassword); - - void setStorePassphrase(boolean storePassphrase); - - void setAnonymous(boolean anonymous); - - void setPrivateKeyFile(String privateKeyFile); - - void setKnownHostsFile(String knownHostsFile); - - void setPassphrase(@Nullable String passphrase); - - void setUseKeyPair(boolean useKeyPair); +public interface MutableRemoteCredentials extends com.intellij.remote.MutableRemoteCredentials { } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java index eeded52aad2e..2a249209b8e8 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java @@ -1,9 +1,26 @@ +/* + * Copyright 2000-2014 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.remotesdk; /** + * @deprecated Remove in IDEA 14 + * * @author traff */ -public class RemoteCancelledException extends RemoteInterpreterException { +public class RemoteCancelledException extends com.intellij.remote.RemoteCancelledException { public RemoteCancelledException(String s) { super(s); } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java index bb7494044beb..e6be766ca826 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,33 +15,10 @@ */ package com.intellij.remotesdk; -import com.intellij.util.xmlb.annotations.Transient; - /** + * @deprecated Remove in IDEA 14 + * * @author traff */ -public interface RemoteCredentials { - String getHost(); - - int getPort(); - - @Transient - String getUserName(); - - String getPassword(); - - @Transient - String getPassphrase(); - - boolean isUseKeyPair(); - - boolean isAnonymous(); - - String getPrivateKeyFile(); - - boolean isStorePassword(); - - boolean isStorePassphrase(); - - String getKnownHostsFile(); +public interface RemoteCredentials extends com.intellij.remote.RemoteCredentials { } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java index 8908c3451a72..886052957f32 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,243 +15,10 @@ */ package com.intellij.remotesdk; -import com.intellij.openapi.util.PasswordUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.xmlb.annotations.Transient; -import org.jdom.Element; -import org.jetbrains.annotations.Nullable; - /** - * @author michael.golubev + * @deprecated Remove in IDEA 14 + * + * @author traff */ -public class RemoteCredentialsHolder implements MutableRemoteCredentials { - - public static final String HOST = "HOST"; - public static final String PORT = "PORT"; - public static final String ANONYMOUS = "ANONYMOUS"; - public static final String USERNAME = "USERNAME"; - public static final String PASSWORD = "PASSWORD"; - public static final String USE_KEY_PAIR = "USE_KEY_PAIR"; - public static final String PRIVATE_KEY_FILE = "PRIVATE_KEY_FILE"; - public static final String KNOWN_HOSTS_FILE = "MY_KNOWN_HOSTS_FILE"; - public static final String PASSPHRASE = "PASSPHRASE"; - - private String myHost; - private int myPort; - private boolean myAnonymous; - private String myUserName; - private String myPassword; - private boolean myUseKeyPair; - private String myPrivateKeyFile; - private String myKnownHostsFile; - private String myPassphrase; - private boolean myStorePassword; - private boolean myStorePassphrase; - - @Override - public String getHost() { - return myHost; - } - - public void setHost(String host) { - myHost = host; - } - - @Override - public int getPort() { - return myPort; - } - - public void setPort(int port) { - myPort = port; - } - - @Override - @Transient - public String getUserName() { - return myUserName; - } - - public void setUserName(String userName) { - myUserName = userName; - } - - @Override - public String getPassword() { - return myPassword; - } - - public void setPassword(String password) { - myPassword = password; - } - - public void setStorePassword(boolean storePassword) { - myStorePassword = storePassword; - } - - public void setStorePassphrase(boolean storePassphrase) { - myStorePassphrase = storePassphrase; - } - - @Override - public boolean isStorePassword() { - return myStorePassword; - } - - @Override - public boolean isStorePassphrase() { - return myStorePassphrase; - } - - @Override - public boolean isAnonymous() { - return myAnonymous; - } - - public void setAnonymous(boolean anonymous) { - myAnonymous = anonymous; - } - - @Override - public String getPrivateKeyFile() { - return myPrivateKeyFile; - } - - public void setPrivateKeyFile(String privateKeyFile) { - myPrivateKeyFile = privateKeyFile; - } - - @Override - public String getKnownHostsFile() { - return myKnownHostsFile; - } - - public void setKnownHostsFile(String knownHostsFile) { - myKnownHostsFile = knownHostsFile; - } - - @Override - @Transient - public String getPassphrase() { - return myPassphrase; - } - - public void setPassphrase(String passphrase) { - myPassphrase = passphrase; - } - - @Override - public boolean isUseKeyPair() { - return myUseKeyPair; - } - - public void setUseKeyPair(boolean useKeyPair) { - myUseKeyPair = useKeyPair; - } - - public String getSerializedUserName() { - if (myAnonymous || myUserName == null) return ""; - return myUserName; - } - - public void setSerializedUserName(String userName) { - if (StringUtil.isEmpty(userName)) { - myUserName = null; - } - else { - myUserName = userName; - } - } - - public String getSerializedPassword() { - if (myAnonymous) return ""; - - if (myStorePassword) { - return PasswordUtil.encodePassword(myPassword); - } - else { - return ""; - } - } - - public void setSerializedPassword(String serializedPassword) { - if (!StringUtil.isEmpty(serializedPassword)) { - myPassword = PasswordUtil.decodePassword(serializedPassword); - myStorePassword = true; - } - else { - myPassword = null; - } - } - - @Nullable - public String getSerializedPassphrase() { - if (myStorePassphrase) { - return PasswordUtil.encodePassword(myPassphrase); - } - else { - return ""; - } - } - - public void setSerializedPassphrase(String serializedPassphrase) { - if (!StringUtil.isEmpty(serializedPassphrase)) { - myPassphrase = PasswordUtil.decodePassword(serializedPassphrase); - myStorePassphrase = true; - } - else { - myPassphrase = null; - myStorePassphrase = false; - } - } - - public void copyRemoteCredentialsTo(RemoteSdkCredentials to) { - to.setHost(getHost()); - to.setPort(getPort()); - to.setAnonymous(isAnonymous()); - to.setUserName(getUserName()); - to.setPassword(getPassword()); - to.setUseKeyPair(isUseKeyPair()); - to.setPrivateKeyFile(getPrivateKeyFile()); - to.setKnownHostsFile(getKnownHostsFile()); - to.setStorePassword(isStorePassword()); - to.setStorePassphrase(isStorePassphrase()); - } - - public void load(Element element) { - setHost(element.getAttributeValue(HOST)); - setPort(StringUtil.parseInt(element.getAttributeValue(PORT), 22)); - setAnonymous(StringUtil.parseBoolean(element.getAttributeValue(ANONYMOUS), false)); - setSerializedUserName(element.getAttributeValue(USERNAME)); - setSerializedPassword(element.getAttributeValue(PASSWORD)); - setPrivateKeyFile(StringUtil.nullize(element.getAttributeValue(PRIVATE_KEY_FILE))); - setKnownHostsFile(StringUtil.nullize(element.getAttributeValue(KNOWN_HOSTS_FILE))); - setSerializedPassphrase(element.getAttributeValue(PASSPHRASE)); - setUseKeyPair(StringUtil.parseBoolean(element.getAttributeValue(USE_KEY_PAIR), false)); - } - - public void save(Element rootElement) { - rootElement.setAttribute(HOST, StringUtil.notNullize(getHost())); - rootElement.setAttribute(PORT, Integer.toString(getPort())); - rootElement.setAttribute(ANONYMOUS, Boolean.toString(isAnonymous())); - rootElement.setAttribute(USERNAME, getSerializedUserName()); - rootElement.setAttribute(PASSWORD, getSerializedPassword()); - rootElement.setAttribute(PRIVATE_KEY_FILE, StringUtil.notNullize(getPrivateKeyFile())); - rootElement.setAttribute(KNOWN_HOSTS_FILE, StringUtil.notNullize(getKnownHostsFile())); - rootElement.setAttribute(PASSPHRASE, getSerializedPassphrase()); - rootElement.setAttribute(USE_KEY_PAIR, Boolean.toString(isUseKeyPair())); - } - - public void copyFrom(RemoteCredentials from) { - setHost(from.getHost()); - setPort(from.getPort()); - setAnonymous(from.isAnonymous()); - setUserName(from.getUserName()); - setPassword(from.getPassword()); - setUseKeyPair(from.isUseKeyPair()); - setPrivateKeyFile(from.getPrivateKeyFile()); - setKnownHostsFile(from.getKnownHostsFile()); - setStorePassword(from.isStorePassword()); - setStorePassphrase(from.isStorePassphrase()); - } +public class RemoteCredentialsHolder extends com.intellij.remote.RemoteCredentialsHolder { } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java index 51896dbf1213..73274cc0f356 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java @@ -1,110 +1,38 @@ +/* + * Copyright 2000-2014 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.remotesdk; -import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** + * @deprecated Remove in IDEA 14 + * * @author traff */ -public class RemoteFile { - - private final boolean myWin; - private final String myPath; +public class RemoteFile extends com.intellij.remote.RemoteFile { public RemoteFile(@NotNull String path, boolean isWin) { - myPath = toSystemDependent(path, isWin); - myWin = isWin; + super(path, isWin); } public RemoteFile(@NotNull String parent, String child) { - this(resolveChild(parent, child, isWindowsPath(parent)), isWindowsPath(parent)); + super(parent, child); } public RemoteFile(@NotNull String parent, String child, boolean isWin) { - this(resolveChild(parent, child, isWin), isWin); - } - - @Nullable - public String getName() { - int ind = myPath.lastIndexOf(getSeparator(myWin)); - if (ind != -1 && ind < myPath.length() - 1) { //not last char - return myPath.substring(ind + 1); - } - else { - return null; - } - } - - private static String resolveChild(@NotNull String parent, @NotNull String child, boolean win) { - String separator = getSeparator(win); - - String path; - if (parent.endsWith(separator)) { - path = parent + child; - } - else { - path = parent + separator + child; - } - return path; - } - - private static String getSeparator(boolean win) { - String separator; - if (win) { - separator = "\\"; - } - else { - separator = "/"; - } - return separator; - } - - - public String getPath() { - return myPath; - } - - public boolean isWin() { - return isWindowsPath(myPath); - } - - public static boolean isWindowsPath(@NotNull String path) { - path = RemoteSdkCredentialsHolder.getInterpreterPathFromFullPath(path); - - return (path.length() > 1 && path.charAt(1) == ':'); - } - - private static String toSystemDependent(@NotNull String path, boolean isWin) { - char separator = isWin ? '\\' : '/'; - return FileUtil.toSystemIndependentName(path).replace('/', separator); - } - - public static RemoteFileBuilder detectSystemByPath(@NotNull String path) { - return new RemoteFileBuilder(isWindowsPath(path)); - } - - public static RemoteFile createRemoteFile(String path, String script) { - return detectSystemByPath(path).createRemoteFile(path, script); - } - - public static RemoteFile createRemoteFile(final String path, final String script, final boolean isWindows) { - return new RemoteFileBuilder(isWindows).createRemoteFile(path, script); - } - - public static class RemoteFileBuilder { - private final boolean isWin; - - private RemoteFileBuilder(boolean win) { - isWin = win; - } - - public RemoteFile createRemoteFile(String path) { - return new RemoteFile(path, isWin); - } - - public RemoteFile createRemoteFile(String path, String child) { - return new RemoteFile(path, child, isWin); - } + super(parent, child, isWin); } } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java index 0a31e6578cce..b3d3b35b5aa2 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java @@ -1,49 +1,29 @@ +/* + * Copyright 2000-2014 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.remotesdk; -import com.intellij.execution.ExecutionException; - -import java.net.NoRouteToHostException; +import com.intellij.remote.RemoteSdkException; /** + * @deprecated Remove in IDEA 14 + * * @author traff */ -public class RemoteInterpreterException extends ExecutionException { - private final boolean myNoRouteToHost; - private final boolean myAuthFailed; - +public class RemoteInterpreterException extends RemoteSdkException { public RemoteInterpreterException(String s, Throwable throwable) { super(s, throwable); - myNoRouteToHost = throwable instanceof NoRouteToHostException; - myAuthFailed = false; - } - - public RemoteInterpreterException(String s) { - super(s); - myAuthFailed = false; - myNoRouteToHost = false; - } - - public boolean isNoRouteToHost() { - return myNoRouteToHost; - } - - public boolean isAuthFailed() { - return myAuthFailed; - } - - public String getMessage() { - if (myNoRouteToHost) { - return getCause().getMessage(); - } - else if (myAuthFailed) { - return "Authentication failed"; - } - else { - return super.getMessage(); - } - } - - public static RemoteInterpreterException cantObtainRemoteCredentials(Throwable e) { - return new RemoteInterpreterException("Cant obtain remote credentials", e); } } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java index c004f8ae211d..a83d2bdc2455 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java @@ -1,19 +1,24 @@ +/* + * Copyright 2000-2014 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.remotesdk; -import com.intellij.openapi.util.Pair; -import com.intellij.util.PathMappingSettings; - -import java.util.List; - /** + * @deprecated Remove in IDEA 14 + * * @author traff */ -public interface RemoteProcessHandlerBase { - PathMappingSettings getMappingSettings(); - - Pair obtainRemoteSocket() throws RemoteInterpreterException; - - void addRemoteForwarding(int remotePort, int localPort); - - List getFileMappings(); +public interface RemoteProcessHandlerBase extends com.intellij.remote.RemoteProcessHandlerBase { } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java index d9f1b67bb836..e4c79ed8d7f2 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java @@ -1,8 +1,10 @@ package com.intellij.remotesdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; +import com.intellij.remote.RemoteSdkCredentials; /** + * @deprecated Remove in IDEA 14 * @author traff */ public interface RemoteSdkAdditionalData extends RemoteSdkCredentials, SdkAdditionalData { diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java new file mode 100644 index 000000000000..d99ea338db00 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 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.remotesdk; + +import com.intellij.remote.RemoteSdkCredentials; + +/** + * @deprecated Remove in IDEA 14 + * + * @author traff + */ +public interface RemoteSdkData extends RemoteSdkCredentials { +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java new file mode 100644 index 000000000000..f2dd26589392 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 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.remotesdk; + +import com.intellij.remote.RemoteSdkCredentialsBuilder; + +/** + * @deprecated Remove in IDEA 14 + * + * @author traff + */ +public class RemoteSdkDataBuilder extends RemoteSdkCredentialsBuilder { +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java new file mode 100644 index 000000000000..b4f837c72a3f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 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.remotesdk; + +import com.intellij.remote.RemoteSdkCredentialsHolder; +import org.jetbrains.annotations.NotNull; + +/** + * @deprecated Remove in IDEA 14 + * + * @author traff + */ +public class RemoteSdkDataHolder extends RemoteSdkCredentialsHolder { + public RemoteSdkDataHolder(@NotNull String defaultHelpersDirName) { + super(defaultHelpersDirName); + } +} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java index 86113a5337bf..1934d1aa36a2 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java @@ -17,6 +17,7 @@ package com.intellij.remotesdk; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.remote.RemoteSdkException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,6 +25,7 @@ import java.awt.*; import java.util.Collection; /** + * @deprecated Remove in IDEA 14 * @author traff */ public interface RemoteSdkFactory { diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java index 35c589719b53..3abe39bd1aba 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java +++ b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java @@ -1,22 +1,23 @@ +/* + * Copyright 2000-2014 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.remotesdk; -import com.intellij.execution.process.SelfKiller; - /** + * @deprecated Remove in IDEA 14 * @author traff */ -abstract public class RemoteSshProcess extends Process implements SelfKiller { - /** - * Makes host:localPort server which is available on local side available on remote side as localhost:remotePort. - */ - public abstract void addRemoteTunnel(int remotePort, String host, int localPort) throws RemoteInterpreterException; - - /** - * Makes host:remotePort server which is available on remote side available on local side as localhost:localPort. - */ - public abstract void addLocalTunnel(int localPort, String host, int remotePort) throws RemoteInterpreterException; - - public abstract boolean hasPty(); - - public abstract boolean sendCtrlC(); +public abstract class RemoteSshProcess extends com.intellij.remote.RemoteSshProcess { } diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index acfe581d20a5..2d3f8d9b35e2 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -950,6 +950,7 @@ action.Debugger.MarkObject.text=Mark Object... action.Debugger.MarkObject.unmark.text=Unmark Object action.Debugger.MarkObject.description=Mark/unmark the object so that it can be visually distinguished in in debugger views action.Debugger.AddToWatch.text=Add to Watches +action.Debugger.EvaluateInConsole.text=Evaluate In Console action.Debugger.AutoRenderer.text=Auto group.EditorPopupMenu.text=Editor Popup Menu group.EditorPopupMenu.description=Editor Popup Menu diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 2a3006e89ee0..6ee99f7a2c6c 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -644,14 +644,17 @@ - + + + + - + @@ -716,7 +719,7 @@ - + @@ -737,7 +740,7 @@ - + diff --git a/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java b/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java index d53ae4af054a..7133c987f4b0 100644 --- a/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java +++ b/platform/platform-tests/testSrc/com/intellij/remotesdk/RemoteFileTest.java @@ -15,6 +15,8 @@ */ package com.intellij.remotesdk; +import com.intellij.remote.RemoteFile; +import com.intellij.remote.RemoteSdkCredentialsHolder; import junit.framework.TestCase; /** diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index 0f941a3a9c21..24884b4a101c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.ex; import com.intellij.codeInsight.hint.EditorFragmentComponent; import com.intellij.codeInsight.hint.HintManagerImpl; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.diff.DiffColors; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -165,9 +166,6 @@ public class LineStatusTrackerDrawing { group.add(new ShowLineStatusRangeDiffAction(tracker, range, editor)); group.add(new CopyLineStatusRangeAction(tracker, range)); - @SuppressWarnings("unchecked") - final List actionList = (List)editorComponent.getClientProperty(AnAction.ourClientProperty); - final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent(); final Color background = ((EditorEx)editor).getBackgroundColor(); @@ -218,6 +216,7 @@ public class LineStatusTrackerDrawing { EditorFactory.getInstance().releaseEditor(uEditor); } + final List actionList = ActionUtil.getActions(editorComponent); final LightweightHint lightweightHint = new LightweightHint(component); HintListener closeListener = new HintListener() { public void hintHidden(final EventObject event) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java index def016c080fd..82c052240673 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java @@ -112,6 +112,10 @@ public abstract class DebuggerSupport { @NotNull public abstract DebuggerActionHandler getAddToWatchesActionHandler(); + public DebuggerActionHandler getEvaluateInConsoleActionHandler() { + return DisabledActionHandler.INSTANCE; + } + @NotNull public abstract DebuggerToggleActionHandler getMuteBreakpointsHandler(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java index 0215c37812cb..fbfe184a5f3f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java @@ -50,7 +50,10 @@ public class XDebuggerSupport extends DebuggerSupport { private final XDebuggerEvaluateActionHandler myEvaluateHandler; private final XQuickEvaluateHandler myQuickEvaluateHandler; private final XDebuggerSettingsPanelProviderImpl mySettingsPanelProvider; + private final XAddToWatchesFromEditorActionHandler myAddToWatchesActionHandler; + private final DebuggerActionHandler myEvaluateInConsoleActionHandler = new XEvaluateInConsoleFromEditorActionHandler(); + private final DebuggerToggleActionHandler myMuteBreakpointsHandler; private final DebuggerActionHandler mySmartStepIntoHandler; private final XMarkObjectActionHandler myMarkObjectActionHandler; @@ -222,6 +225,12 @@ public class XDebuggerSupport extends DebuggerSupport { return myAddToWatchesActionHandler; } + @NotNull + @Override + public DebuggerActionHandler getEvaluateInConsoleActionHandler() { + return myEvaluateInConsoleActionHandler; + } + @Override @NotNull public DebuggerToggleActionHandler getMuteBreakpointsHandler() { @@ -250,5 +259,4 @@ public class XDebuggerSupport extends DebuggerSupport { public DebuggerSettingsPanelProvider getSettingsPanelProvider() { return mySettingsPanelProvider; } - } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java index 0dcddb3db416..ebfbb94ed5da 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EvaluateInConsoleAction.java @@ -26,6 +26,6 @@ final class EvaluateInConsoleAction extends XDebuggerActionBase { @NotNull @Override protected DebuggerActionHandler getHandler(@NotNull DebuggerSupport debuggerSupport) { - return debuggerSupport.getAddToWatchesActionHandler(); + return debuggerSupport.getEvaluateInConsoleActionHandler(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java index 0a261501fa95..b1aac452c60f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java @@ -35,7 +35,7 @@ public class XAddToWatchesFromEditorActionHandler extends XDebuggerActionHandler } @Nullable - private static String getTextToEvaluate(DataContext dataContext, XDebugSession session) { + protected static String getTextToEvaluate(DataContext dataContext, XDebugSession session) { final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); if (editor == null) { return null; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java new file mode 100644 index 000000000000..880f588d9c2b --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XEvaluateInConsoleFromEditorActionHandler.java @@ -0,0 +1,79 @@ +package com.intellij.xdebugger.impl.actions.handlers; + +import com.intellij.execution.console.ConsoleExecuteAction; +import com.intellij.execution.console.LanguageConsoleView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.ActionUtil; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class XEvaluateInConsoleFromEditorActionHandler extends XAddToWatchesFromEditorActionHandler { + @Override + protected boolean isEnabled(@NotNull XDebugSession session, DataContext dataContext) { + return super.isEnabled(session, dataContext) && getConsoleExecuteAction(session) != null; + } + + @Nullable + private static ConsoleExecuteAction getConsoleExecuteAction(@NotNull XDebugSession session) { + if (!(session.getConsoleView() instanceof LanguageConsoleView)) { + return null; + } + List actions = ActionUtil.getActions(((LanguageConsoleView)session.getConsoleView()).getConsole().getConsoleEditor().getComponent()); + ConsoleExecuteAction action = ContainerUtil.findInstance(actions, ConsoleExecuteAction.class); + return action == null || !action.isEnabled() ? null : action; + } + + @Override + protected void perform(@NotNull XDebugSession session, DataContext dataContext) { + Editor editor = CommonDataKeys.EDITOR.getData(dataContext); + if (editor == null || !(editor instanceof EditorEx)) { + return; + } + + int selectionStart = editor.getSelectionModel().getSelectionStart(); + int selectionEnd = editor.getSelectionModel().getSelectionEnd(); + String text; + TextRange range; + if (selectionStart != selectionEnd) { + range = new TextRange(selectionStart, selectionEnd); + text = editor.getDocument().getText(range); + } + else { + XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator(); + if (evaluator != null) { + Pair expressionInfo = evaluator.getExpressionAtOffset(session.getProject(), editor.getDocument(), selectionStart, true); + if (expressionInfo == null) { + return; + } + + // todo check - is it wrong in case of not-null expressionInfo.second - copied (to console history document) text (text range) could be not correct statement? + range = expressionInfo.first; + text = XDebuggerEvaluateActionHandler.getExpressionText(expressionInfo, editor.getDocument()); + } + else { + return; + } + } + + if (StringUtil.isEmptyOrSpaces(text)) { + return; + } + + ConsoleExecuteAction action = getConsoleExecuteAction(session); + if (action != null) { + action.execute(range, text, (EditorEx)editor); + } + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java index d0b051e31d60..f4b380bd966f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GroovyUntypedAccessInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -27,6 +27,7 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarationAssignment; @@ -35,8 +36,37 @@ import static org.jetbrains.plugins.groovy.annotator.GrHighlightUtil.isDeclarati */ public class GroovyUntypedAccessInspection extends BaseInspection { + @NotNull protected BaseInspectionVisitor buildVisitor() { - return new Visitor(); + return new BaseInspectionVisitor() { + @Override + public void visitReferenceExpression(GrReferenceExpression refExpr) { + super.visitReferenceExpression(refExpr); + + if (PsiUtil.isThisOrSuperRef(refExpr)) return; + + GroovyResolveResult resolveResult = refExpr.advancedResolve(); + + PsiElement resolved = resolveResult.getElement(); + if (resolved != null) { + if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return; + } + else { + GrExpression qualifier = refExpr.getQualifierExpression(); + if (qualifier == null && isDeclarationAssignment(refExpr)) return; + } + + final PsiType refExprType = refExpr.getType(); + if (refExprType == null) { + if (resolved != null) { + registerError(refExpr); + } + } + else if (refExprType instanceof PsiClassType && ((PsiClassType)refExprType).resolve() == null) { + registerError(refExpr); + } + } + }; } @Nls @@ -55,31 +85,4 @@ public class GroovyUntypedAccessInspection extends BaseInspection { protected String buildErrorString(Object... args) { return "Cannot determine type of '#ref'"; } - - private static class Visitor extends BaseInspectionVisitor { - @Override - public void visitReferenceExpression(GrReferenceExpression refExpr) { - super.visitReferenceExpression(refExpr); - GroovyResolveResult resolveResult = refExpr.advancedResolve(); - - PsiElement resolved = resolveResult.getElement(); - if (resolved != null) { - if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return; - } - else { - GrExpression qualifier = refExpr.getQualifierExpression(); - if (qualifier == null && isDeclarationAssignment(refExpr)) return; - } - - final PsiType refExprType = refExpr.getType(); - if (refExprType == null) { - if (resolved != null) { - registerError(refExpr); - } - } - else if (refExprType instanceof PsiClassType && ((PsiClassType)refExprType).resolve() == null) { - registerError(refExpr); - } - } - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java index bba144184a7a..8a98eeff03ea 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java @@ -405,7 +405,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { PsiElement psi = child.getPsi(); if (psi instanceof GrLabeledStatement) { alignGroup(currentGroup, spock, classLevel); - currentGroup = ContainerUtil.newArrayList(/*(GrStatement)psi*/); + currentGroup = ContainerUtil.newArrayList(); spock = true; } else if (currentGroup != null && spock && isTablePart(psi)) { @@ -428,6 +428,10 @@ public class GroovyBlockGenerator implements GroovyElementTypes { currentGroup = null; } } + + if (currentGroup != null) { + alignGroup(currentGroup, spock, classLevel); + } } private boolean shouldSkip(boolean classLevel, PsiElement psi) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java index 990876dea044..6e312234decb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java @@ -1,6 +1,6 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,7 +25,6 @@ import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.stubs.EmptyStub; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; -import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -212,7 +211,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase impl @Nullable @Override public Result compute() { - return Result.create(getReferenceInner(), PsiModificationTracker.MODIFICATION_COUNT); + return Result.create(getReferenceInner(), getContainingFile()); } }); } @@ -226,20 +225,40 @@ public class GrVariableDeclarationImpl extends GrStubElementBase impl final GrVariable[] variables = getVariables(); if (variables.length == 0) return null; - final PsiElement resolved = variables[0]; - return new PsiReferenceBase(this, range, true) { - @Nullable - @Override - public PsiElement resolve() { - return resolved; - } + final GrVariable resolved = variables[0]; + final PsiType inferredType = resolved.getTypeGroovy(); + if (inferredType == null) return null; - @NotNull - @Override - public Object[] getVariants() { - return EMPTY_ARRAY; - } - }; + if (inferredType instanceof PsiClassType) { + return new PsiReferenceBase(this, range, true) { + @Nullable + @Override + public PsiElement resolve() { + return ((PsiClassType)inferredType).resolve(); + } + + @NotNull + @Override + public Object[] getVariants() { + return EMPTY_ARRAY; + } + }; + } + else { + return new PsiReferenceBase(this, range, true) { + @Nullable + @Override + public PsiElement resolve() { + return resolved; + } + + @NotNull + @Override + public Object[] getVariants() { + return EMPTY_ARRAY; + } + }; + } } private TextRange getRangeForReference() { diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java index b506ff73f957..b2eb832319f5 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/DragTracker.java @@ -125,23 +125,26 @@ public class DragTracker extends SelectionTracker { myContext.setLocation(getLocation()); if (myContext.getComponents() == null) { - List components = RadComponent.getPureSelection(myArea.getSelection()); - - RadComponent parent = null; - for (RadComponent component : components) { - if (parent == null) { - parent = component.getParent(); - } - else if (parent != component.getParent()) { - components = Collections.emptyList(); - break; - } - } - + List components = calculateContextComponents(RadComponent.getPureSelection(myArea.getSelection())); myContext.setComponents(components); + for (RadComponent component : components) { component.processDropOperation(myContext); } } } + + protected List calculateContextComponents(List components) { + RadComponent parent = null; + for (RadComponent component : components) { + if (parent == null) { + parent = component.getParent(); + } + else if (parent != component.getParent()) { + components = Collections.emptyList(); + break; + } + } + return components; + } } \ No newline at end of file diff --git a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java index b0790146e6f6..ed2163afd9bd 100644 --- a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java +++ b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java @@ -25,9 +25,9 @@ import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.util.NullableConsumer; import com.intellij.util.containers.ContainerUtil; -import com.jetbrains.python.configuration.PythonSdkDetailsDialog; +import com.jetbrains.python.configuration.PyConfigurableInterpreterList; import com.jetbrains.python.sdk.PyDetectedSdk; -import com.jetbrains.python.sdk.PythonSdkType; +import com.jetbrains.python.sdk.PythonSdkDetailsStep; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import org.jetbrains.annotations.Nullable; @@ -63,14 +63,7 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton { }); addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - final List sdks = PythonSdkType.getAllSdks(); - PythonSdkDetailsDialog dialog = new PythonSdkDetailsDialog(project, new NullableConsumer() { - @Override - public void consume(@Nullable Sdk sdk) { - comboBox.setModel(new CollectionComboBoxModel(sdks, sdk)); - } - }); - dialog.show(); + showOptions(project); notifyChanged(e); } }); @@ -81,6 +74,19 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton { }); } + private void showOptions(final Project project) { + final PyConfigurableInterpreterList interpreterList = PyConfigurableInterpreterList.getInstance(project); + final Sdk[] sdks = interpreterList.getModel().getSdks(); + PythonSdkDetailsStep.show(project, sdks, null, this, getButton().getLocationOnScreen(), new NullableConsumer() { + @Override + public void consume(@Nullable Sdk sdk) { + //noinspection unchecked + getComboBox().setModel(new CollectionComboBoxModel(interpreterList.getAllPythonSdks(), sdk)); + } + } + ); + } + private void notifyChanged(ActionEvent e) { for (ActionListener changedListener : myChangedListeners) { changedListener.actionPerformed(e); diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java index b7298ae10bce..42dbef84b6ce 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java @@ -37,6 +37,7 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.FixedSizeButton; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; @@ -72,6 +73,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { private JButton myDetailsButton; private static final String SHOW_ALL = "Show All"; private NullableConsumer myDetailsCallback; + private PythonSdkDetailsDialog myMoreDialog; public PyActiveSdkConfigurable(@NotNull Project project) { myModule = null; @@ -127,15 +129,14 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { } } }; - + myMoreDialog = myModule == null ? new PythonSdkDetailsDialog(myProject, myDetailsCallback) : + new PythonSdkDetailsDialog(myModule, myDetailsCallback); myDetailsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - PythonSdkDetailsStep - .show(myProject, myProjectSdksModel.getSdks(), - myModule == null ? new PythonSdkDetailsDialog(myProject, myDetailsCallback) : - new PythonSdkDetailsDialog(myModule, myDetailsCallback), myMainPanel, - myDetailsButton.getLocationOnScreen(), true, + PythonSdkDetailsStep.show(myProject, myProjectSdksModel.getSdks(), + myMoreDialog, myMainPanel, + myDetailsButton.getLocationOnScreen(), new NullableConsumer() { @Override public void consume(Sdk sdk) { @@ -407,6 +408,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { public void disposeUIResources() { myProjectSdksModel.removeListener(mySdkModelListener); myInterpreterList.disposeModel(); + Disposer.dispose(myMoreDialog.getDisposable()); } private static class MySdkModelListener implements SdkModel.Listener { diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java index fdb9d31c0fa7..68146c065a4e 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java +++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java @@ -39,7 +39,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.remotesdk.RemoteCredentials; +import com.intellij.remote.RemoteCredentials; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.util.NullableConsumer; @@ -257,7 +257,7 @@ public class PythonSdkDetailsDialog extends DialogWrapper { private void addSdk(AnActionButton button) { PythonSdkDetailsStep - .show(myProject, myProjectSdksModel.getSdks(), this, myMainPanel, button.getPreferredPopupPoint().getScreenPoint(), false, + .show(myProject, myProjectSdksModel.getSdks(), null, myMainPanel, button.getPreferredPopupPoint().getScreenPoint(), new NullableConsumer() { @Override public void consume(Sdk sdk) { diff --git a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java index 8ee900ae3e75..fc639713d965 100644 --- a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java +++ b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java @@ -26,7 +26,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.DirectoryProjectGenerator; import com.intellij.platform.NewDirectoryProjectDialog; -import com.intellij.remotesdk.RemoteSdkCredentials; +import com.intellij.remote.RemoteSdkCredentials; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java b/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java index 5ba21bf90556..f89f25fdf2d2 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyArgumentList.java @@ -20,6 +20,8 @@ import com.jetbrains.python.psi.resolve.PyResolveContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + /** * Represents an argument list of a function call. * @@ -27,6 +29,12 @@ import org.jetbrains.annotations.Nullable; */ public interface PyArgumentList extends PyElement { + /** + * @return all argument list param expressions (keyword argument or nameless) + */ + @NotNull + Collection getArgumentExpressions(); + @NotNull PyExpression[] getArguments(); diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java index 657a54f78299..a988714c144a 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Map; /** * Represents a class declaration in source. @@ -112,6 +113,13 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine @NotNull PyFunction[] getMethods(); + /** + * Get class properties. + * @return Map [property_name] = [{@link com.jetbrains.python.psi.Property}] + */ + @NotNull + Map getProperties(); + /** * Finds a method with given name. * @param name what to look for diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java index 213f63511eb6..c3f89cd0cd57 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java @@ -54,8 +54,8 @@ import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.FileElement; -import com.intellij.remotesdk.RemoteSdkCredentials; -import com.intellij.remotesdk.RemoteSshProcess; +import com.intellij.remote.RemoteSdkCredentials; +import com.intellij.remote.RemoteSshProcess; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.IJSwingUtilities; diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 312db25573c8..0bae7af19732 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -34,7 +34,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; -import com.intellij.remotesdk.RemoteProcessHandlerBase; +import com.intellij.remote.RemoteProcessHandlerBase; import com.intellij.xdebugger.*; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.XBreakpointHandler; diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java index aaf058ca3c6d..fe4ab8f910ef 100644 --- a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java +++ b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java @@ -49,10 +49,9 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; -import com.intellij.remotesdk.RemoteFile; -import com.intellij.remotesdk.RemoteSdkAdditionalData; -import com.intellij.remotesdk.RemoteSdkCredentials; -import com.intellij.remotesdk2.RemoteSdkAdditionalData2; +import com.intellij.remote.RemoteSdkAdditionalData; +import com.intellij.remote.RemoteFile; +import com.intellij.remote.RemoteSdkCredentials; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.SystemProperties; @@ -780,10 +779,10 @@ public class PyPackageManagerImpl extends PyPackageManager { if (homePath == null) { throw new PyExternalProcessException(ERROR_INVALID_SDK, helperPath, args, "Cannot find interpreter for SDK"); } - if (sdkData instanceof RemoteSdkAdditionalData2) { //remote interpreter + if (sdkData instanceof RemoteSdkAdditionalData) { //remote interpreter RemoteSdkCredentials remoteSdkCredentials; try { - remoteSdkCredentials = ((RemoteSdkAdditionalData2)sdkData).getRemoteSdkCredentials(); + remoteSdkCredentials = ((RemoteSdkAdditionalData)sdkData).getRemoteSdkCredentials(); } catch (InterruptedException e) { LOG.error(e); diff --git a/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java b/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java index dfe12ca6dc30..2e6120a29303 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyArgumentListImpl.java @@ -48,6 +48,23 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList pyVisitor.visitPyArgumentList(this); } + @Override + @NotNull + public Collection getArgumentExpressions() { + final PyExpression[] arguments = getArguments(); + final Collection result = new ArrayList(arguments.length); + for (final PyExpression expression : arguments) { + if (expression instanceof PyKeywordArgument) { + final PyExpression valueExpression = ((PyKeywordArgument)expression).getValueExpression(); + result.add(valueExpression); + } + if (expression instanceof PyReferenceExpression) { + result.add(expression); + } + } + return result; + } + @NotNull public PyExpression[] getArguments() { return childrenToPsi(PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens(), PyExpression.EMPTY_ARRAY); diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 516cb4704a95..8e934af1f3bf 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -380,6 +380,13 @@ public class PyClassImpl extends PyPresentableElementImpl implement return getClassChildren(PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens(), PyFunction.ARRAY_FACTORY); } + @Override + @NotNull + public Map getProperties() { + initProperties(); + return new HashMap(myPropertyCache); + } + @Override public PyClass[] getNestedClasses() { return getClassChildren(TokenSet.create(PyElementTypes.CLASS_DECLARATION), PyClass.ARRAY_FACTORY); @@ -607,9 +614,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement @Override public Property findPropertyByCallable(Callable callable) { - if (myPropertyCache == null) { - myPropertyCache = initializePropertyCache(); - } + initProperties(); for (Property property : myPropertyCache.values()) { if (property.getGetter().valueOrNull() == callable || property.getSetter().valueOrNull() == callable || @@ -621,10 +626,14 @@ public class PyClassImpl extends PyPresentableElementImpl implement } private Property findLocalProperty(String name) { + initProperties(); + return myPropertyCache.get(name); + } + + private synchronized void initProperties() { if (myPropertyCache == null) { myPropertyCache = initializePropertyCache(); } - return myPropertyCache.get(name); } private Map initializePropertyCache() { diff --git a/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java b/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java index b22449d9abb0..6cb4504bb960 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/DependencyVisitor.java @@ -38,9 +38,24 @@ class DependencyVisitor extends PyRecursiveElementVisitor { } final String calleeName = callee.getName(); - if ((calleeName != null) && calleeName.equals(myElementToFind.getName())) { // Check by name also + final String name = myElementToFind.getName(); + if ((calleeName != null) && calleeName.equals(name)) { // Check by name also myDependencyFound = true; } + + // Member could be used as method param + final PyArgumentList list = node.getArgumentList(); + if (list != null) { + for (final PyExpression expression : node.getArgumentList().getArgumentExpressions()) { + final PsiReference reference = expression.getReference(); + if ((reference != null) && reference.isReferenceTo(myElementToFind)) { + myDependencyFound = true; + } + if ((name != null) && name.equals(expression.getName())) { + myDependencyFound = true; + } + } + } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java index 3dfc71bc87f7..25b8a23703cf 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java @@ -125,7 +125,7 @@ public final class PyClassRefactoringUtil { } @NotNull - public static List copyMethods(Collection methods, PyClass superClass) { + public static List copyMethods(Collection methods, PyClass superClass, boolean skipIfExist ) { if (methods.isEmpty()) { return Collections.emptyList(); } @@ -133,7 +133,7 @@ public final class PyClassRefactoringUtil { rememberNamedReferences(e); } final PyFunction[] elements = methods.toArray(new PyFunction[methods.size()]); - return addMethods(superClass, true, elements); + return addMethods(superClass, skipIfExist, elements); } /** diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java index 3bf4f00553e1..281ad586bdd7 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java @@ -1,9 +1,9 @@ package com.jetbrains.python.refactoring.classes.membersManager; -import com.jetbrains.python.psi.PyAssignmentStatement; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.psi.PyTargetExpression; +import com.google.common.collect.FluentIterable; +import com.jetbrains.NotNullPredicate; +import com.jetbrains.python.PyNames; +import com.jetbrains.python.psi.*; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; import org.jetbrains.annotations.NotNull; @@ -31,8 +31,21 @@ class ClassFieldsManager extends FieldsManager { protected Collection moveAssignments(@NotNull final PyClass from, @NotNull final Collection statements, @NotNull final PyClass... to) { + return moveAssignmentsImpl(from, statements, to); + } + + /** + * Moves assignments from one class to anothers + * @param from source + * @param statements assignments + * @param to destination + * @return newly created assignments + */ + static Collection moveAssignmentsImpl(@NotNull final PyClass from, + @NotNull final Collection statements, + @NotNull final PyClass... to) { //TODO: Copy/paste with InstanceFieldsManager. Move to parent? - final List result = new ArrayList(); + final Collection result = new ArrayList(); for (final PyClass destClass : to) { result.addAll(PyClassRefactoringUtil.copyFieldDeclarationToStatement(statements, destClass.getStatementList(), destClass)); } @@ -49,6 +62,39 @@ class ClassFieldsManager extends FieldsManager { @NotNull @Override protected List getFieldsByClass(@NotNull final PyClass pyClass) { - return pyClass.getClassAttributes(); + return FluentIterable.from(pyClass.getClassAttributes()).filter(new NoMetaAndProperties(pyClass)).toList(); + } + + /** + * Exclude "__metaclass__" field and properties (there should be separate managers for them) + * TODO: Check type and filter out any builtin element instead? + */ + private static class NoMetaAndProperties extends NotNullPredicate { + @NotNull + private final PyClass myClass; + + private NoMetaAndProperties(@NotNull final PyClass aClass) { + myClass = aClass; + } + + @Override + public boolean applyNotNull(@NotNull final PyTargetExpression input) { + final String name = input.getName(); + if (name == null) { + return false; + } + if (name.equals(PyNames.DUNDER_METACLASS)) { + return false; + } + + final PyExpression assignedValue = input.findAssignedValue(); + if (assignedValue instanceof PyCallExpression) { + final PyExpression callee = ((PyCallExpression)assignedValue).getCallee(); + if ((callee != null) && PyNames.PROPERTY.equals(callee.getName()) && (myClass.findProperty(name, false) != null)) { + return false; + } + } + return true; + } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java index 437b8085d765..b2d8dac2c4a8 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java @@ -20,7 +20,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiNamedElement; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.MultiMap; import com.jetbrains.NotNullPredicate; @@ -45,7 +44,11 @@ public abstract class MembersManager implements Function> MANAGERS = - Arrays.asList(new MethodsManager(), new SuperClassesManager(), new ClassFieldsManager(), new InstanceFieldsManager()); + Arrays.asList(new MethodsManager(), + new SuperClassesManager(), + new ClassFieldsManager(), + new InstanceFieldsManager(), + new PropertiesManager()); @NotNull private final Class myExpectedClass; @@ -84,7 +87,7 @@ public abstract class MembersManager implements Function> transformSafely(@NotNull final PyClass pyClass, @NotNull final MembersManager manager) { - final List membersCouldBeMoved = manager.getMembersCouldBeMoved(pyClass); + final List membersCouldBeMoved = manager.getMembersCouldBeMoved(pyClass); manager.checkElementTypes((Iterable)membersCouldBeMoved); return (Collection>)Collections2.transform(membersCouldBeMoved, (Function)manager); } @@ -175,7 +178,8 @@ public abstract class MembersManager implements Function implements Function getMembersCouldBeMoved(@NotNull PyClass pyClass); + protected abstract List getMembersCouldBeMoved(@NotNull PyClass pyClass); - /** - * Filters out named elements (ones that subclasses {@link com.intellij.psi.PsiNamedElement}) and {@link com.jetbrains.python.psi.PyElement}) - * that are null or has null name. - * You need it sometimes when code has errors (i.e. bad formatted code with annotation may treat annotation as method with null name. - * note: we should probably throw exceptions in such cases and display "refactoring not available" window in handler) - * - * @param elementsToFilter collection of elements to filter - * @param element type - * @return collection of T with out of nulls and elemens whos {@link com.intellij.psi.PsiNamedElement#getName()} returns null - */ - @NotNull - protected static Collection filterNameless(@NotNull final Collection elementsToFilter) { - return Collections2.filter(elementsToFilter, new NamelessFilter()); - } - /** * Returns list of elements that may require reference storing aid from {@link com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil#rememberNamedReferences(com.intellij.psi.PsiElement, String...)} * @@ -227,6 +216,7 @@ public abstract class MembersManager implements Function implements Function extends NotNullPredicate { - @Override - public boolean applyNotNull(@NotNull final T input) { - return input.getName() != null; - } - } - private static class FindByElement extends NotNullPredicate> { private final PyElement myPyElement; diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java index 7cba0a2a639c..6b2e0295090f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -1,7 +1,8 @@ package com.jetbrains.python.refactoring.classes.membersManager; +import com.google.common.base.Predicate; import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; +import com.google.common.collect.FluentIterable; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -35,6 +36,7 @@ class MethodsManager extends MembersManager { {PyNames.PROPERTY, PyNames.CLASSMETHOD, PyNames.STATICMETHOD}; public static final String ABC_META_PACKAGE = "abc"; + private static final NoPropertiesPredicate NO_PROPERTIES = new NoPropertiesPredicate(); MethodsManager() { super(PyFunction.class); @@ -62,8 +64,8 @@ class MethodsManager extends MembersManager { @NotNull @Override - protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { - return Lists.newArrayList(filterNameless(Arrays.asList(pyClass.getMethods()))); + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return FluentIterable.from(Arrays.asList(pyClass.getMethods())).filter(new NamelessFilter()).filter(NO_PROPERTIES).toList(); } @Override @@ -74,7 +76,7 @@ class MethodsManager extends MembersManager { final Collection methodsToAbstract = fetchElements(Collections2.filter(members, new AbstractFilter(true))); makeMethodsAbstract(methodsToAbstract, to); - return moveMethods(from, methodsToMove, to); + return moveMethods(from, methodsToMove, true, to); } /** @@ -156,9 +158,10 @@ class MethodsManager extends MembersManager { * @param from source * @param methodsToMove what to move * @param to where + * @param skipIfExist skip (do not add) if method already exists * @return newly added methods */ - private static List moveMethods(final PyClass from, final Collection methodsToMove, final PyClass... to) { + static List moveMethods(final PyClass from, final Collection methodsToMove, final boolean skipIfExist, final PyClass... to) { final List result = new ArrayList(); for (final PyClass destClass : to) { //We move copies here because there may be several destinations @@ -168,7 +171,7 @@ class MethodsManager extends MembersManager { copies.add(newMethod); } - result.addAll(PyClassRefactoringUtil.copyMethods(copies, destClass)); + result.addAll(PyClassRefactoringUtil.copyMethods(copies, destClass, skipIfExist)); } deleteElements(methodsToMove); @@ -281,4 +284,14 @@ class MethodsManager extends MembersManager { } } } + + /** + * Filter out property setters and getters + */ + private static class NoPropertiesPredicate implements Predicate { + @Override + public boolean apply(@NotNull PyFunction input) { + return input.getProperty() == null; + } + } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java new file mode 100644 index 000000000000..ec688e3f4a9c --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/NamelessFilter.java @@ -0,0 +1,21 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.intellij.psi.PsiNamedElement; +import com.jetbrains.NotNullPredicate; +import com.jetbrains.python.psi.PyElement; +import org.jetbrains.annotations.NotNull; + +/** + * Filters out named elements (ones that subclasses {@link com.intellij.psi.PsiNamedElement}) and {@link com.jetbrains.python.psi.PyElement}) + * that are null or has null name. + * You need it sometimes when code has errors (i.e. bad formatted code with annotation may treat annotation as method with null name. + * +* @author Ilya.Kazakevich +*/ +class NamelessFilter extends NotNullPredicate { + + @Override + public boolean applyNotNull(@NotNull final T input) { + return input.getName() != null; + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java new file mode 100644 index 000000000000..6cf7c0b0cd1b --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PropertiesManager.java @@ -0,0 +1,162 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.MultiMap; +import com.jetbrains.python.psi.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Plugin that moves class properties. + * It represents property (whatever old or new) as one of its methods. + * + * @author Ilya.Kazakevich + */ +class PropertiesManager extends MembersManager { + + PropertiesManager() { + super(PyElement.class); + } + + + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + final List elements = new ArrayList(pyClass.getProperties().size()); + for (final Property property : pyClass.getProperties().values()) { + elements.add(getElement(property)); + } + return elements; + } + + @NotNull + private static PyElement getElement(@NotNull final Property property) { + final Callable getter = property.getGetter().valueOrNull(); + final Callable setter = property.getSetter().valueOrNull(); + final Callable deleter = property.getDeleter().valueOrNull(); + + if (getter != null) { + return getter; + } + else if (setter != null) { + return setter; + } + else if (deleter != null) { + return deleter; + } + else { + final PyTargetExpression site = property.getDefinitionSite(); + assert site != null : "Property has no methods nor declaration. That is not property"; + return site; + } + } + + @NotNull + private static Property getProperty(@NotNull final PyClass pyClass, @NotNull final PyElement element) { + final Collection properties = pyClass.getProperties().values(); + if (element instanceof PyTargetExpression) { + return getPropertyByTargetExpression(properties, (PyTargetExpression)element); + } + if (element instanceof PyFunction) { + return getPropertyByFunction(properties, (PyFunction)element); + } + throw new IllegalArgumentException("Not function nor target"); + } + + @NotNull + private static Property getPropertyByFunction(@NotNull final Collection properties, + @NotNull final PyFunction functionToSearch) { + for (final Property property : properties) { + for (final PyFunction function : getAllFunctions(property)) { + if (function.equals(functionToSearch)) { + return property; + } + } + } + throw new IllegalArgumentException("No property found"); + } + + @NotNull + private static Property getPropertyByTargetExpression(@NotNull final Iterable properties, + @NotNull final PyTargetExpression element) { + for (final Property property : properties) { + if (element.equals(property.getDefinitionSite())) { + return property; + } + } + throw new IllegalArgumentException("No property found"); + } + + @NotNull + private static Collection getAllFunctions(@NotNull final Property property) { + final Collection result = new ArrayList(3); + final Callable getter = property.getGetter().valueOrNull(); + final Callable setter = property.getSetter().valueOrNull(); + final Callable deleter = property.getDeleter().valueOrNull(); + + if (getter instanceof PyFunction) { + result.add((PyFunction)getter); + } + if (setter instanceof PyFunction) { + result.add((PyFunction)setter); + } + if (deleter instanceof PyFunction) { + result.add((PyFunction)deleter); + } + return result; + } + + @Override + protected Collection moveMembers(@NotNull final PyClass from, + @NotNull final Collection> members, + @NotNull final PyClass... to) { + final Collection result = new ArrayList(); + + final Collection elements = fetchElements(members); + for (final PyElement element : elements) { + final Property property = getProperty(from, element); + final Collection functions = getAllFunctions(property); + MethodsManager.moveMethods(from, functions, false, to); + final PyTargetExpression definitionSite = property.getDefinitionSite(); + if (definitionSite != null) { + final PyAssignmentStatement assignmentStatement = PsiTreeUtil.getParentOfType(definitionSite, PyAssignmentStatement.class); + ClassFieldsManager.moveAssignmentsImpl(from, Collections.singleton(assignmentStatement), to); + } + } + return result; + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + return new PyMemberInfo(input, false, getName(input), false, this, false); + } + + private static String getName(@NotNull final PyElement input) { + final PyClass clazz = PsiTreeUtil.getParentOfType(input, PyClass.class); + assert clazz != null : "Element not declared in class"; + final Property property = getProperty(clazz, input); + return property.getName(); + } + + @Override + public boolean hasConflict(@NotNull final PyElement member, @NotNull final PyClass aClass) { + return false; + } + + @NotNull + @Override + protected MultiMap getDependencies(@NotNull final PyElement member) { + return new MultiMap(); + } + + @NotNull + @Override + protected Collection getDependencies(@NotNull final MultiMap usedElements) { + return Collections.emptyList(); + } +} diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java index deb8030f93c7..66cceb192a04 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java +++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalDataBase.java @@ -15,10 +15,10 @@ */ package com.jetbrains.python.remote; -import com.intellij.remotesdk2.RemoteSdkAdditionalData2; +import com.intellij.remote.RemoteSdkAdditionalData; /** * @author traff */ -public interface PyRemoteSdkAdditionalDataBase extends RemoteSdkAdditionalData2, PySkeletonsPathAware { +public interface PyRemoteSdkAdditionalDataBase extends RemoteSdkAdditionalData, PySkeletonsPathAware { } diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java index 5b5fc9b9e7e3..d9a9f04ecce2 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java +++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkCredentials.java @@ -15,7 +15,7 @@ */ package com.jetbrains.python.remote; -import com.intellij.remotesdk.RemoteSdkCredentials; +import com.intellij.remote.RemoteSdkCredentials; /** * @author yole diff --git a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java index e263e957cb3b..4276ed8cafe5 100644 --- a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java +++ b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java @@ -27,12 +27,8 @@ import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.remotesdk.RemoteCredentials; -import com.intellij.remotesdk.RemoteInterpreterException; -import com.intellij.remotesdk.RemoteSdkCredentials; -import com.intellij.remotesdk.RemoteSshProcess; -import com.intellij.remotesdk2.VagrantBasedCredentialsHolder; -import com.intellij.util.Consumer; +import com.intellij.remote.*; +import com.intellij.remote.RemoteSdkException; import com.intellij.util.NullableConsumer; import com.intellij.util.PathMappingSettings; import com.jetbrains.python.PythonHelpersLocator; @@ -59,14 +55,14 @@ public abstract class PythonRemoteInterpreterManager { @NotNull GeneralCommandLine commandLine, @Nullable PathMappingSettings mappingSettings) - throws RemoteInterpreterException; + throws RemoteSdkException; public abstract ProcessHandler startRemoteProcessWithPid(@Nullable Project project, @NotNull PyRemoteSdkCredentials data, @NotNull GeneralCommandLine commandLine, @Nullable PathMappingSettings mappingSettings) - throws RemoteInterpreterException; + throws RemoteSdkException; public abstract void addRemoteSdk(Project project, Component parentComponent, Collection existingSdks, NullableConsumer sdkCallback); @@ -77,13 +73,13 @@ public abstract class PythonRemoteInterpreterManager { String[] command, @Nullable String workingDir, boolean askForSudo) - throws RemoteInterpreterException; + throws RemoteSdkException; @NotNull public abstract RemoteSshProcess createRemoteProcess(@Nullable Project project, @NotNull RemoteSdkCredentials data, @NotNull GeneralCommandLine commandLine, boolean allocatePty) - throws RemoteInterpreterException; + throws RemoteSdkException; public abstract boolean editSdk(@NotNull Project project, @NotNull SdkModificator sdkModificator, Collection existingSdks); diff --git a/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java b/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java index 514fc2a59d8e..db2b329e1fd7 100644 --- a/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java +++ b/python/src/com/jetbrains/python/remote/RemoteDebuggableProcessHandler.java @@ -15,7 +15,7 @@ */ package com.jetbrains.python.remote; -import com.intellij.remotesdk.RemoteProcessHandlerBase; +import com.intellij.remote.RemoteProcessHandlerBase; import com.jetbrains.python.debugger.PyDebugProcess; import com.jetbrains.python.debugger.PyPositionConverter; diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java index 5941d5f345c9..673b87dfd53d 100644 --- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java +++ b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java @@ -24,10 +24,8 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; -import com.intellij.remotesdk2.RemoteSdkAdditionalData2; import com.intellij.util.PathMappingSettings; import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase; -import com.jetbrains.python.remote.PyRemoteSdkCredentials; import com.jetbrains.python.remote.PythonRemoteInterpreterManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form deleted file mode 100644 index ea6172e1faac..000000000000 --- a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.form +++ /dev/null @@ -1,81 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java index 2b6ca61f83ad..e2cfe9c36914 100644 --- a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java +++ b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java @@ -29,6 +29,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.FixedSizeButton; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; @@ -36,10 +38,12 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.LocationNameFieldsBinding; -import com.intellij.remotesdk.RemoteSdkCredentialsHolder; +import com.intellij.remote.RemoteSdkCredentialsHolder; import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.JBLabel; +import com.intellij.util.NullableConsumer; import com.intellij.util.PathUtil; import com.intellij.util.PlatformUtils; import com.jetbrains.python.packaging.PyExternalProcessException; @@ -112,8 +116,10 @@ public class CreateVirtualEnvDialog extends IdeaDialog { setupDialog(null, allSdks, suggestedBaseSdk); } - private void setupDialog(Project project, List allSdks, @Nullable Sdk suggestedBaseSdk) { + private void setupDialog(Project project, final List allSdks, @Nullable Sdk suggestedBaseSdk) { myProject = project; + layoutPanel(allSdks); + init(); setTitle("Create Virtual Environment"); Iterables.removeIf(allSdks, new Predicate() { @@ -140,16 +146,19 @@ public class CreateVirtualEnvDialog extends IdeaDialog { final VirtualFile file = VirtualEnvSdkFlavor.getDefaultLocation(); - if (file != null) + if (file != null) { myInitialPath = file.getPath(); + } else { final String savedPath = PyPackageService.getInstance().getVirtualEnvBasePath(); - if (!StringUtil.isEmptyOrSpaces(savedPath)) + if (!StringUtil.isEmptyOrSpaces(savedPath)) { myInitialPath = savedPath; + } else if (myProject != null) { final VirtualFile baseDir = myProject.getBaseDir(); - if (baseDir != null) + if (baseDir != null) { myInitialPath = baseDir.getPath(); + } } } @@ -168,6 +177,87 @@ public class CreateVirtualEnvDialog extends IdeaDialog { checkValid(); } + private void layoutPanel(final List allSdks) { + final GridBagLayout layout = new GridBagLayout(); + myMainPanel = new JPanel(layout); + + final GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(2,2,2,2); + + c.gridx = 0; + c.gridy = 0; + c.weightx = 0.0; + myMainPanel.add(new JBLabel("Name:"), c); + + c.gridx = 1; + c.gridy = 0; + c.gridwidth = 2; + c.weightx = 1.0; + myName = new JTextField(); + myMainPanel.add(myName, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 1; + c.weightx = 0.0; + myMainPanel.add(new JBLabel("Location:"), c); + + c.gridx = 1; + c.gridy = 1; + c.gridwidth = 2; + c.weightx = 1.0; + myDestination = new TextFieldWithBrowseButton(); + myMainPanel.add(myDestination, c); + + c.gridx = 0; + c.gridy = 2; + c.gridwidth = 1; + c.weightx = 0.0; + myMainPanel.add(new JBLabel("Base interpreter:"), c); + + c.gridx = 1; + c.gridy = 2; + mySdkCombo = new ComboBox(); + c.insets = new Insets(2,2,2,2); + c.weightx = 1.0; + myMainPanel.add(mySdkCombo, c); + + c.gridx = 2; + c.gridy = 2; + c.insets = new Insets(0,0,2,2); + c.weightx = 0.0; + FixedSizeButton button = new FixedSizeButton(); + button.setPreferredSize(myDestination.getButton().getPreferredSize()); + myMainPanel.add(button, c); + + c.gridx = 0; + c.gridy = 3; + c.gridwidth = 3; + c.insets = new Insets(2,2,2,2); + mySitePackagesCheckBox = new JBCheckBox("Inherit global site-packages"); + myMainPanel.add(mySitePackagesCheckBox, c); + + c.gridx = 0; + c.gridy = 4; + myMakeAvailableToAllProjectsCheckbox = new JBCheckBox("Make available to all projects"); + myMainPanel.add(myMakeAvailableToAllProjectsCheckbox, c); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + SdkConfigurationUtil.createSdk(myProject, allSdks.toArray(new Sdk[allSdks.size() - 1]), new NullableConsumer() { + @Override + public void consume(@Nullable Sdk sdk) { + if (sdk == null) return; + if (!allSdks.contains(sdk)) { + allSdks.add(sdk); + } + updateSdkList(allSdks, sdk); + } + }, false, PythonSdkType.getInstance()); + } + }); + } + private void checkValid() { final String projectName = myName.getText(); if (new File(getDestination()).exists()) { diff --git a/python/src/com/jetbrains/python/sdk/PySdkUtil.java b/python/src/com/jetbrains/python/sdk/PySdkUtil.java index 4185da7fd42c..d8a2c2f6d0a3 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkUtil.java +++ b/python/src/com/jetbrains/python/sdk/PySdkUtil.java @@ -25,8 +25,7 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.remotesdk.RemoteCredentials; -import com.intellij.remotesdk2.RemoteSdkAdditionalData2; +import com.intellij.remote.RemoteSdkAdditionalData; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NonNls; @@ -214,7 +213,7 @@ public class PySdkUtil { } public static boolean isRemote(@Nullable Sdk sdk) { - return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData2; + return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData; } public static boolean isElementInSkeletons(@NotNull final PsiElement element) { diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java index 48132c358437..3e0d4ff7e3bf 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java @@ -40,7 +40,7 @@ import java.util.Collection; import java.util.List; public class PythonSdkDetailsStep extends BaseListPopupStep { - private static DialogWrapper myMore; + private DialogWrapper myMore; private final Project myProject; private final Component myOwnerComponent; private final Sdk[] myExistingSdks; @@ -55,21 +55,20 @@ public class PythonSdkDetailsStep extends BaseListPopupStep { final Sdk[] existingSdks, DialogWrapper moreDialog, JComponent ownerComponent, final Point popupPoint, - final boolean showMore, final NullableConsumer callback) { - myMore = moreDialog; - final ListPopupStep sdkHomesStep = new PythonSdkDetailsStep(project, ownerComponent, existingSdks, showMore, callback); + + final ListPopupStep sdkHomesStep = new PythonSdkDetailsStep(project, moreDialog, ownerComponent, existingSdks, callback); final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep); popup.showInScreenCoordinates(ownerComponent, popupPoint); } public PythonSdkDetailsStep(Project project, - Component ownerComponent, + DialogWrapper moreDialog, Component ownerComponent, Sdk[] existingSdks, - boolean showMore, NullableConsumer callback) { - super(null, getAvailableOptions(showMore)); + super(null, getAvailableOptions(moreDialog != null)); myProject = project; + myMore = moreDialog; myOwnerComponent = ownerComponent; myExistingSdks = existingSdks; myCallback = callback; diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 6e8f604f2336..147c9a7c5b6f 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -51,8 +51,8 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.reference.SoftReference; -import com.intellij.remotesdk.RemoteSdkCredentials; -import com.intellij.remotesdk.RemoteSdkCredentialsHolder; +import com.intellij.remote.RemoteSdkCredentials; +import com.intellij.remote.RemoteSdkCredentialsHolder; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.NullableConsumer; @@ -282,7 +282,7 @@ public class PythonSdkType extends SdkType { final Point point = parentComponent.getMousePosition(); SwingUtilities.convertPointToScreen(point, parentComponent); PythonSdkDetailsStep - .show(project, sdkModel.getSdks(), null, parentComponent, point, false, new NullableConsumer() { + .show(project, sdkModel.getSdks(), null, parentComponent, point, new NullableConsumer() { @Override public void consume(@Nullable Sdk sdk) { if (sdk != null) { diff --git a/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java index 0ad83294398b..271afc6e8c2f 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/PyRemoteSdkFlavor.java @@ -17,7 +17,7 @@ package com.jetbrains.python.sdk.flavors; import com.google.common.collect.Lists; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.remotesdk.RemoteFile; +import com.intellij.remote.RemoteFile; import org.jetbrains.annotations.Nullable; import java.util.Collection; diff --git a/python/testData/refactoring/extractsuperclass/properties.after.py b/python/testData/refactoring/extractsuperclass/properties.after.py new file mode 100644 index 000000000000..e512d94e920d --- /dev/null +++ b/python/testData/refactoring/extractsuperclass/properties.after.py @@ -0,0 +1,27 @@ +class ToClass(object): + C = 12 + + def __init__(self): + self.a = 1 + + def _get(self): + return 1 + + def _set(self, value): + pass + + def _delete(self): + pass + + old_property = property(_get, _set, _delete) + + def foo(self): + pass + + +class FromClass(ToClass): + def __init__(self): pass + + + def lala(self): + pass \ No newline at end of file diff --git a/python/testData/refactoring/extractsuperclass/properties.before.py b/python/testData/refactoring/extractsuperclass/properties.before.py new file mode 100644 index 000000000000..3df31fe9c31f --- /dev/null +++ b/python/testData/refactoring/extractsuperclass/properties.before.py @@ -0,0 +1,22 @@ +class FromClass(object): + C = 12 + + def __init__(self): + self.a = 1 + + def _get(self): + return 1 + + def _set(self, value): + pass + + def _delete(self): + pass + + old_property = property(_get, _set, _delete) + + def foo(self): + pass + + def lala(self): + pass \ No newline at end of file diff --git a/python/testData/refactoring/pullup/presenter/file.py b/python/testData/refactoring/pullup/presenter/file.py index cb6ca9511209..04eecf38db15 100644 --- a/python/testData/refactoring/pullup/presenter/file.py +++ b/python/testData/refactoring/pullup/presenter/file.py @@ -30,12 +30,36 @@ class BadMro(MainParent, object, SubParent1, SubParent2): pass class HugeChild(SubParent1, date): #SubParent1 is disabled + __metaclass__ = None # Anyway, this field should be ignored and processed separately as "metaclass", not "class field" + def __init__(self): self.instance_field_1 = 42 self.instance_field_2 = 100500 CLASS_FIELD = 42 (CLASS_FIELD_A,CLASS_FIELD_B) = (42,100500) #We do not support tuples in class assignments for now (see ClassFieldsManager) + + def _set(self, val): # Should not be treated as method (part of property) + pass + + def _get(self): # Should not be treated as method (part of property) + return None + + name = property(fget=_get, fset=_set) + + + @property + def some_property(self): # Should not be treated as method (part of property) + return None + + @some_property.setter + def some_property(self, val): # Should not be treated as method (part of property) + pass + + + + + def foo(self): #should be disabled pass def bar(self): diff --git a/python/testData/refactoring/pullup/properties/Class.after.py b/python/testData/refactoring/pullup/properties/Class.after.py new file mode 100644 index 000000000000..1291238ed082 --- /dev/null +++ b/python/testData/refactoring/pullup/properties/Class.after.py @@ -0,0 +1,19 @@ +from SuperClass import SuperClass + + +class AnyClass(SuperClass): + C = 1 + + def __init__(self): + super(AnyClass, self).__init__() + + + + + + + + + def foo(self): + pass + diff --git a/python/testData/refactoring/pullup/properties/Class.py b/python/testData/refactoring/pullup/properties/Class.py new file mode 100644 index 000000000000..5a091a9bd934 --- /dev/null +++ b/python/testData/refactoring/pullup/properties/Class.py @@ -0,0 +1,25 @@ +from SuperClass import SuperClass + + +class AnyClass(SuperClass): + C = 1 + + def __init__(self): + super(AnyClass, self).__init__() + + + @property + def new_property(self): + return 1 + + @new_property.setter + def new_property(self, value): + pass + + @new_property.deleter + def new_property(self): + pass + + def foo(self): + pass + diff --git a/python/testData/refactoring/pullup/properties/SuperClass.after.py b/python/testData/refactoring/pullup/properties/SuperClass.after.py new file mode 100644 index 000000000000..1b2be8de00a9 --- /dev/null +++ b/python/testData/refactoring/pullup/properties/SuperClass.after.py @@ -0,0 +1,15 @@ +class SuperClass(object): + def __init__(self): + pass + + @property + def new_property(self): + return 1 + + @new_property.setter + def new_property(self, value): + pass + + @new_property.deleter + def new_property(self): + pass diff --git a/python/testData/refactoring/pullup/properties/SuperClass.py b/python/testData/refactoring/pullup/properties/SuperClass.py new file mode 100644 index 000000000000..a41b8fdc7db1 --- /dev/null +++ b/python/testData/refactoring/pullup/properties/SuperClass.py @@ -0,0 +1,3 @@ +class SuperClass(object): + def __init__(self): + pass diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java index 13d5b4d4f253..c96bdc2397e1 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java @@ -125,6 +125,11 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { doSimpleTest("FromClass", "ToClass", null, true, "#instance_field", "#CLASS_FIELD"); } + + public void testProperties() throws Exception { + doSimpleTest("FromClass", "ToClass", null, true, "#C", "#a", "._get", ".foo"); + } + private void doSimpleTest(final String className, final String superclassName, final String expectedError, diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java index ee5371cf24b4..1ee20d27f62a 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java @@ -144,7 +144,9 @@ public class PyPullUpPresenterTest extends PyRefactoringPresenterTestCase(result[0], ArrayUtil.toObjectArray(deps));