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:
@@ -19,7 +19,7 @@ all this too.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
OUR_OWN_DATETIME = datetime(2010, 6, 3, 17, 13, 12) # datetime.now() of edit time
|
||||
OUR_OWN_DATETIME = datetime(2010, 7, 9, 16, 1, 5) # datetime.now() of edit time
|
||||
# we could use script's ctime, but the actual running copy may have it all wrong.
|
||||
#
|
||||
# Note: DON'T FORGET TO UPDATE!
|
||||
@@ -347,7 +347,7 @@ optionalPart << (
|
||||
| ellipsis
|
||||
)
|
||||
|
||||
# this is our ideal target, with balancing paren and a multiline rest of doc.
|
||||
# this is our ideal target, with balancing paren and a multiline rest of doc.
|
||||
paramSeqAndRest = paramSeq + Suppress(')') + Suppress(Optional(Regex(".*(?s)")))
|
||||
|
||||
def transformSeq(results, toplevel=True):
|
||||
@@ -555,6 +555,146 @@ class ModuleRedeclarator(object):
|
||||
PREDEFINED_MOD_CLASS_SIGS = {
|
||||
("datetime", "timedelta", "__new__") : "(cls, days=None, seconds=None, microseconds=None, milliseconds=None, minutes=None, hours=None, weeks=None)",
|
||||
}
|
||||
|
||||
# known properties of modules
|
||||
# {{"module": {"class", "property" : ("letters", "getter")}},
|
||||
# where letters is any set of r,w,d (read, write, del) and "getter" is a source of typed getter.
|
||||
# if vlue is None, the property should be omitted.
|
||||
# read-only properties that return an object are not listed.
|
||||
G_OBJECT = "lambda self: object()"
|
||||
G_TYPE = "lambda self: type(object)"
|
||||
G_DICT = "lambda self: {}"
|
||||
G_STR = "lambda self: ''"
|
||||
G_TUPLE = "lambda self: tuple()"
|
||||
G_FLOAT = "lambda self: 0.0"
|
||||
G_INT = "lambda self: 0"
|
||||
G_BOOL = "lambda self: True"
|
||||
|
||||
KNOWN_PROPS = {
|
||||
BUILTIN_MOD_NAME: {
|
||||
("object", '__class__'): ('r', G_TYPE),
|
||||
("BaseException", '__dict__'): ('r', G_DICT),
|
||||
("BaseException", 'message'): ('rwd', G_STR),
|
||||
("BaseException",'args'): ('r', G_TUPLE),
|
||||
('complex','real'): ('r', G_FLOAT),
|
||||
('complex','imag'): ('r', G_FLOAT),
|
||||
("EnvironmentError", 'errno'): ('rwd', G_INT),
|
||||
("EnvironmentError", 'message'): ('rwd', G_STR),
|
||||
("EnvironmentError", 'strerror'): ('rwd', G_INT),
|
||||
("EnvironmentError", 'filename'): ('rwd', G_STR),
|
||||
("file", 'softspace'): ('r', G_BOOL),
|
||||
("file", 'name'): ('r', G_STR),
|
||||
("file", 'encoding'): ('r', G_STR),
|
||||
("file", 'mode'): ('r', G_STR),
|
||||
("file", 'closed'): ('r', G_BOOL),
|
||||
("file", 'newlines'): ('r', G_STR),
|
||||
("SyntaxError", 'text'): ('rwd', G_STR),
|
||||
("SyntaxError", 'print_file_and_line'): ('rwd', G_BOOL),
|
||||
("SyntaxError", 'filename'): ('rwd', G_STR),
|
||||
("SyntaxError", 'lineno'): ('rwd', G_INT),
|
||||
("SyntaxError", 'offset'): ('rwd', G_INT),
|
||||
("SyntaxError", 'msg'): ('rwd', G_STR),
|
||||
("SyntaxError", 'message'): ('rwd', G_STR),
|
||||
("slice", 'start'): ('r', G_INT),
|
||||
("slice", 'step'): ('r', G_INT),
|
||||
("slice", 'stop'): ('r', G_INT),
|
||||
("super", '__thisclass__'): ('r', G_TYPE),
|
||||
("super", '__self__'): ('r', G_TYPE),
|
||||
("super", '__self_class__'): ('r', G_TYPE),
|
||||
("SystemExit", 'message'): ('rwd', G_STR),
|
||||
("SystemExit", 'code'): ('rwd', G_OBJECT),
|
||||
("type", '__basicsize__'): ('r', G_INT),
|
||||
("type", '__itemsize__'): ('r', G_INT),
|
||||
("type", '__base__'): ('r', G_TYPE),
|
||||
("type", '__flags__'): ('r', G_INT),
|
||||
("type", '__mro__'): ('r', G_TUPLE),
|
||||
("type", '__bases__'): ('r', G_TUPLE),
|
||||
("type", '__dictoffset__'): ('r', G_INT),
|
||||
("type", '__dict__'): ('r', G_DICT),
|
||||
("type", '__name__'): ('r', G_STR),
|
||||
("type", '__weakrefoffset__'): ('r', G_INT),
|
||||
("UnicodeDecodeError", '__basicsize__'): None,
|
||||
("UnicodeDecodeError", '__itemsize__'): None,
|
||||
("UnicodeDecodeError", '__base__'): None,
|
||||
("UnicodeDecodeError", '__flags__'): ('rwd', G_INT),
|
||||
("UnicodeDecodeError", '__mro__'): None,
|
||||
("UnicodeDecodeError", '__bases__'): None,
|
||||
("UnicodeDecodeError", '__dictoffset__'): None,
|
||||
("UnicodeDecodeError", '__dict__'): None,
|
||||
("UnicodeDecodeError", '__name__'): None,
|
||||
("UnicodeDecodeError", '__weakrefoffset__'): None,
|
||||
("UnicodeEncodeError", 'end'): ('rwd', G_INT),
|
||||
("UnicodeEncodeError", 'encoding'): ('rwd', G_STR),
|
||||
("UnicodeEncodeError", 'object'): ('rwd', G_OBJECT),
|
||||
("UnicodeEncodeError", 'start'): ('rwd', G_INT),
|
||||
("UnicodeEncodeError", 'reason'): ('rwd', G_STR),
|
||||
("UnicodeEncodeError", 'message'): ('rwd', G_STR),
|
||||
("UnicodeTranslateError", 'end'): ('rwd', G_INT),
|
||||
("UnicodeTranslateError", 'encoding'): ('rwd', G_STR),
|
||||
("UnicodeTranslateError", 'object'): ('rwd', G_OBJECT),
|
||||
("UnicodeTranslateError", 'start'): ('rwd', G_INT),
|
||||
("UnicodeTranslateError", 'reason'): ('rwd', G_STR),
|
||||
("UnicodeTranslateError", 'message'): ('rwd', G_STR),
|
||||
},
|
||||
'_ast': {
|
||||
("AST", '__dict__'): ('rd', G_DICT),
|
||||
},
|
||||
'posix': {
|
||||
("statvfs_result", 'f_flag'): ('r', G_INT),
|
||||
("statvfs_result", 'f_bavail'): ('r', G_INT),
|
||||
("statvfs_result", 'f_favail'): ('r', G_INT),
|
||||
("statvfs_result", 'f_files'): ('r', G_INT),
|
||||
("statvfs_result", 'f_frsize'): ('r', G_INT),
|
||||
("statvfs_result", 'f_blocks'): ('r', G_INT),
|
||||
("statvfs_result", 'f_ffree'): ('r', G_INT),
|
||||
("statvfs_result", 'f_bfree'): ('r', G_INT),
|
||||
("statvfs_result", 'f_namemax'): ('r', G_INT),
|
||||
("statvfs_result", 'f_bsize'): ('r', G_INT),
|
||||
|
||||
("stat_result", 'st_ctime'): ('r', G_INT),
|
||||
("stat_result", 'st_rdev'): ('r', G_INT),
|
||||
("stat_result", 'st_mtime'): ('r', G_INT),
|
||||
("stat_result", 'st_blocks'): ('r', G_INT),
|
||||
("stat_result", 'st_gid'): ('r', G_INT),
|
||||
("stat_result", 'st_nlink'): ('r', G_INT),
|
||||
("stat_result", 'st_ino'): ('r', G_INT),
|
||||
("stat_result", 'st_blksize'): ('r', G_INT),
|
||||
("stat_result", 'st_dev'): ('r', G_INT),
|
||||
("stat_result", 'st_size'): ('r', G_INT),
|
||||
("stat_result", 'st_mode'): ('r', G_INT),
|
||||
("stat_result", 'st_uid'): ('r', G_INT),
|
||||
("stat_result", 'st_atime'): ('r', G_INT),
|
||||
},
|
||||
"pwd": {
|
||||
("struct_pwent", 'pw_dir'): ('r', G_STR),
|
||||
("struct_pwent", 'pw_gid'): ('r', G_INT),
|
||||
("struct_pwent", 'pw_passwd'): ('r', G_STR),
|
||||
("struct_pwent", 'pw_gecos'): ('r', G_STR),
|
||||
("struct_pwent", 'pw_shell'): ('r', G_STR),
|
||||
("struct_pwent", 'pw_name'): ('r', G_STR),
|
||||
("struct_pwent", 'pw_uid'): ('r', G_INT),
|
||||
|
||||
("struct_passwd", 'pw_dir'): ('r', G_STR),
|
||||
("struct_passwd", 'pw_gid'): ('r', G_INT),
|
||||
("struct_passwd", 'pw_passwd'): ('r', G_STR),
|
||||
("struct_passwd", 'pw_gecos'): ('r', G_STR),
|
||||
("struct_passwd", 'pw_shell'): ('r', G_STR),
|
||||
("struct_passwd", 'pw_name'): ('r', G_STR),
|
||||
("struct_passwd", 'pw_uid'): ('r', G_INT),
|
||||
},
|
||||
"thread": {
|
||||
("_local", '__dict__'): None
|
||||
},
|
||||
"xxsubtype": {
|
||||
("spamdict", 'state'): ('r', G_INT),
|
||||
("spamlist", 'state'): ('r', G_INT),
|
||||
},
|
||||
"zipimport": {
|
||||
("zipimporter", 'prefix'): ('r', G_STR),
|
||||
("zipimporter", 'archive'): ('r', G_STR),
|
||||
("zipimporter", '_files'): ('r', G_DICT),
|
||||
},
|
||||
}
|
||||
|
||||
# Some builtin classes effectively change __init__ signature without overriding it.
|
||||
# This callable serves as a placeholder to be replaced via REDEFINED_BUILTIN_SIGS
|
||||
@@ -948,10 +1088,10 @@ class ModuleRedeclarator(object):
|
||||
self.out("class " + p_name + base_def + ":", indent)
|
||||
self.outDocAttr(p_class, indent+1)
|
||||
# inner parts
|
||||
methods = {}
|
||||
properties = {}
|
||||
others = {}
|
||||
if hasattr(p_class, "__dict__"):
|
||||
methods = {}
|
||||
properties = {}
|
||||
others = {}
|
||||
we_are_the_base_class = p_modname == BUILTIN_MOD_NAME and p_name in ("object", FAKE_CLASSOBJ_NAME)
|
||||
for item_name in p_class.__dict__:
|
||||
if item_name in ("__doc__", "__module__"):
|
||||
@@ -978,9 +1118,24 @@ class ModuleRedeclarator(object):
|
||||
item = methods[item_name]
|
||||
self.redoFunction(item, item_name, indent+1, p_class, p_modname)
|
||||
#
|
||||
known_props = self.KNOWN_PROPS.get(p_modname, {})
|
||||
a_setter = "lambda self, v: None"
|
||||
a_deleter = "lambda self: None"
|
||||
for item_name in sortedNoCase(properties.keys()):
|
||||
item = properties[item_name]
|
||||
self.out(item_name + " = property(None, None, None)", indent+1) # TODO: handle docstring
|
||||
prop_key = (p_name, item_name)
|
||||
if known_props.has_key(prop_key):
|
||||
prop_descr = known_props.get(prop_key, None)
|
||||
if prop_descr is None:
|
||||
continue # explicitly omitted
|
||||
acc_line, getter = prop_descr
|
||||
accessors = []
|
||||
accessors.append("r" in acc_line and getter or "None")
|
||||
accessors.append("w" in acc_line and a_setter or "None")
|
||||
accessors.append("d" in acc_line and a_deleter or "None")
|
||||
self.out(item_name + " = property(" + ", ".join(accessors) + ")", indent+1)
|
||||
else:
|
||||
self.out(item_name + " = property(lambda self: object(), None, None) # default", indent+1)
|
||||
# TODO: handle docstring
|
||||
if properties:
|
||||
self.out("", 0) # empty line after the block
|
||||
#
|
||||
@@ -1015,7 +1170,7 @@ class ModuleRedeclarator(object):
|
||||
if hasattr(item, "__name__"):
|
||||
self.out("import " + item.__name__ + " as " + item_name + " # refers to " + str(item))
|
||||
else:
|
||||
self.out(item_name + " = None # XXX name unknown, refers to " + str(item))
|
||||
self.out(item_name + " = None # ??? name unknown, refers to " + str(item))
|
||||
self.out("", 0) # empty line after imports
|
||||
# group what else we have into buckets
|
||||
vars_simple = {}
|
||||
|
||||
@@ -49,4 +49,9 @@ public class PyJavaClassType implements PyType {
|
||||
return myClass.getName();
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false; // TODO: JSDK's types could be considered built-in.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class PyTokenTypes {
|
||||
|
||||
public static final PyElementType END_OF_LINE_COMMENT = new PyElementType("END_OF_LINE_COMMENT");
|
||||
|
||||
public static final PyElementType AND_KEYWORD = new PyElementType("AND_KEYWORD");
|
||||
public static final PyElementType AND_KEYWORD = new PyElementType("AND_KEYWORD", "__and__");
|
||||
public static final PyElementType AS_KEYWORD = new PyElementType("AS_KEYWORD");
|
||||
public static final PyElementType ASSERT_KEYWORD = new PyElementType("ASSERT_KEYWORD");
|
||||
public static final PyElementType BREAK_KEYWORD = new PyElementType("BREAK_KEYWORD");
|
||||
@@ -42,7 +42,7 @@ public class PyTokenTypes {
|
||||
public static final PyElementType IS_KEYWORD = new PyElementType("IS_KEYWORD");
|
||||
public static final PyElementType LAMBDA_KEYWORD = new PyElementType("LAMBDA_KEYWORD");
|
||||
public static final PyElementType NOT_KEYWORD = new PyElementType("NOT_KEYWORD");
|
||||
public static final PyElementType OR_KEYWORD = new PyElementType("OR_KEYWORD");
|
||||
public static final PyElementType OR_KEYWORD = new PyElementType("OR_KEYWORD", "__or__");
|
||||
public static final PyElementType PASS_KEYWORD = new PyElementType("PASS_KEYWORD");
|
||||
public static final PyElementType PRINT_KEYWORD = new PyElementType("PRINT_KEYWORD");
|
||||
public static final PyElementType RAISE_KEYWORD = new PyElementType("RAISE_KEYWORD");
|
||||
@@ -75,26 +75,26 @@ public class PyTokenTypes {
|
||||
public static final PyElementType STRING_LITERAL = new PyElementType("STRING_LITERAL");
|
||||
|
||||
// Operators
|
||||
public static final PyElementType PLUS = new PyElementType("PLUS");// +
|
||||
public static final PyElementType MINUS = new PyElementType("MINUS");// -
|
||||
public static final PyElementType MULT = new PyElementType("MULT");// *
|
||||
public static final PyElementType EXP = new PyElementType("EXP");// **
|
||||
public static final PyElementType DIV = new PyElementType("DIV"); // /
|
||||
public static final PyElementType FLOORDIV = new PyElementType("FLOORDIV"); // //
|
||||
public static final PyElementType PERC = new PyElementType("PERC");// %
|
||||
public static final PyElementType LTLT = new PyElementType("LTLT");// <<
|
||||
public static final PyElementType GTGT = new PyElementType("GTGT");// >>
|
||||
public static final PyElementType AND = new PyElementType("AND");// &
|
||||
public static final PyElementType OR = new PyElementType("OR");// |
|
||||
public static final PyElementType XOR = new PyElementType("XOR");// ^
|
||||
public static final PyElementType TILDE = new PyElementType("TILDE");// ~
|
||||
public static final PyElementType LT = new PyElementType("LT");// <
|
||||
public static final PyElementType GT = new PyElementType("GT");// >
|
||||
public static final PyElementType LE = new PyElementType("LE");// <=
|
||||
public static final PyElementType GE = new PyElementType("GE");// >=
|
||||
public static final PyElementType EQEQ = new PyElementType("EQEQ");// ==
|
||||
public static final PyElementType NE = new PyElementType("NE");// !=
|
||||
public static final PyElementType NE_OLD = new PyElementType("NE_OLD");// <>
|
||||
public static final PyElementType PLUS = new PyElementType("PLUS", "__add__");// +
|
||||
public static final PyElementType MINUS = new PyElementType("MINUS", "__sub__");// -
|
||||
public static final PyElementType MULT = new PyElementType("MULT", "__mul__");// *
|
||||
public static final PyElementType EXP = new PyElementType("EXP", "__pow__");// **
|
||||
public static final PyElementType DIV = new PyElementType("DIV", "__div__"); // /
|
||||
public static final PyElementType FLOORDIV = new PyElementType("FLOORDIV", "__floordiv__"); // //
|
||||
public static final PyElementType PERC = new PyElementType("PERC", "__mod__");// %
|
||||
public static final PyElementType LTLT = new PyElementType("LTLT", "__lshift__");// <<
|
||||
public static final PyElementType GTGT = new PyElementType("GTGT", "__rshift__");// >>
|
||||
public static final PyElementType AND = new PyElementType("AND", "__and__");// &
|
||||
public static final PyElementType OR = new PyElementType("OR", "__or__");// |
|
||||
public static final PyElementType XOR = new PyElementType("XOR", "__xor__");// ^
|
||||
public static final PyElementType TILDE = new PyElementType("TILDE", "__invert__");// ~
|
||||
public static final PyElementType LT = new PyElementType("LT", "__lt__");// <
|
||||
public static final PyElementType GT = new PyElementType("GT", "__gt__");// >
|
||||
public static final PyElementType LE = new PyElementType("LE", "__le__");// <=
|
||||
public static final PyElementType GE = new PyElementType("GE", "__ge__");// >=
|
||||
public static final PyElementType EQEQ = new PyElementType("EQEQ", "__eq__");// ==
|
||||
public static final PyElementType NE = new PyElementType("NE", "__ne__");// !=
|
||||
public static final PyElementType NE_OLD = new PyElementType("NE_OLD", "__ne__");// <>
|
||||
|
||||
// Delimiters
|
||||
public static final PyElementType LPAR = new PyElementType("LPAR");// (
|
||||
|
||||
@@ -49,11 +49,11 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
cat.append("class ").append(cls_name).append("\n ");
|
||||
// It would be nice to have class import info here, but we don't know the ctrl+hovered reference and context
|
||||
}
|
||||
return describeFunction(func, LSame2, ", ", LSame2, LSame1).toString();
|
||||
return describeDecorators(func, LSame2, ", ", LSame1).add(describeFunction(func, LSame2, LSame1)).toString();
|
||||
}
|
||||
else if (element instanceof PyClass) {
|
||||
PyClass cls = (PyClass)element;
|
||||
return describeClass(cls, LSame2).toString();
|
||||
return describeDecorators(cls, LSame2, ", ", LSame1).add(describeClass(cls, LSame2)).toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -75,18 +75,10 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
*/
|
||||
private static ChainIterable<String> describeFunction(
|
||||
PyFunction fun,
|
||||
FP.Lambda1<Iterable<String>, Iterable<String>> deco_name_wrapper,
|
||||
String deco_separator,
|
||||
FP.Lambda1<Iterable<String>, Iterable<String>> func_name_wrapper,
|
||||
FP.Lambda1<String, String> escaper
|
||||
) {
|
||||
ChainIterable<String> cat = new ChainIterable<String>(null);
|
||||
PyDecoratorList deco_list = fun.getDecoratorList();
|
||||
if (deco_list != null) {
|
||||
for (PyDecorator deco : deco_list.getDecorators()) {
|
||||
cat.add(describeDeco(deco, deco_name_wrapper, escaper)).add(deco_separator); // can't easily pass describeDeco to map() %)
|
||||
}
|
||||
}
|
||||
cat.add("def ").addWith(func_name_wrapper, $(fun.getName()));
|
||||
cat.add(escaper.apply(PyUtil.getReadableRepr(fun.getParameterList(), false)));
|
||||
final PyType returnType = fun.getReturnType();
|
||||
@@ -96,6 +88,20 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
return cat;
|
||||
}
|
||||
|
||||
private static ChainIterable<String> describeDecorators(
|
||||
PyDecoratable what, FP.Lambda1<Iterable<String>, Iterable<String>> deco_name_wrapper,
|
||||
String deco_separator, FP.Lambda1<String, String> escaper
|
||||
) {
|
||||
ChainIterable<String> cat = new ChainIterable<String>();
|
||||
PyDecoratorList deco_list = what.getDecoratorList();
|
||||
if (deco_list != null) {
|
||||
for (PyDecorator deco : deco_list.getDecorators()) {
|
||||
cat.add(describeDeco(deco, deco_name_wrapper, escaper)).add(deco_separator); // can't easily pass describeDeco to map() %)
|
||||
}
|
||||
}
|
||||
return cat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HTML description of function definition.
|
||||
* @param cls the class
|
||||
@@ -112,7 +118,6 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
if (ancestors.length > 0) {
|
||||
cat.add("(").add(interleave(FP.map(LReadableRepr, ancestors), ", ")).add(")");
|
||||
}
|
||||
// TODO: for py3k, show decorators
|
||||
return cat;
|
||||
}
|
||||
|
||||
@@ -260,6 +265,7 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
// doc of what?
|
||||
if (followed instanceof PyClass) {
|
||||
cls = (PyClass)followed;
|
||||
doc_cat.add(describeDecorators(cls, TagItalic, BR, LCombUp));
|
||||
doc_cat.addWith(TagSmall, describeClass(cls, TagBold));
|
||||
}
|
||||
else if (followed instanceof PyFunction) {
|
||||
@@ -269,7 +275,7 @@ public class PythonDocumentationProvider extends QuickDocumentationProvider {
|
||||
if (cls != null) doc_cat.addWith(TagSmall, $("class ", cls.getName(), BR));
|
||||
}
|
||||
else cls = null;
|
||||
doc_cat.add(describeFunction(fun, TagItalic, BR, TagBold, LCombUp));
|
||||
doc_cat.add(describeDecorators(fun, TagItalic, BR, LCombUp)).add(describeFunction(fun, TagBold, LCombUp));
|
||||
if (docString == null) {
|
||||
addInheritedDocString(fun, cls, doc_cat, epilog_cat);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -56,6 +59,27 @@ public class PyStatementEffectInspection extends PyInspection {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PyBinaryExpression) {
|
||||
PyBinaryExpression binary = (PyBinaryExpression)expression;
|
||||
String method = binary.getOperator().getSpecialMethodName();
|
||||
if (method != null) {
|
||||
// maybe the op is overridden and may produce side effects, like cout << "hello"
|
||||
PyType type = binary.getLeftExpression().getType(TypeEvalContext.fast());
|
||||
if (type != null && ! type.isBuiltin() && type.resolveMember(method, AccessDirection.READ) != null) {
|
||||
return;
|
||||
}
|
||||
final PyExpression rhs = binary.getRightExpression();
|
||||
if (rhs != null) {
|
||||
type = rhs.getType(TypeEvalContext.fast());
|
||||
if (type != null) {
|
||||
String rmethod = "__r" + method.substring(2); // __add__ -> __radd__
|
||||
if (! type.isBuiltin() && type.resolveMember(rmethod, AccessDirection.READ) != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PyTryPart tryPart = PsiTreeUtil.getParentOfType(node, PyTryPart.class);
|
||||
if (tryPart != null) {
|
||||
|
||||
@@ -16,7 +16,9 @@ import java.util.List;
|
||||
/**
|
||||
* Represents a class declaration in source.
|
||||
*/
|
||||
public interface PyClass extends PsiNamedElement, PyStatement, NameDefiner, PyDocStringOwner, StubBasedPsiElement<PyClassStub>, ScopeOwner {
|
||||
public interface PyClass extends
|
||||
PsiNamedElement, PyStatement, NameDefiner, PyDocStringOwner, StubBasedPsiElement<PyClassStub>, ScopeOwner, PyDecoratable
|
||||
{
|
||||
@Nullable
|
||||
ASTNode getNameNode();
|
||||
|
||||
@@ -101,8 +103,6 @@ public interface PyClass extends PsiNamedElement, PyStatement, NameDefiner, PyDo
|
||||
*/
|
||||
boolean isSubclass(PyClass parent);
|
||||
|
||||
@Nullable
|
||||
PyDecoratorList getDecoratorList();
|
||||
|
||||
String getQualifiedName();
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* TODO: Add description
|
||||
* User: dcheryasov
|
||||
* Date: Jul 8, 2010 3:48:14 AM
|
||||
*/
|
||||
public interface PyDecoratable {
|
||||
@Nullable
|
||||
PyDecoratorList getDecoratorList();
|
||||
}
|
||||
@@ -18,15 +18,23 @@ public class PyElementType extends IElementType {
|
||||
private static final Class[] PARAMETER_TYPES = new Class[]{ASTNode.class};
|
||||
private Constructor<? extends PsiElement> myConstructor;
|
||||
|
||||
private String mySpecialMethodName;
|
||||
|
||||
public PyElementType(@NotNull @NonNls String debugName) {
|
||||
super(debugName, PythonFileType.INSTANCE.getLanguage());
|
||||
}
|
||||
|
||||
|
||||
public PyElementType(@NonNls String debugName, Class<? extends PsiElement> psiElementClass) {
|
||||
this(debugName);
|
||||
_psiElementClass = psiElementClass;
|
||||
}
|
||||
|
||||
public PyElementType(@NotNull @NonNls String debugName, @NotNull @NonNls String specialMethodName) {
|
||||
this(debugName);
|
||||
mySpecialMethodName = specialMethodName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement createElement(ASTNode node) {
|
||||
if (_psiElementClass == null) {
|
||||
@@ -45,6 +53,13 @@ public class PyElementType extends IElementType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of special method for operation marked by this token; e.g. "__add__" for "+".
|
||||
*/
|
||||
public String getSpecialMethodName() {
|
||||
return mySpecialMethodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Py:" + super.toString();
|
||||
|
||||
@@ -17,8 +17,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface PyFunction
|
||||
extends
|
||||
PsiNamedElement, StubBasedPsiElement<PyFunctionStub>,
|
||||
PsiNameIdentifierOwner, PyStatement, Callable, NameDefiner, PyDocStringOwner, ScopeOwner
|
||||
{
|
||||
PsiNameIdentifierOwner, PyStatement, Callable, NameDefiner, PyDocStringOwner, ScopeOwner, PyDecoratable {
|
||||
PyFunction[] EMPTY_ARRAY = new PyFunction[0];
|
||||
|
||||
/**
|
||||
@@ -36,9 +35,6 @@ extends
|
||||
@Nullable
|
||||
PyClass getContainingClass();
|
||||
|
||||
@Nullable
|
||||
PyDecoratorList getDecoratorList();
|
||||
|
||||
/**
|
||||
* Returns true if the function is a top-level class (its parent is its containing file).
|
||||
*
|
||||
|
||||
@@ -231,6 +231,11 @@ public class PyClassType implements PyType {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return PyBuiltinCache.getInstance(myClass).hasInBuiltins(myClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<String> getPossibleInstanceMembers() {
|
||||
Set<String> ret = new HashSet<String>();
|
||||
|
||||
@@ -55,4 +55,9 @@ public class PyImportedModuleType implements PyType {
|
||||
public String getName() {
|
||||
return "PyImportedModuleType:" + myImportedModule.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false; // no module can be imported from builtins
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ public class PyModuleType implements PyType { // Maybe make it a PyClassType ref
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<String> getPossibleInstanceMembers() {
|
||||
return ourPossibleFields;
|
||||
|
||||
@@ -31,4 +31,9 @@ public class PyNoneType implements PyType { // TODO must extend ClassType. It's
|
||||
public String getName() {
|
||||
return "None";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.jetbrains.python.psi.types;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.Callable;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -23,4 +24,10 @@ public class PyReturnTypeReference extends PyTypeReferenceImpl {
|
||||
public String getName() {
|
||||
return "return type of " + myCallable.getPresentation().getPresentableText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
PyType type = myCallable.getReturnType();
|
||||
return type != null && type.isBuiltin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ public class PyTupleType extends PyClassType implements PySubscriptableType {
|
||||
}, ",") + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public PyType getElementType(PyExpression index, TypeEvalContext context) {
|
||||
final Object value = PyConstantExpressionEvaluator.evaluate(index);
|
||||
if (value instanceof Integer) {
|
||||
|
||||
@@ -48,4 +48,9 @@ public interface PyType {
|
||||
@Nullable
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @return true if the type is a known built-in type.
|
||||
*/
|
||||
boolean isBuiltin();
|
||||
|
||||
}
|
||||
|
||||
@@ -55,6 +55,17 @@ public class PyUnionType implements PyType {
|
||||
}, ", ") + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all types in the union are built-in.
|
||||
*/
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
for (PyType one : myMembers) {
|
||||
if (! one.isBuiltin()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType union(PyType type1, PyType type2) {
|
||||
if (type1 instanceof PyTupleType && type2 instanceof PyTupleType) {
|
||||
|
||||
Reference in New Issue
Block a user