mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/ultimate
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="yaml" />
|
||||
<orderEntry type="library" name="microba" level="project" />
|
||||
<orderEntry type="library" name="XmlRPC" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -316,6 +316,11 @@
|
||||
text="Run Python Console..." description="Allows to quickly run Python console">
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
</action>
|
||||
<action id="com.jetbrains.python.console.RunPythonConsoleActionNew"
|
||||
class="com.jetbrains.python.console.RunPythonConsoleActionNew"
|
||||
text="Run TRUE Python Console..." description="Allows to quickly run Python console">
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
</action>
|
||||
<action id="com.jetbrains.django.console.RunDjangoConsoleAction"
|
||||
class="com.jetbrains.django.console.RunDjangoConsoleAction"
|
||||
text="Run Django Console..." description="Allows to quickly run Django console">
|
||||
|
||||
@@ -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<String> 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<String> collectAssemblyReferences(PsiFile file) {
|
||||
if (!(PythonSdkFlavor.getFlavor(mySdk.getHomePath()) instanceof IronPythonSdkFlavor)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<String> result = new ArrayList<String>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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.<Exception>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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <module>
|
||||
// port, client_port = sys.argv[1:3]
|
||||
ports = NetUtils.findAvailableSocketPorts(2);
|
||||
}
|
||||
catch (IOException e) {
|
||||
ExecutionHelper.showErrors(project, Arrays.<Exception>asList(e), consoleTitle, null);
|
||||
return;
|
||||
}
|
||||
final ArrayList<String> args = new ArrayList<String>(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<String, String> 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.<Exception>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<Object, InterpreterResponse>() {
|
||||
public Object call(final InterpreterResponse interpreterResponse) {
|
||||
final LanguageConsoleImpl console = myConsoleView.getConsole();
|
||||
// TODO[oleg] More sophisticated callback required!
|
||||
// At least this one works!
|
||||
if (!StringUtil.isEmpty(interpreterResponse.err)){
|
||||
PyConsoleProcessHandler.processOutput(console, interpreterResponse.err, ProcessOutputTypes.STDERR);
|
||||
} else {
|
||||
PyConsoleProcessHandler.processOutput(console, interpreterResponse.out, ProcessOutputTypes.STDOUT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.jetbrains.python.console;
|
||||
|
||||
import com.intellij.execution.process.CommandLineArgumentsProvider;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.jetbrains.django.util.DjangoUtil;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author oleg
|
||||
*/
|
||||
public class RunPythonConsoleActionNew extends AnAction implements DumbAware {
|
||||
|
||||
public RunPythonConsoleActionNew() {
|
||||
super();
|
||||
getTemplatePresentation().setIcon(IconLoader.getIcon("/com/jetbrains/python/python.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final AnActionEvent e) {
|
||||
e.getPresentation().setVisible(false);
|
||||
e.getPresentation().setEnabled(false);
|
||||
final Project project = e.getData(LangDataKeys.PROJECT);
|
||||
if (project != null){
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
e.getPresentation().setVisible(true);
|
||||
if (PythonSdkType.findPythonSdk(module) != null){
|
||||
e.getPresentation().setEnabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
final Project project = e.getData(LangDataKeys.PROJECT);
|
||||
assert project != null : "Project is null";
|
||||
Sdk sdk = null;
|
||||
Module module = null;
|
||||
for (Module m : ModuleManager.getInstance(project).getModules()) {
|
||||
module = m;
|
||||
sdk = PythonSdkType.findPythonSdk(module);
|
||||
if (sdk != null){
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert module != null : "Module is null";
|
||||
assert sdk != null : "Sdk is null";
|
||||
|
||||
PydevConsoleRunner.run(project, module, sdk);
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,12 @@ import com.jetbrains.python.run.AbstractPythonRunConfiguration;
|
||||
import com.jetbrains.python.run.CommandLinePatcher;
|
||||
import com.jetbrains.python.run.PythonCommandLineState;
|
||||
import com.jetbrains.python.run.PythonRunConfiguration;
|
||||
import com.jetbrains.python.sdk.PythonSdkFlavor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -66,6 +68,13 @@ public class PyDebugRunner extends GenericProgramRunner {
|
||||
// script name is the last parameter; all other params are for python interpreter; insert just before name
|
||||
final ParametersList parameters_list = commandLine.getParametersList();
|
||||
int parameter_offset = pyState.getInterpreterOptionsCount();
|
||||
final PythonSdkFlavor flavor = pyState.getConfig().getSdkFlavor();
|
||||
if (flavor != null) {
|
||||
final Collection<String> options = flavor.getExtraDebugOptions();
|
||||
for (String option : options) {
|
||||
parameters_list.addAt(parameter_offset++, option);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
parameters_list.addAt(i + parameter_offset, args[i]);
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.actions.AddFieldQuickFix;
|
||||
import com.jetbrains.python.actions.AddImportAction;
|
||||
import com.jetbrains.python.actions.AddMethodQuickFix;
|
||||
import com.jetbrains.python.actions.ImportFromExistingFix;
|
||||
import com.jetbrains.python.actions.*;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
@@ -373,6 +370,9 @@ public class PyUnresolvedReferencesInspection extends LocalInspectionTool {
|
||||
hl_type = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL;
|
||||
}
|
||||
|
||||
if (GenerateBinaryStubsFix.isApplicable(reference)) {
|
||||
actions.add(new GenerateBinaryStubsFix(reference));
|
||||
}
|
||||
addPluginQuickFixes(reference, actions);
|
||||
|
||||
PsiElement point = node.getLastChild(); // usually the identifier at the end of qual ref
|
||||
|
||||
@@ -38,6 +38,13 @@ public interface PyCallExpression extends PyExpression {
|
||||
@Nullable
|
||||
PyMarkedFunction resolveCallee();
|
||||
|
||||
/**
|
||||
* Checks if the unqualified name of the callee matches the specified text.
|
||||
*
|
||||
* @param name the text to check
|
||||
* @return true if matches, false otherwise
|
||||
*/
|
||||
boolean isCalleeText(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Couples function with a flag describing the way it is called.
|
||||
|
||||
@@ -49,6 +49,14 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
return PyCallExpressionHelper.resolveCallee(this);
|
||||
}
|
||||
|
||||
public boolean isCalleeText(@NotNull String name) {
|
||||
final PyExpression callee = getCallee();
|
||||
if (!(callee instanceof PyReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
return name.equals(((PyReferenceExpression)callee).getReferencedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PyCallExpression: " + PyUtil.getReadableRepr(getCallee(), true); //or: getCalledFunctionReference().getReferencedName();
|
||||
|
||||
@@ -102,6 +102,14 @@ public class PyDecoratorImpl extends PyPresentableElementImpl<PyDecoratorStub> i
|
||||
return callee;
|
||||
}
|
||||
|
||||
public boolean isCalleeText(@NotNull String name) {
|
||||
final PyExpression callee = getCallee();
|
||||
if (!(callee instanceof PyReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
return name.equals(((PyReferenceExpression)callee).getReferencedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PyDecorator: @" + PyUtil.getReadableRepr(getCallee(), true); //getCalledFunctionReference().getReferencedName();
|
||||
|
||||
@@ -531,6 +531,9 @@ public class ResolveImportUtil {
|
||||
public boolean visitRoot(final VirtualFile root) {
|
||||
PsiElement module = root.isDirectory() ? psimgr.findDirectory(root) : psimgr.findFile(root);
|
||||
for (String component : qualifiedName.getComponents()) {
|
||||
if (component == null) {
|
||||
return true;
|
||||
}
|
||||
module = resolveChild(module, component, foothold_file, false); // only files, we want a module
|
||||
}
|
||||
if (module != null) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.sdk.PythonSdkFlavor;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -108,6 +109,12 @@ public abstract class AbstractPythonRunConfiguration extends ModuleBasedConfigur
|
||||
return PythonSdkType.getInterpreterPath(sdkHome);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PythonSdkFlavor getSdkFlavor() {
|
||||
final String path = getInterpreterPath();
|
||||
return path == null ? null : PythonSdkFlavor.getFlavor(path);
|
||||
}
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
super.readExternal(element);
|
||||
myInterpreterOptions = JDOMExternalizerUtil.readField(element, "INTERPRETER_OPTIONS");
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class IronPythonSdkFlavor extends PythonSdkFlavor {
|
||||
private IronPythonSdkFlavor() {
|
||||
}
|
||||
|
||||
public static IronPythonSdkFlavor INSTANCE = new IronPythonSdkFlavor();
|
||||
|
||||
@Override
|
||||
public boolean isValidSdkHome(String path) {
|
||||
final String name = new File(path).getName();
|
||||
return name.equals("ipy.exe") || name.equals("ipy64.exe");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString(String sdkHome) {
|
||||
return "IronPython " + getVersionFromOutput(sdkHome, "-V", "\\w+ ([0-9\\.]+).*", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExtraDebugOptions() {
|
||||
return Collections.singletonList("-X:Frames");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class JythonSdkFlavor extends PythonSdkFlavor {
|
||||
private JythonSdkFlavor() {
|
||||
}
|
||||
|
||||
public static JythonSdkFlavor INSTANCE = new JythonSdkFlavor();
|
||||
|
||||
@Override
|
||||
public boolean isValidSdkHome(String path) {
|
||||
File file = new File(path);
|
||||
return file.isFile() && FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("jython");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString(String sdkHome) {
|
||||
return getVersionFromOutput(sdkHome, "--version", "(Jython \\S+) on .*", false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class MacPythonSdkFlavor extends PythonSdkFlavor {
|
||||
private MacPythonSdkFlavor() {
|
||||
}
|
||||
|
||||
public static MacPythonSdkFlavor INSTANCE = new MacPythonSdkFlavor();
|
||||
|
||||
@Override
|
||||
public List<String> suggestHomePaths() {
|
||||
List<String> candidates = new ArrayList<String>();
|
||||
final String pythonPath = "/Library/Frameworks/Python.framework/Versions";
|
||||
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath(pythonPath);
|
||||
if (rootVDir != null) {
|
||||
for (VirtualFile dir : rootVDir.getChildren()) {
|
||||
final String dir_name = dir.getName().toLowerCase();
|
||||
if (dir.isDirectory()) {
|
||||
// TODO why would Jython be ever installed under /Library/Frameworks?
|
||||
if ("Current".equals(dir_name) || dir_name.startsWith("2") || dir_name.startsWith("3") || dir_name.startsWith("jython")) {
|
||||
VirtualFile bin_dir = dir.findChild("bin");
|
||||
if (bin_dir != null && bin_dir.isDirectory()) {
|
||||
VirtualFile python_exe = dir.findChild("python");
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
python_exe = dir.findChild("jython"); // maybe it's in bin/
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
else {
|
||||
VirtualFile python_exe = dir.findChild("jython"); // maybe it's not in bin/
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class PythonSdkFlavor {
|
||||
public List<String> suggestHomePaths() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static List<PythonSdkFlavor> getApplicableFlavors() {
|
||||
List<PythonSdkFlavor> result = new ArrayList<PythonSdkFlavor>();
|
||||
if (SystemInfo.isWindows) {
|
||||
result.add(WinPythonSdkFlavor.INSTANCE);
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
result.add(MacPythonSdkFlavor.INSTANCE);
|
||||
}
|
||||
else if (SystemInfo.isUnix) {
|
||||
result.add(UnixPythonSdkFlavor.INSTANCE);
|
||||
}
|
||||
result.add(JythonSdkFlavor.INSTANCE);
|
||||
result.add(IronPythonSdkFlavor.INSTANCE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PythonSdkFlavor getFlavor(String sdkPath) {
|
||||
for (PythonSdkFlavor flavor : getApplicableFlavors()) {
|
||||
if (flavor.isValidSdkHome(sdkPath)) {
|
||||
return flavor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the path is the name of a Python interpreter of this flavor.
|
||||
*
|
||||
* @param path path to check.
|
||||
* @return true if paths points to a valid home.
|
||||
*/
|
||||
public boolean isValidSdkHome(String path) {
|
||||
File file = new File(path);
|
||||
return file.isFile() && FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("python");
|
||||
}
|
||||
|
||||
public String getVersionString(String sdkHome) {
|
||||
return getVersionFromOutput(sdkHome, "-V", "(Python \\S+).*", false);
|
||||
}
|
||||
|
||||
protected static String getVersionFromOutput(String sdkHome, String version_opt, String version_regexp, boolean stdout) {
|
||||
Pattern pattern = Pattern.compile(version_regexp);
|
||||
String run_dir = new File(sdkHome).getParent();
|
||||
final ProcessOutput process_output = SdkUtil.getProcessOutput(run_dir, new String[]{sdkHome, version_opt});
|
||||
if (process_output.getExitCode() != 0) {
|
||||
throw new RuntimeException(process_output.getStderr() + " (exit code " + process_output.getExitCode() + ")");
|
||||
}
|
||||
final List<String> lines = stdout ? process_output.getStdoutLines() : process_output.getStderrLines();
|
||||
return SdkUtil.getFirstMatch(lines, pattern);
|
||||
}
|
||||
|
||||
public Collection<String> getExtraDebugOptions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.*;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
|
||||
@@ -63,7 +59,7 @@ public class PythonSdkType extends SdkType {
|
||||
private static final Logger LOG = Logger.getInstance("#" + PythonSdkType.class.getName());
|
||||
private static final String[] WINDOWS_EXECUTABLE_SUFFIXES = new String[]{"cmd", "exe", "bat", "com"};
|
||||
|
||||
static final int RUN_TIMEOUT = 30 * 1000; // 30 seconds per script invocation is plenty; anything more seems wrong (10 wasn't enough tho).
|
||||
static final int RUN_TIMEOUT = 60 * 1000; // 60 seconds per script invocation is plenty; anything more seems wrong (10 wasn't enough tho).
|
||||
|
||||
public static PythonSdkType getInstance() {
|
||||
return SdkType.findInstance(PythonSdkType.class);
|
||||
@@ -99,8 +95,6 @@ public class PythonSdkType extends SdkType {
|
||||
return PyBuiltinCache.BUILTIN_FILE;
|
||||
}
|
||||
|
||||
@NonNls static final private String PYTHON_STR = "python";
|
||||
|
||||
@NonNls
|
||||
@Nullable
|
||||
public String suggestHomePath() {
|
||||
@@ -109,49 +103,8 @@ public class PythonSdkType extends SdkType {
|
||||
return findDigits(o1).compareTo(findDigits(o2));
|
||||
}
|
||||
});
|
||||
if (SystemInfo.isWindows) {
|
||||
findSubdirInstallations(candidates, "C:\\", PYTHON_STR, "python.exe");
|
||||
findSubdirInstallations(candidates, "C:\\Program Files\\", PYTHON_STR, "python.exe");
|
||||
findSubdirInstallations(candidates, "C:\\", "jython", "jython.bat");
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
final String pythonPath = "/Library/Frameworks/Python.framework/Versions";
|
||||
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath(pythonPath);
|
||||
if (rootVDir != null) {
|
||||
for (VirtualFile dir : rootVDir.getChildren()) {
|
||||
final String dir_name = dir.getName().toLowerCase();
|
||||
if (dir.isDirectory()) {
|
||||
if ("Current".equals(dir_name) || dir_name.startsWith("2") || dir_name.startsWith("3") || dir_name.startsWith("jython")) {
|
||||
VirtualFile bin_dir = dir.findChild("bin");
|
||||
if (bin_dir != null && bin_dir.isDirectory()) {
|
||||
VirtualFile python_exe = dir.findChild(PYTHON_STR);
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
python_exe = dir.findChild("jython"); // maybe it's in bin/
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
else {
|
||||
VirtualFile python_exe = dir.findChild("jython"); // maybe it's not in bin/
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SystemInfo.isUnix) {
|
||||
VirtualFile rootDir = LocalFileSystem.getInstance().findFileByPath("/usr/bin");
|
||||
if (rootDir != null) {
|
||||
VirtualFile[] suspects = rootDir.getChildren();
|
||||
for (VirtualFile child : suspects) {
|
||||
if (!child.isDirectory()) {
|
||||
final String child_name = child.getName();
|
||||
if (child_name.startsWith(PYTHON_STR) || child_name.startsWith("jython")) {
|
||||
candidates.add(child.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
candidates.add(rootDir.getPath());
|
||||
}
|
||||
for (PythonSdkFlavor flavor : PythonSdkFlavor.getApplicableFlavors()) {
|
||||
candidates.addAll(flavor.suggestHomePaths());
|
||||
}
|
||||
|
||||
if (candidates.size() > 0) {
|
||||
@@ -174,20 +127,8 @@ public class PythonSdkType extends SdkType {
|
||||
return s;
|
||||
}
|
||||
|
||||
private static void findSubdirInstallations(TreeSet<String> candidates, String rootDir, String dir_prefix, String exe_name) {
|
||||
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath("C:\\");
|
||||
if (rootVDir != null) {
|
||||
for (VirtualFile dir : rootVDir.getChildren()) {
|
||||
if (dir.isDirectory() && dir.getName().toLowerCase().startsWith(dir_prefix)) {
|
||||
VirtualFile python_exe = dir.findChild(exe_name);
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValidSdkHome(final String path) {
|
||||
return isPythonSdkHome(path) || isJythonSdkHome(path);
|
||||
return PythonSdkFlavor.getFlavor(path) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -225,29 +166,6 @@ public class PythonSdkType extends SdkType {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the path is the name of a Python intepreter.
|
||||
*
|
||||
* @param path path to check.
|
||||
* @return true if paths points to a valid home.
|
||||
*/
|
||||
@NonNls
|
||||
private static boolean isPythonSdkHome(final String path) {
|
||||
File file = new File(path);
|
||||
return file.isFile() && FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("python");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the path is the name of a Jython intepreter.
|
||||
*
|
||||
* @param path path to check.
|
||||
* @return true if paths points to a valid home.
|
||||
*/
|
||||
private static boolean isJythonSdkHome(final String path) {
|
||||
File file = new File(path);
|
||||
return file.isFile() && FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("jython");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path where to look
|
||||
* @return Python interpreter executable on the path, or null.
|
||||
@@ -429,9 +347,8 @@ public class PythonSdkType extends SdkType {
|
||||
}
|
||||
}
|
||||
// fix skeletons as needed
|
||||
String url = findSkeletonsUrl(currentSdk);
|
||||
if (url != null) {
|
||||
final String path = VfsUtil.urlToPath(url);
|
||||
final String path = findSkeletonsPath(currentSdk);
|
||||
if (path != null) {
|
||||
File stubs_dir = new File(path);
|
||||
if (!stubs_dir.exists()) {
|
||||
final ProgressManager progman = ProgressManager.getInstance();
|
||||
@@ -441,7 +358,7 @@ public class PythonSdkType extends SdkType {
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
try {
|
||||
generateBuiltinStubs(currentSdk.getHomePath(), path);
|
||||
generateBinaryStubs(currentSdk.getHomePath(), path, indicator);
|
||||
generateBinarySkeletons(currentSdk.getHomePath(), path, indicator);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
@@ -487,11 +404,11 @@ public class PythonSdkType extends SdkType {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String findSkeletonsUrl(Sdk sdk) {
|
||||
public static String findSkeletonsPath(Sdk sdk) {
|
||||
final String[] urls = sdk.getRootProvider().getUrls(BUILTIN_ROOT_TYPE);
|
||||
for (String url : urls) {
|
||||
if (url.contains(SKELETON_DIR_NAME)) {
|
||||
return url;
|
||||
return VfsUtil.urlToPath(url);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -605,7 +522,7 @@ public class PythonSdkType extends SdkType {
|
||||
// regenerate stubs, existing or not
|
||||
final File stubs_dir = new File(stubs_path);
|
||||
if (!stubs_dir.exists()) stubs_dir.mkdirs();
|
||||
generateBinaryStubs(bin_path, stubs_path, indicator);
|
||||
generateBinarySkeletons(bin_path, stubs_path, indicator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,28 +556,8 @@ public class PythonSdkType extends SdkType {
|
||||
|
||||
@Nullable
|
||||
public String getVersionString(final String sdkHome) {
|
||||
final String binaryPath = getInterpreterPath(sdkHome);
|
||||
if (binaryPath == null) {
|
||||
return null;
|
||||
}
|
||||
final boolean isJython = isJythonSdkHome(sdkHome);
|
||||
@NonNls String version_regexp, version_opt;
|
||||
if (isJython) {
|
||||
version_regexp = "(Jython \\S+) on .*";
|
||||
version_opt = "--version";
|
||||
}
|
||||
else { // CPython
|
||||
version_regexp = "(Python \\S+).*";
|
||||
version_opt = "-V";
|
||||
}
|
||||
Pattern pattern = Pattern.compile(version_regexp);
|
||||
String run_dir = new File(binaryPath).getParent();
|
||||
final ProcessOutput process_output = SdkUtil.getProcessOutput(run_dir, new String[]{binaryPath, version_opt});
|
||||
if (process_output.getExitCode() != 0) {
|
||||
throw new RuntimeException(process_output.getStderr() + " (exit code " + process_output.getExitCode() + ")");
|
||||
}
|
||||
String version = SdkUtil.getFirstMatch(process_output.getStderrLines(), pattern);
|
||||
return version;
|
||||
final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(sdkHome);
|
||||
return flavor != null ? flavor.getVersionString(sdkHome) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -685,7 +582,7 @@ public class PythonSdkType extends SdkType {
|
||||
"-b", // for builtins
|
||||
"-u", // for update-only mode
|
||||
},
|
||||
getVirtualEnvAdditionalEnv(binary_path), RUN_TIMEOUT
|
||||
getVirtualEnvAdditionalEnv(binary_path), RUN_TIMEOUT*5
|
||||
);
|
||||
if (run_result.getExitCode() != 0) {
|
||||
LOG.error(run_result.getStderr() + (run_result.isTimeout()? "\nTimed out" : "\nExit code " + run_result.getExitCode()));
|
||||
@@ -700,8 +597,7 @@ public class PythonSdkType extends SdkType {
|
||||
* @param stubsRoot where to put results (expected to exist).
|
||||
* @param indicator ProgressIndicator to update, or null.
|
||||
*/
|
||||
public static void generateBinaryStubs(final String binaryPath, final String stubsRoot, ProgressIndicator indicator)
|
||||
{
|
||||
public static void generateBinarySkeletons(final String binaryPath, final String stubsRoot, ProgressIndicator indicator) {
|
||||
if (indicator != null) {
|
||||
indicator.setText("Generating skeletons of binary libs");
|
||||
}
|
||||
@@ -732,19 +628,7 @@ public class PythonSdkType extends SdkType {
|
||||
indicator.setText2(modname);
|
||||
}
|
||||
LOG.info("Skeleton for " + modname);
|
||||
final ProcessOutput gen_result = SdkUtil.getProcessOutput(
|
||||
parent_dir,
|
||||
new String[]{binaryPath, PythonHelpersLocator.getHelperPath(GENERATOR3), "-d", stubsRoot, modname},
|
||||
getVirtualEnvAdditionalEnv(binaryPath),
|
||||
RUN_TIMEOUT
|
||||
);
|
||||
if (gen_result.getExitCode() != 0) {
|
||||
StringBuffer sb = new StringBuffer("Skeleton for ");
|
||||
sb.append(modname).append(" failed. stderr: --");
|
||||
for (String err_line : gen_result.getStderrLines()) sb.append(err_line).append("\n");
|
||||
sb.append("--");
|
||||
LOG.warn(sb.toString());
|
||||
}
|
||||
generateSkeleton(binaryPath, stubsRoot, modname, Collections.<String>emptyList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,6 +642,34 @@ public class PythonSdkType extends SdkType {
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateSkeleton(String binaryPath, String stubsRoot, String modname, List<String> assemblyRefs) {
|
||||
final String parent_dir = new File(binaryPath).getParent();
|
||||
List<String> commandLine = new ArrayList<String>();
|
||||
commandLine.add(binaryPath);
|
||||
commandLine.add(PythonHelpersLocator.getHelperPath(GENERATOR3));
|
||||
commandLine.add("-d");
|
||||
commandLine.add(stubsRoot);
|
||||
if (!assemblyRefs.isEmpty()) {
|
||||
commandLine.add("-c");
|
||||
commandLine.add(StringUtil.join(assemblyRefs, ";"));
|
||||
}
|
||||
commandLine.add(modname);
|
||||
|
||||
final ProcessOutput gen_result = SdkUtil.getProcessOutput(
|
||||
parent_dir,
|
||||
commandLine.toArray(new String[commandLine.size()]),
|
||||
getVirtualEnvAdditionalEnv(binaryPath),
|
||||
RUN_TIMEOUT*10
|
||||
);
|
||||
if (gen_result.getExitCode() != 0) {
|
||||
StringBuffer sb = new StringBuffer("Skeleton for ");
|
||||
sb.append(modname).append(" failed. stderr: --");
|
||||
for (String err_line : gen_result.getStderrLines()) sb.append(err_line).append("\n");
|
||||
sb.append("--");
|
||||
LOG.warn(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Sdk> getAllSdks() {
|
||||
return ProjectJdkTable.getInstance().getSdksOfType(getInstance());
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
@@ -18,7 +18,7 @@ import java.util.List;
|
||||
public class SkeletonVersionUpdater implements ProjectComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.sdk.SkeletonVersionUpdater");
|
||||
|
||||
public static int SKELETONS_VERSION = 2;
|
||||
public static int SKELETONS_VERSION = 3;
|
||||
|
||||
public SkeletonVersionUpdater(StartupManager startupManager) {
|
||||
startupManager.registerStartupActivity(new Runnable() {
|
||||
@@ -30,10 +30,9 @@ public class SkeletonVersionUpdater implements ProjectComponent {
|
||||
writeVersion(versionFile, SKELETONS_VERSION);
|
||||
final List<Sdk> sdkList = PythonSdkType.getAllSdks();
|
||||
for (Sdk sdk : sdkList) {
|
||||
final String url = PythonSdkType.findSkeletonsUrl(sdk);
|
||||
final String path = VfsUtil.urlToPath(url);
|
||||
final String path = PythonSdkType.findSkeletonsPath(sdk);
|
||||
PythonSdkType.generateBuiltinStubs(sdk.getHomePath(), path);
|
||||
PythonSdkType.generateBinaryStubs(sdk.getHomePath(), path, ProgressManager.getInstance().getProgressIndicator());
|
||||
PythonSdkType.generateBinarySkeletons(sdk.getHomePath(), path, ProgressManager.getInstance().getProgressIndicator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class UnixPythonSdkFlavor extends PythonSdkFlavor {
|
||||
private UnixPythonSdkFlavor() {
|
||||
}
|
||||
|
||||
public static UnixPythonSdkFlavor INSTANCE = new UnixPythonSdkFlavor();
|
||||
|
||||
@Override
|
||||
public List<String> suggestHomePaths() {
|
||||
List<String> candidates = new ArrayList<String>();
|
||||
VirtualFile rootDir = LocalFileSystem.getInstance().findFileByPath("/usr/bin");
|
||||
if (rootDir != null) {
|
||||
VirtualFile[] suspects = rootDir.getChildren();
|
||||
for (VirtualFile child : suspects) {
|
||||
if (!child.isDirectory()) {
|
||||
final String child_name = child.getName();
|
||||
if (child_name.startsWith("python") || child_name.startsWith("jython")) {
|
||||
candidates.add(child.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
candidates.add(rootDir.getPath());
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.jetbrains.python.sdk;
|
||||
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class WinPythonSdkFlavor extends PythonSdkFlavor {
|
||||
@NonNls static final private String PYTHON_STR = "python";
|
||||
|
||||
public static WinPythonSdkFlavor INSTANCE = new WinPythonSdkFlavor();
|
||||
|
||||
private WinPythonSdkFlavor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> suggestHomePaths() {
|
||||
List<String> candidates = new ArrayList<String>();
|
||||
findSubdirInstallations(candidates, "C:\\", PYTHON_STR, "python.exe");
|
||||
findSubdirInstallations(candidates, "C:\\Program Files\\", PYTHON_STR, "python.exe");
|
||||
findSubdirInstallations(candidates, "C:\\", "jython", "jython.bat");
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private static void findSubdirInstallations(Collection<String> candidates, String rootDir, String dir_prefix, String exe_name) {
|
||||
VirtualFile rootVDir = LocalFileSystem.getInstance().findFileByPath(rootDir);
|
||||
if (rootVDir != null) {
|
||||
for (VirtualFile dir : rootVDir.getChildren()) {
|
||||
if (dir.isDirectory() && dir.getName().toLowerCase().startsWith(dir_prefix)) {
|
||||
VirtualFile python_exe = dir.findChild(exe_name);
|
||||
if (python_exe != null) candidates.add(python_exe.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +161,12 @@ public class UnsupportedFeatures extends PyAnnotator {
|
||||
getHolder().createWarningAnnotation(node,
|
||||
"Integer literals do not support a trailing \'l\' or \'L\' in Python 3").registerFix(new RemoveTrailingLIntention());
|
||||
}
|
||||
if (text.length() > 1 && text.charAt(0) == '0' && (text.charAt(1) != 'o' || text.charAt(1) != 'b')) {
|
||||
getHolder().createWarningAnnotation(node,
|
||||
"Python 3 requires '0o' prefix for octal literals").registerFix(new ReplaceOctalNumericLiteralIntention());
|
||||
if (text.length() > 1 && text.charAt(0) == '0') {
|
||||
char c = Character.toLowerCase(text.charAt(1));
|
||||
if (c != 'o' && c != 'b' && c != 'x') {
|
||||
getHolder().createWarningAnnotation(node,
|
||||
"Python 3 requires '0o' prefix for octal literals").registerFix(new ReplaceOctalNumericLiteralIntention());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ print(<warning descr="<> is not supported in Python 3, use != instead">a <> 3</w
|
||||
x = <warning descr="Method 'raw_input' has been removed, use 'input' instead">raw_input</warning>()
|
||||
a = <warning descr="Integer literals do not support a trailing 'l' or 'L' in Python 3">123l</warning>
|
||||
a = <warning descr="Python 3 requires '0o' prefix for octal literals">043</warning>
|
||||
a = 0X43
|
||||
a = 0b1
|
||||
s = <warning descr="String literals do not support a leading 'u' or 'U' in Python 3">u"text"</warning>
|
||||
<warning descr="Python 3 does not support this syntax">raise a, b, c</warning>
|
||||
<warning descr="Python 3 does not support this syntax">raise a, b</warning>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<caret><warning descr="Old-style class">class A:
|
||||
class <warning descr="Old-style class"><caret>A</warning>:
|
||||
def foo(self):
|
||||
pass
|
||||
|
||||
def bar(self):
|
||||
pass</warning>
|
||||
pass
|
||||
Reference in New Issue
Block a user