From dec36415af0f183e43f26cf687e299b4f56df3ae Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Thu, 6 Oct 2016 16:15:12 +0300 Subject: [PATCH] PY-17447 PyRemoteDebugSessionCreator extension point with PyDockerDebugSessionCreator implementation that uses new Python debugger connection strategy introduced --- python/src/META-INF/python-core-common.xml | 1 + .../python/debugger/PyDebugRunner.java | 53 ++++++++++++------ .../debugger/PyRemoteDebugSessionCreator.java | 56 +++++++++++++++++++ 3 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml index 7c2d825b4d07..847c415fe0fa 100644 --- a/python/src/META-INF/python-core-common.xml +++ b/python/src/META-INF/python-core-common.xml @@ -630,6 +630,7 @@ + diff --git a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java index 4418b39b293a..8ffa7a88e38f 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java @@ -33,6 +33,7 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.remote.RemoteSdkAdditionalData; import com.intellij.xdebugger.XDebugProcess; import com.intellij.xdebugger.XDebugProcessStarter; import com.intellij.xdebugger.XDebugSession; @@ -69,6 +70,7 @@ public class PyDebugRunner extends GenericProgramRunner { public static final String PORT_PARAM = "--port"; public static final String FILE_PARAM = "--file"; public static final String MODULE_PARAM = "--module"; + public static final String MULTIPROCESS_PARAM = "--multiprocess"; public static final String IDE_PROJECT_ROOTS = "IDE_PROJECT_ROOTS"; public static final String LIBRARY_ROOTS = "LIBRARY_ROOTS"; public static final String PYTHON_ASYNCIO_DEBUG = "PYTHONASYNCIODEBUG"; @@ -121,6 +123,16 @@ public class PyDebugRunner extends GenericProgramRunner { FileDocumentManager.getInstance().saveAllDocuments(); final PythonCommandLineState pyState = (PythonCommandLineState)state; + + Sdk sdk = pyState.getSdk(); + if (sdk != null && sdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData) { + RemoteSdkAdditionalData remoteSdkAdditionalData = (RemoteSdkAdditionalData)sdk.getSdkAdditionalData(); + PyRemoteDebugSessionCreator sessionCreator = PyRemoteDebugSessionCreator.findExtension(remoteSdkAdditionalData); + if (sessionCreator != null) { + return sessionCreator.createSession(this, pyState, environment); + } + } + final ServerSocket serverSocket = PythonCommandLineState.createServerSocket(); final int serverLocalPort = serverSocket.getLocalPort(); RunProfile profile = environment.getRunProfile(); @@ -215,7 +227,7 @@ public class PyDebugRunner extends GenericProgramRunner { } @Nullable - private static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) { + public static CommandLinePatcher createRunConfigPatcher(RunProfileState state, RunProfile profile) { CommandLinePatcher runConfigPatcher = null; if (state instanceof PythonCommandLineState && profile instanceof AbstractPythonRunConfiguration) { runConfigPatcher = (AbstractPythonRunConfiguration)profile; @@ -283,10 +295,10 @@ public class PyDebugRunner extends GenericProgramRunner { } private void fillDebugParameters(@NotNull Project project, - @NotNull ParamsGroup debugParams, - int serverLocalPort, - @NotNull PythonCommandLineState pyState, - @NotNull GeneralCommandLine cmd) { + @NotNull ParamsGroup debugParams, + int serverLocalPort, + @NotNull PythonCommandLineState pyState, + @NotNull GeneralCommandLine cmd) { PythonHelper.DEBUGGER.addToGroup(debugParams, cmd); configureDebugParameters(project, debugParams, pyState, cmd); @@ -294,14 +306,7 @@ public class PyDebugRunner extends GenericProgramRunner { configureDebugEnvironment(project, cmd.getEnvironment()); - final String[] debuggerArgs = new String[]{ - CLIENT_PARAM, "127.0.0.1", - PORT_PARAM, String.valueOf(serverLocalPort), - FILE_PARAM - }; - for (String s : debuggerArgs) { - debugParams.addParameter(s); - } + configureDebugConnectionParameters(debugParams, serverLocalPort); } public static void configureDebugEnvironment(@NotNull Project project, Map environment) { @@ -324,14 +329,19 @@ public class PyDebugRunner extends GenericProgramRunner { } protected void configureDebugParameters(@NotNull Project project, - @NotNull ParamsGroup debugParams, - @NotNull PythonCommandLineState pyState, - @NotNull GeneralCommandLine cmd) { + @NotNull ParamsGroup debugParams, + @NotNull PythonCommandLineState pyState, + @NotNull GeneralCommandLine cmd) { if (pyState.isMultiprocessDebug()) { //noinspection SpellCheckingInspection debugParams.addParameter("--multiproc"); } + configureCommonDebugParameters(project, debugParams); + } + + public static void configureCommonDebugParameters(@NotNull Project project, + @NotNull ParamsGroup debugParams) { if (isModule) { debugParams.addParameter("--module"); } @@ -349,6 +359,17 @@ public class PyDebugRunner extends GenericProgramRunner { } } + private static void configureDebugConnectionParameters(@NotNull ParamsGroup debugParams, int serverLocalPort) { + final String[] debuggerArgs = new String[]{ + CLIENT_PARAM, "127.0.0.1", + PORT_PARAM, String.valueOf(serverLocalPort), + FILE_PARAM + }; + for (String s : debuggerArgs) { + debugParams.addParameter(s); + } + } + private static void addProjectRootsToEnv(@NotNull Project project, @NotNull Map environment) { List roots = Lists.newArrayList(); diff --git a/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java b/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java new file mode 100644 index 000000000000..3c9c6c8640b4 --- /dev/null +++ b/python/src/com/jetbrains/python/debugger/PyRemoteDebugSessionCreator.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2016 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.jetbrains.python.debugger; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.remote.RemoteSdkAdditionalData; +import com.intellij.xdebugger.XDebugSession; +import com.jetbrains.python.run.PythonCommandLineState; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Alexander Koshevoy + */ +public abstract class PyRemoteDebugSessionCreator { + public static final ExtensionPointName EP_NAME + = ExtensionPointName.create("Pythonid.pyRemoteDebugSessionCreator"); + + protected abstract boolean appliesTo(@NotNull RemoteSdkAdditionalData remoteSdkAdditionalData); + + @NotNull + public abstract XDebugSession createSession(@NotNull PyDebugRunner runner, + @NotNull PythonCommandLineState state, + @NotNull ExecutionEnvironment environment) + throws ExecutionException; + + @Contract("null -> null") + @Nullable + public static PyRemoteDebugSessionCreator findExtension(@Nullable RemoteSdkAdditionalData remoteSdkAdditionalData) { + if (remoteSdkAdditionalData == null) { + return null; + } + for (PyRemoteDebugSessionCreator sessionCreator : EP_NAME.getExtensions()) { + if (sessionCreator.appliesTo(remoteSdkAdditionalData)) { + return sessionCreator; + } + } + return null; + } +}