diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py
index 16704fb68287..9dea2f0f1f5a 100644
--- a/python/helpers/generator3.py
+++ b/python/helpers/generator3.py
@@ -1,5 +1,4 @@
# encoding: utf-8
-import re
"""
This thing tries to restore public interface of objects that don't have a python
source: C extensions and built-in objects. It does not reimplement the
@@ -24,6 +23,7 @@ import os
import string
import stat
import types
+import atexit
#import __builtin__
try:
@@ -33,6 +33,9 @@ except ImportError:
import re
+if sys.platform == 'cli':
+ import clr
+
string_mod = string
version = (
@@ -161,6 +164,31 @@ def sortedNoCase(p_array):
return p_array
+def cleanup(value):
+ result = ''
+ for c in value:
+ if c == '\n': result += '\\n'
+ elif c == '\r': result += '\\r'
+ elif c < ' ' or c > chr(127): result += '?'
+ else: result += c
+ return result
+
+# http://blogs.msdn.com/curth/archive/2009/03/29/an-ironpython-profiler.aspx
+def print_profile():
+ data = []
+ data.extend(clr.GetProfilerData())
+ data.sort(lambda x, y: -cmp(x.InclusiveTime, y.InclusiveTime))
+ for p in data:
+ print '%s\t%d\t%d\t%d' % (p.Name, p.InclusiveTime, p.ExclusiveTime, p.Calls)
+
+def is_clr_type(t):
+ if not t: return False
+ try:
+ clr.GetClrType(t)
+ return True
+ except TypeError:
+ return False
+
_prop_types = [type(property())]
try: _prop_types.append(types.GetSetDescriptorType)
except: pass
@@ -613,7 +641,7 @@ class ModuleRedeclarator(object):
else:
# a forward / circular declaration happens
notice = ""
- s = repr(p_value)
+ s = cleanup(repr(p_value))
if found_name:
if found_name == as_name:
notice = " # (!) real value is " + s
@@ -739,6 +767,27 @@ class ModuleRedeclarator(object):
spec.append("**" + kwarg)
return flatten(spec)
+ def restoreClr(self, p_func, p_name, p_class):
+ """Restore the function signature by the CLR type signature"""
+ clr_type = clr.GetClrType(p_class)
+ if p_name == '__new__':
+ methods = clr_type.GetConstructors()
+ if not methods:
+ return p_name + '(*args) # could not find CLR constructor'
+ else:
+ methods = [m for m in clr_type.GetMethods() if m.Name == p_name]
+ if not methods:
+ return p_name + '(*args) # could not find CLR method'
+ method = methods[0]
+ for overload in methods[1:]:
+ if len(overload.GetParameters()) < len(method.GetParameters()): method = overload
+ params = [p.Name for p in method.GetParameters()]
+ if not method.IsStatic:
+ params = ['self'] + params
+ if len(methods) > 1:
+ params.append("*___args")
+ return p_name + '(' + ', '.join(params) + ')'
+
def redoFunction(self, p_func, p_name, indent, p_class=None, p_modname=None):
"""
Restore function argument list as best we can.
@@ -771,6 +820,7 @@ class ModuleRedeclarator(object):
#self.out("@staticmethod # known case of __new__", indent)
deco = "staticmethod"
deco_comment = " # known case of __new__"
+
if deco and HAS_DECORATORS:
self.out("@" + deco + deco_comment, indent)
if inspect and inspect.isfunction(p_func):
@@ -780,7 +830,10 @@ class ModuleRedeclarator(object):
spec, sig_note = self.restorePredefinedBuiltin(classname, p_name)
self.out("def " + spec + ": # " + sig_note, indent)
self.outDocAttr(p_func, indent+1, p_class)
-
+ elif sys.platform == 'cli' and is_clr_type(p_class):
+ spec = self.restoreClr(p_func, p_name, p_class)
+ self.out("def " + spec + ":", indent)
+ self.outDocAttr(p_func, indent+1, p_class)
else:
# __doc__ is our best source of arglist
sig_note = "real signature unknown"
@@ -1042,8 +1095,10 @@ if __name__ == "__main__":
-q -- quiet, do not print anything on stdout. Errors still go to stderr.
-u -- update, only recreate skeletons for newer files, and skip unchanged.
-x -- die on exceptions with a stacktrace; only for debugging.
+ -c modules -- import CLR assemblies with specified names
+ -p -- run CLR profiler
"""
- opts, fnames = getopt(sys.argv[1:], "d:hbqux")
+ opts, fnames = getopt(sys.argv[1:], "d:hbquxc:p")
opts = dict(opts)
if not opts or '-h' in opts:
print(helptext)
@@ -1066,6 +1121,18 @@ if __name__ == "__main__":
names.remove('__main__') # we don't want ourselves processed
else:
doing_builtins = False
+
+ if sys.platform == 'cli':
+ refs = opts.get('-c', '')
+ if refs:
+ for ref in refs.split(';'): clr.AddReferenceByPartialName(ref)
+
+ if '-p' in opts:
+ atexit.register(print_profile)
+
+ from System import DateTime
+ start = DateTime.Now
+
# go on
for name in names:
if not quiet:
@@ -1126,3 +1193,6 @@ if __name__ == "__main__":
raise
else:
continue
+
+ if sys.platform == 'cli':
+ print "Generation completed in " + str((DateTime.Now - start).TotalMilliseconds) + " ms"
diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py
new file mode 100644
index 000000000000..0e72d63d024d
--- /dev/null
+++ b/python/helpers/pydev/pydevconsole.py
@@ -0,0 +1,225 @@
+try:
+ from code import InteractiveConsole
+except ImportError:
+ from pydevconsole_code_for_ironpython import InteractiveConsole
+
+import os
+import sys
+
+try:
+ False
+ True
+except NameError: # version < 2.3 -- didn't have the True/False builtins
+ import __builtin__
+ setattr(__builtin__, 'True', 1) #Python 3.0 does not accept __builtin__.True = 1 in its syntax
+ setattr(__builtin__, 'False', 0)
+
+try:
+ try:
+ import xmlrpclib
+ except ImportError:
+ import xmlrpc.client as xmlrpclib
+except ImportError:
+ import _pydev_xmlrpclib as xmlrpclib
+
+#=======================================================================================================================
+# StdIn
+#=======================================================================================================================
+class StdIn:
+ '''
+ Object to be added to stdin (to emulate it as non-blocking while the next line arrives)
+ '''
+
+ def __init__(self, interpreter, host, client_port):
+ self.interpreter = interpreter
+ self.client_port = client_port
+ self.host = host
+
+ def readline(self, *args, **kwargs): #@UnusedVariable
+ #Ok, callback into the client to see get the new input
+ server = xmlrpclib.Server('http://%s:%s' % (self.host, self.client_port))
+ return server.RequestInput()
+
+ def isatty(self):
+ return False #not really a file
+
+ def write(self, *args, **kwargs):
+ pass #not available StdIn (but it can be expected to be in the stream interface)
+
+ def flush(self, *args, **kwargs):
+ pass #not available StdIn (but it can be expected to be in the stream interface)
+
+ #in the interactive interpreter, a read and a readline are the same.
+ read = readline
+
+#=======================================================================================================================
+# InterpreterInterface
+#=======================================================================================================================
+class InterpreterInterface:
+ '''
+ The methods in this class should be registered in the xml-rpc server.
+ '''
+
+ def __init__(self, host, client_port):
+ self.client_port = client_port
+ self.host = host
+ self.namespace = {}
+ self.interpreter = InteractiveConsole(self.namespace)
+
+
+ def addExec(self, line):
+ #f_opened = open('c:/temp/a.txt', 'a')
+ #f_opened.write(line+'\n')
+
+ original_in = sys.stdin
+ try:
+ help = None
+ if 'pydoc' in sys.modules:
+ pydoc = sys.modules['pydoc'] #Don't import it if it still is not there.
+
+
+ if hasattr(pydoc, 'help'):
+ #You never know how will the API be changed, so, let's code defensively here
+ help = pydoc.help
+ if not hasattr(help, 'input'):
+ help = None
+ except:
+ #Just ignore any error here
+ pass
+
+ sys.stdin = StdIn(self, self.host, self.client_port)
+ if help is not None:
+ #This will enable the help() function to work.
+ help.input = sys.stdin
+
+ try:
+ more = self.interpreter.push(line)
+ finally:
+ if help is not None:
+ help.input = original_in
+
+ sys.stdin = original_in
+
+ #it's always false at this point
+ need_input = False
+ return more, need_input
+
+
+ def getCompletions(self, text):
+ from _completer import Completer
+ completer = Completer(self.namespace, None)
+ return completer.complete(text)
+
+
+ def getDescription(self, text):
+ obj = None
+ if '.' not in text:
+ try:
+ obj = self.namespace[text]
+ except KeyError:
+ return ''
+
+ else:
+ try:
+ splitted = text.split('.')
+ obj = self.namespace[splitted[0]]
+ for t in splitted[1:]:
+ obj = getattr(obj, t)
+ except:
+ return ''
+
+
+ if obj is not None:
+ try:
+ if sys.platform.startswith("java"):
+ #Jython
+ doc = obj.__doc__
+ if doc is not None:
+ return doc
+
+ import jyimportsTipper
+ is_method, infos = jyimportsTipper.ismethod(obj)
+ ret = ''
+ if is_method:
+ for info in infos:
+ ret += info.getAsDoc()
+ return ret
+
+ else:
+ #Python and Iron Python
+ import inspect #@UnresolvedImport
+ doc = inspect.getdoc(obj)
+ if doc is not None:
+ return doc
+ except:
+ pass
+
+ try:
+ #if no attempt succeeded, try to return repr()...
+ return repr(obj)
+ except:
+ try:
+ #otherwise the class
+ return str(obj.__class__)
+ except:
+ #if all fails, go to an empty string
+ return ''
+
+
+ def close(self):
+ sys.exit(0)
+
+
+
+#=======================================================================================================================
+# _DoExit
+#=======================================================================================================================
+def _DoExit(*args):
+ '''
+ We have to override the exit because calling sys.exit will only actually exit the main thread,
+ and as we're in a Xml-rpc server, that won't work.
+ '''
+
+ try:
+ import java.lang.System
+ java.lang.System.exit(1)
+ except ImportError:
+ if len(args) == 1:
+ os._exit(args[0])
+ else:
+ os._exit(0)
+
+#=======================================================================================================================
+# StartServer
+#=======================================================================================================================
+def StartServer(host, port, client_port):
+ #replace exit (see comments on method)
+ #note that this does not work in jython!!! (sys method can't be replaced).
+ sys.exit = _DoExit
+
+ try:
+ try:
+ from SimpleXMLRPCServer import SimpleXMLRPCServer
+ except ImportError:
+ from xmlrpc.server import SimpleXMLRPCServer
+ except ImportError:
+ from _pydev_SimpleXMLRPCServer import SimpleXMLRPCServer
+
+ interpreter = InterpreterInterface(host, client_port)
+ server = SimpleXMLRPCServer((host, port), logRequests=False)
+
+ server.register_function(interpreter.addExec)
+ server.register_function(interpreter.getCompletions)
+ server.register_function(interpreter.getDescription)
+ server.register_function(interpreter.close)
+
+ server.serve_forever()
+
+
+#=======================================================================================================================
+# main
+#=======================================================================================================================
+if __name__ == '__main__':
+ port, client_port = sys.argv[1:3]
+ StartServer('localhost', int(port), int(client_port))
+
diff --git a/python/python.iml b/python/python.iml
index 2eed16a30183..85eba30f20b6 100644
--- a/python/python.iml
+++ b/python/python.iml
@@ -37,6 +37,7 @@
+
diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml
index ace147507f09..198e8a08a20e 100644
--- a/python/src/META-INF/python-plugin-common.xml
+++ b/python/src/META-INF/python-plugin-common.xml
@@ -316,6 +316,11 @@
text="Run Python Console..." description="Allows to quickly run Python console">
+
+
+
diff --git a/python/src/com/jetbrains/python/actions/GenerateBinaryStubsFix.java b/python/src/com/jetbrains/python/actions/GenerateBinaryStubsFix.java
new file mode 100644
index 000000000000..a95bc63073a5
--- /dev/null
+++ b/python/src/com/jetbrains/python/actions/GenerateBinaryStubsFix.java
@@ -0,0 +1,111 @@
+package com.jetbrains.python.actions;
+
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyImportReferenceImpl;
+import com.jetbrains.python.sdk.IronPythonSdkFlavor;
+import com.jetbrains.python.sdk.PythonSdkFlavor;
+import com.jetbrains.python.sdk.PythonSdkType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public class GenerateBinaryStubsFix implements LocalQuickFix {
+ private String myQualifiedName;
+ private Sdk mySdk;
+
+ public GenerateBinaryStubsFix(PsiReference reference) {
+ myQualifiedName = getReferenceText(reference);
+ mySdk = getPythonSdk(reference);
+ }
+
+ private static String getReferenceText(PsiReference reference) {
+ PsiElement element = reference.getElement();
+ while (element.getParent() instanceof PyReferenceExpression) {
+ element = element.getParent();
+ }
+ return element.getText();
+ }
+
+ @NotNull
+ public String getName() {
+ return "Generate stubs for binary module " + myQualifiedName;
+ }
+
+ @NotNull
+ public String getFamilyName() {
+ return "GenerateBinaryStubs";
+ }
+
+ public void applyFix(@NotNull Project project, @NotNull final ProblemDescriptor descriptor) {
+ ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+ public void run() {
+ List assemblyRefs = collectAssemblyReferences(descriptor.getPsiElement().getContainingFile());
+ final String skeletonPath = PythonSdkType.findSkeletonsPath(mySdk);
+ PythonSdkType.generateSkeleton(mySdk.getHomePath(), skeletonPath, myQualifiedName, assemblyRefs);
+ final VirtualFile skeletonDir = LocalFileSystem.getInstance().findFileByPath(skeletonPath);
+ if (skeletonDir != null) {
+ skeletonDir.refresh(true, true);
+ }
+ }
+ }, "Generating stubs for binary module", false, project);
+ }
+
+ private List collectAssemblyReferences(PsiFile file) {
+ if (!(PythonSdkFlavor.getFlavor(mySdk.getHomePath()) instanceof IronPythonSdkFlavor)) {
+ return Collections.emptyList();
+ }
+ final List result = new ArrayList();
+ file.accept(new PyRecursiveElementVisitor() {
+ @Override
+ public void visitPyCallExpression(PyCallExpression node) {
+ super.visitPyCallExpression(node);
+ if (node.isCalleeText("AddReference") || node.isCalleeText("AddReferenceByPartialName")) {
+ final PyExpression[] args = node.getArguments();
+ if (args.length == 1 && args [0] instanceof PyStringLiteralExpression) {
+ result.add(((PyStringLiteralExpression) args [0]).getStringValue());
+ }
+ }
+ }
+ });
+ return result;
+ }
+
+ public static boolean isApplicable(PsiReference ref) {
+ if (!(ref instanceof PyImportReferenceImpl)) {
+ return false;
+ }
+ final Sdk sdk = getPythonSdk(ref);
+ if (sdk == null) {
+ return false;
+ }
+ final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(sdk.getHomePath());
+ if (flavor instanceof IronPythonSdkFlavor) {
+ return getReferenceText(ref).contains("System");
+ }
+ return false;
+ }
+
+ @Nullable
+ private static Sdk getPythonSdk(PsiReference ref) {
+ final Module module = ModuleUtil.findModuleForPsiElement(ref.getElement());
+ return module == null ? null : PythonSdkType.findPythonSdk(module);
+ }
+}
diff --git a/python/src/com/jetbrains/python/actions/TransformClassicClassQuickFix.java b/python/src/com/jetbrains/python/actions/TransformClassicClassQuickFix.java
index 68251120da4f..7a5a45ccad66 100644
--- a/python/src/com/jetbrains/python/actions/TransformClassicClassQuickFix.java
+++ b/python/src/com/jetbrains/python/actions/TransformClassicClassQuickFix.java
@@ -4,9 +4,9 @@ import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyNames;
-import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElementGenerator;
import com.jetbrains.python.psi.PyExpression;
@@ -31,7 +31,8 @@ public class TransformClassicClassQuickFix implements LocalQuickFix {
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement psiElement = descriptor.getPsiElement();
- if (psiElement instanceof PyClass) {
+ psiElement = PsiTreeUtil.getParentOfType(psiElement, PyClass.class);
+ if (psiElement != null) {
PyClass pyClass = (PyClass) psiElement;
PyExpression[] superClassExpressions = pyClass.getSuperClassExpressions();
PyElementGenerator generator = PyElementGenerator.getInstance(project);
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PySplitIfIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PySplitIfIntention.java
index af9bbcb96a74..3a552ea9294c 100644
--- a/python/src/com/jetbrains/python/codeInsight/intentions/PySplitIfIntention.java
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/PySplitIfIntention.java
@@ -9,7 +9,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyTokenTypes;
-import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -53,27 +52,12 @@ public class PySplitIfIntention extends BaseIntentionAction {
}
PyIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PyIfStatement.class);
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
- StringBuilder builder = new StringBuilder();
-
- builder.append("if ").append(element.getLeftExpression().getText()).append(":\n");
- builder.append(" if ").append(element.getRightExpression().getText()).append(":");
- appendStatements(ifStatement.getIfPart().getStatementList(), builder);
- final PyIfPart[] elifParts = ifStatement.getElifParts();
- for (PyIfPart elifPart: elifParts) {
- builder.append("\n elif ").append(elifPart.getCondition().getText()).append(":");
- appendStatements(elifPart.getStatementList(), builder);
- }
- final PyElsePart elsePart = ifStatement.getElsePart();
- if (elsePart != null) {
- builder.append("\n else:");
- appendStatements(elsePart.getStatementList(), builder);
- }
- ifStatement.getIfPart().replace(elementGenerator.createFromText(PyIfStatement.class, builder.toString()));
- }
-
- private static void appendStatements(PyStatementList statementList, StringBuilder builder) {
- for (PyStatement statement : statementList.getStatements()) {
- builder.append("\n ").append(statement.getText());
- }
+
+ PyIfStatement subIf = (PyIfStatement) ifStatement.copy();
+ subIf.getIfPart().getCondition().replace(element.getRightExpression());
+ ifStatement.getIfPart().getCondition().replace(element.getLeftExpression());
+ PyStatementList statementList = elementGenerator.createFromText(PyIfStatement.class, "if a:\n a = 1").getIfPart().getStatementList();
+ statementList.getStatements()[0].replace(subIf);
+ ifStatement.getIfPart().getStatementList().replace(statementList);
}
}
diff --git a/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java b/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java
index 9dc63061fe4f..087ffbfb3812 100644
--- a/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java
+++ b/python/src/com/jetbrains/python/console/PyConsoleProcessHandler.java
@@ -4,6 +4,7 @@ import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.process.ColoredProcessHandler;
import com.intellij.execution.process.ConsoleHighlighter;
import com.intellij.execution.process.OSProcessHandler;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -19,16 +20,16 @@ import java.util.regex.Pattern;
/**
* @author oleg
*/
-class PyConsoleProcessHandler extends OSProcessHandler {
- private final PyConsoleRunner myPyConsoleRunner;
+public class PyConsoleProcessHandler extends OSProcessHandler {
private final Charset myCharset;
+ private final LanguageConsoleImpl myLanguageConsole;
- public PyConsoleProcessHandler(final PyConsoleRunner pyConsoleRunner,
- final Process process,
+ public PyConsoleProcessHandler(final Process process,
+ final LanguageConsoleImpl languageConsole,
final String commandLine,
final Charset charset) {
super(process, commandLine);
- myPyConsoleRunner = pyConsoleRunner;
+ myLanguageConsole = languageConsole;
myCharset = charset;
}
@@ -60,27 +61,31 @@ class PyConsoleProcessHandler extends OSProcessHandler {
@Override
public void notifyTextAvailable(final String text, final Key attributes) {
- final LanguageConsoleImpl languageConsole = myPyConsoleRunner.getLanguageConsole();
- String string = processPrompts(languageConsole, StringUtil.convertLineSeparators(text));
+ String string = processPrompts(myLanguageConsole, StringUtil.convertLineSeparators(text));
+ processOutput(myLanguageConsole, string, attributes);
+ }
+ public static void processOutput(LanguageConsoleImpl console, String string, final Key attributes) {
+ final ConsoleViewContentType type =
+ attributes == ProcessOutputTypes.STDERR ? ConsoleViewContentType.ERROR_OUTPUT : ConsoleViewContentType.NORMAL_OUTPUT;
// Highlight output by pattern
Matcher matcher;
while ((matcher = CODE_ELEMENT_PATTERN.matcher(string)).find()) {
- printToConsole(languageConsole, string.substring(0, matcher.start()), ConsoleViewContentType.NORMAL_OUTPUT);
+ printToConsole(console, string.substring(0, matcher.start()), type);
// Number group
if (matcher.group(1) != null) {
- printToConsole(languageConsole, matcher.group(1), NUMBER_ATTRIBUTES);
+ printToConsole(console, matcher.group(1), NUMBER_ATTRIBUTES);
}
// String group
else if (matcher.group(6) != null) {
- printToConsole(languageConsole, matcher.group(6), STRING_ATTRIBUTES);
+ printToConsole(console, matcher.group(6), STRING_ATTRIBUTES);
}
else {
- printToConsole(languageConsole, matcher.group(), ConsoleViewContentType.NORMAL_OUTPUT);
+ printToConsole(console, matcher.group(), type);
}
string = string.substring(matcher.end());
}
- printToConsole(languageConsole, string, ConsoleViewContentType.NORMAL_OUTPUT);
+ printToConsole(console, string, type);
}
private String processPrompts(final LanguageConsoleImpl languageConsole, String string) {
@@ -119,7 +124,7 @@ class PyConsoleProcessHandler extends OSProcessHandler {
final TextAttributes attributes = TextAttributes.merge(type.getAttributes(), ConsoleHighlighter.OUT.getDefaultAttributes());
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
- console.addToHistory(string, attributes);
+ console.printToHistory(string, attributes);
}
}, ModalityState.stateForComponent(console.getComponent()));
}
diff --git a/python/src/com/jetbrains/python/console/PyConsoleRunner.java b/python/src/com/jetbrains/python/console/PyConsoleRunner.java
index 2995a323f530..62f897df9fbd 100644
--- a/python/src/com/jetbrains/python/console/PyConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PyConsoleRunner.java
@@ -7,16 +7,11 @@ import com.intellij.execution.ExecutionManager;
import com.intellij.execution.Executor;
import com.intellij.execution.ExecutorRegistry;
import com.intellij.execution.console.LanguageConsoleImpl;
-import com.intellij.execution.console.LanguageConsoleViewImpl;
-import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
-import com.intellij.execution.filters.Filter;
import com.intellij.execution.process.*;
import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.execution.ui.RunContentManager;
import com.intellij.execution.ui.actions.CloseAction;
import com.intellij.ide.CommonActionsManager;
-import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
@@ -38,16 +33,10 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.PsiFile;
-import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentFactory;
import com.intellij.util.PairProcessor;
import com.jetbrains.django.run.ExecutionHelper;
import com.jetbrains.django.run.Runner;
-import com.jetbrains.django.util.DjangoUtil;
-import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.psi.LanguageLevel;
-import com.jetbrains.python.psi.PyUtil;
-import com.jetbrains.python.psi.types.PyModuleType;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -67,17 +56,17 @@ public class PyConsoleRunner {
private final String myConsoleTitle;
private OSProcessHandler myProcessHandler;
- private final CommandLineArgumentsProvider myProvider;
- private final String myWorkingDir;
+ protected final CommandLineArgumentsProvider myProvider;
+ protected final String myWorkingDir;
- private PyLanguageConsoleView myConsoleView;
+ protected PyLanguageConsoleView myConsoleView;
private final ConsoleHistoryModel myHistory = new ConsoleHistoryModel();
private AnAction myRunAction;
- private PyConsoleRunner(@NotNull final Project project,
+ public PyConsoleRunner(@NotNull final Project project,
@NotNull final String consoleTitle,
@NotNull final CommandLineArgumentsProvider provider,
- @Nullable final String workingDir) throws ExecutionException {
+ @Nullable final String workingDir) {
myProject = project;
myConsoleTitle = consoleTitle;
myProvider = provider;
@@ -88,40 +77,27 @@ public class PyConsoleRunner {
@NotNull final String consoleTitle,
@NotNull final CommandLineArgumentsProvider provider,
@Nullable final String workingDir) {
+
+ final PyConsoleRunner consoleRunner = new PyConsoleRunner(project, consoleTitle, provider, workingDir);
try {
- final PyConsoleRunner consoleRunner = createRunner(project, consoleTitle, provider, workingDir);
- initAndRun(consoleRunner);
+ consoleRunner.initAndRun();
}
catch (ExecutionException e) {
ExecutionHelper.showErrors(project, Arrays.asList(e), consoleTitle, null);
}
}
- @NotNull
- public static PyConsoleRunner createRunner(@NotNull final Project project,
- @NotNull final String consoleTitle,
- @NotNull final CommandLineArgumentsProvider provider,
- @Nullable final String workingDir) throws ExecutionException {
- return new PyConsoleRunner(project, consoleTitle, provider, workingDir);
- }
-
- public static void initAndRun(@NotNull final PyConsoleRunner runner) throws ExecutionException {
- runner.init();
- runner.doRun();
- }
-
- private void init() throws ExecutionException {
-// add holder created
- final Process process = Runner.createProcess(myWorkingDir, true, myProvider.getAdditionalEnvs(), myProvider.getArguments());
-
- final Charset outputEncoding = EncodingManager.getInstance().getDefaultCharset();
- myProcessHandler = new PyConsoleProcessHandler(this, process, getProviderCommandLine(), outputEncoding);
-
- ProcessTerminatedListener.attach(myProcessHandler);
+ public void initAndRun() throws ExecutionException {
+ // Create Server process
+ final Process process = createProcess();
// Init console view
myConsoleView = new PyLanguageConsoleView(myProject, myConsoleTitle);
+ myProcessHandler = createProcessHandler(process);
+
+ ProcessTerminatedListener.attach(myProcessHandler);
+
// Set language level
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final Sdk pythonSdk = PythonSdkType.findPythonSdk(module);
@@ -138,7 +114,7 @@ public class PyConsoleRunner {
break;
}
}
-
+
myProcessHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
@@ -191,6 +167,19 @@ public class PyConsoleRunner {
IdeFocusManager.getInstance(myProject).requestFocus(getLanguageConsole().getCurrentEditor().getContentComponent(), true);
}
});
+// Run
+ myProcessHandler.startNotify();
+ }
+
+
+ @Nullable
+ protected Process createProcess() throws ExecutionException {
+ return Runner.createProcess(myWorkingDir, true, myProvider.getAdditionalEnvs(), myProvider.getArguments());
+ }
+
+ protected PyConsoleProcessHandler createProcessHandler(final Process process) {
+ final Charset outputEncoding = EncodingManager.getInstance().getDefaultCharset();
+ return new PyConsoleProcessHandler(process, myConsoleView.getConsole(), getProviderCommandLine(), outputEncoding);
}
private void registerActionShortcuts(final AnAction[] actions, final JComponent component) {
@@ -252,11 +241,9 @@ public class PyConsoleRunner {
return new AnAction[]{stopAction, closeAction, myRunAction, historyNextAction, historyPrevAction};
}
- private void doRun() {
- myProcessHandler.startNotify();
- }
-
- private static void sendInput(final String input, final Charset charset, final OutputStream outputStream) {
+ protected void sendInput(final String input) {
+ final Charset charset = myProcessHandler.getCharset();
+ final OutputStream outputStream = myProcessHandler.getProcessInput();
try {
byte[] bytes = input.getBytes(charset.name());
outputStream.write(bytes);
@@ -285,7 +272,7 @@ public class PyConsoleRunner {
myHistory.addToHistory(line);
}
final String text2send = line.length() == 0 ? "\n\n" : line + "\n";
- sendInput(text2send, myProcessHandler.getCharset(), myProcessHandler.getProcessInput());
+ sendInput(text2send);
myConsoleView.inputSent(text2send);
}
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
new file mode 100644
index 000000000000..3494a35172f0
--- /dev/null
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -0,0 +1,123 @@
+package com.jetbrains.python.console;
+
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.console.LanguageConsoleImpl;
+import com.intellij.execution.process.*;
+import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.encoding.EncodingManager;
+import com.intellij.util.net.NetUtils;
+import com.jetbrains.django.run.ExecutionHelper;
+import com.jetbrains.django.run.Runner;
+import com.jetbrains.django.util.DjangoUtil;
+import com.jetbrains.python.PythonHelpersLocator;
+import com.jetbrains.python.console.pydev.ICallback;
+import com.jetbrains.python.console.pydev.InterpreterResponse;
+import com.jetbrains.python.console.pydev.PydevConsoleCommunication;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author oleg
+ */
+public class PydevConsoleRunner extends PyConsoleRunner {
+ private final int[] myPorts;
+ private PydevConsoleCommunication myPydevConsoleCommunication;
+
+ protected PydevConsoleRunner(@NotNull final Project project,
+ @NotNull final String consoleTitle,
+ @NotNull final CommandLineArgumentsProvider provider,
+ @Nullable final String workingDir,
+ int[] ports) {
+ super(project, consoleTitle, provider, workingDir);
+ myPorts = ports;
+ }
+
+ public static void run(@NotNull final Project project,
+ @NotNull final Module module,
+ @NotNull final Sdk sdk) {
+ final String consoleTitle = "TRUE console";
+ final int[] ports;
+ try {
+ // File "pydev/pydevconsole.py", line 223, in
+ // port, client_port = sys.argv[1:3]
+ ports = NetUtils.findAvailableSocketPorts(2);
+ }
+ catch (IOException e) {
+ ExecutionHelper.showErrors(project, Arrays.asList(e), consoleTitle, null);
+ return;
+ }
+ final ArrayList args = new ArrayList(Arrays.asList(sdk.getHomePath(), "-u", PythonHelpersLocator.getHelperPath("pydev/pydevconsole.py")));
+ for (int port : ports) {
+ args.add(String.valueOf(port));
+ }
+ final CommandLineArgumentsProvider provider = new CommandLineArgumentsProvider() {
+ public String[] getArguments() {
+ return args.toArray(new String[args.size()]);
+ }
+
+ public boolean passParentEnvs() {
+ return false;
+ }
+
+ public Map getAdditionalEnvs() {
+ return Collections.emptyMap();
+ }
+ };
+
+ final PydevConsoleRunner consoleRunner = new PydevConsoleRunner(project, consoleTitle, provider, DjangoUtil.getProjectRoot(module), ports);
+ try {
+ consoleRunner.initAndRun();
+ }
+ catch (ExecutionException e) {
+ ExecutionHelper.showErrors(project, Arrays.asList(e), consoleTitle, null);
+ }
+ }
+
+ @Override
+ protected Process createProcess() throws ExecutionException {
+ final Process server = Runner.createProcess(myWorkingDir, true, myProvider.getAdditionalEnvs(), myProvider.getArguments());
+ try {
+ myPydevConsoleCommunication = new PydevConsoleCommunication(getProject(), myPorts[0], server, myPorts[1]);
+ }
+ catch (Exception e) {
+ throw new ExecutionException(e.getMessage());
+ }
+ return server;
+ }
+
+ @Override
+ public void initAndRun() throws ExecutionException {
+ super.initAndRun();
+ sendInput("import sys; print('Python %s on %s' % (sys.version, sys.platform))\n");
+ }
+
+ @Override
+ protected void sendInput(final String input) {
+ if (myPydevConsoleCommunication != null){
+ myPydevConsoleCommunication.execInterpreter(input, new ICallback