1
0
forked from VimPlug/jedi

Trying to get ird of the weird param generation in the parser tree.

This commit is contained in:
Dave Halter
2015-02-10 15:49:26 +01:00
parent 8775d90173
commit cdbe26786a
9 changed files with 71 additions and 72 deletions

View File

@@ -339,7 +339,7 @@ class BaseDefinition(object):
params = sub.params[1:] # ignore self
except KeyError:
return []
return [_Param(self._evaluator, p.get_name()) for p in params]
return [_Param(self._evaluator, p.name) for p in params]
def parent(self):
scope = self._definition.get_parent_scope()

View File

@@ -230,7 +230,7 @@ def save_parser(path, name, parser, pickling=True):
class ParserPickling(object):
version = 23
version = 24
"""
Version number (integer) for file system cache.

View File

@@ -176,7 +176,7 @@ def follow_param(evaluator, param):
return [p
for param_str in _search_param_in_docstr(func.raw_doc,
str(param.get_name()))
str(param.name))
for p in _evaluate_for_statement_string(evaluator, param_str,
param.get_parent_until())]

View File

@@ -59,7 +59,7 @@ def search_params(evaluator, param):
"""
for params in get_posibilities(evaluator, module, func_name):
for p in params:
if str(p) == str(param.get_name()):
if str(p) == str(param.name):
result += p.parent.eval(evaluator)
"""
# Compare the param names.

View File

@@ -82,6 +82,7 @@ class NameFinder(object):
@debug.increase_indent
def find(self, scopes, search_global=False):
# TODO rename scopes to names_dicts
names = self.filter_name(scopes)
types = self._names_to_types(names, search_global)
@@ -109,7 +110,7 @@ class NameFinder(object):
def names_dict_lookup(self, names_dict, position):
def get_param(scope, el):
if isinstance(el.parent, pr.Param) or isinstance(el.parent.parent, pr.Param):
if isinstance(el.get_parent_until(pr.Param), pr.Param):
return scope.param_by_name(str(el))
return el
@@ -331,7 +332,7 @@ def _remove_statements(evaluator, stmt, name):
def _eval_param(evaluator, param, scope):
res_new = []
func = param.parent
func = param.get_parent_scope()
cls = func.parent.get_parent_until((pr.Class, pr.Function))

View File

@@ -70,7 +70,7 @@ def deep_ast_copy(obj, new_elements_default=None, check_first=False):
setattr(new_obj, key, new_elements[value])
except KeyError:
unfinished_parents.append(new_obj)
elif key in ['parent_function', 'use_as_parent', '_sub_module']:
elif key == 'position_modifier':
continue
elif key == 'names_dict':
d = dict((k, sequence_recursion(v)) for k, v in value.items())

View File

@@ -199,7 +199,7 @@ def get_params(evaluator, func, var_args):
param_names = []
param_dict = {}
for param in func.params:
param_dict[str(param.get_name())] = param
param_dict[str(param.name)] = param
unpacked_va = list(var_args.unpack(func))
from jedi.evaluate.representation import InstanceElement
if isinstance(func, InstanceElement):
@@ -279,7 +279,7 @@ def get_params(evaluator, func, var_args):
# Now add to result if it's not one of the previously covered cases.
if (not keys_only or param.stars == 2):
param_names.append(ExecutedParam(param, var_args, values).name)
keys_used[unicode(param.get_name())] = param_names[-1]
keys_used[unicode(param.name)] = param_names[-1]
if keys_only:
# All arguments should be handed over to the next function. It's not

View File

@@ -140,7 +140,7 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
normally self.
"""
try:
return str(func.params[0].get_name())
return str(func.params[0].name)
except IndexError:
return None

View File

@@ -281,12 +281,10 @@ class Name(Leaf):
def is_definition(self):
stmt = self.get_definition()
if stmt.type in ('funcdef', 'classdef', 'file_input'):
if stmt.type in ('funcdef', 'classdef', 'file_input', 'param'):
return self == stmt.name
elif stmt.type == 'for_stmt':
return self.start_pos < stmt.children[2].start_pos
elif stmt.type == 'param':
return self == stmt.get_name()
elif stmt.type == 'try_stmt':
return self.prev_sibling() == 'as'
else:
@@ -704,40 +702,32 @@ class Class(ClassOrFunc):
return docstr
def _create_params(function, lst):
if not lst:
def _create_params(parent, argslist_list):
"""
TODO DOC
This is a function to hack the general parser structure.
Preparing the replacement of *argslist with a list of Params.
"""
if not argslist_list:
return []
if is_node(lst[0], 'typedargslist', 'varargslist'):
params = []
iterator = iter(lst[0].children)
for n in iterator:
stars = 0
if n in ('*', '**'):
stars = len(n.value)
n = next(iterator)
op = next(iterator, None)
if op == '=':
default = next(iterator)
next(iterator, None)
else:
default = None
params.append(Param(n, function, default, stars))
if argslist_list[0].type == 'name':
return [Param([argslist_list[0]], parent)]
else: # argslist is a `typedargslist` or a `varargslist`.
children = argslist_list[0].children
params = []
start = 0
# Start with offset 1, because the end is higher.
for end, child in enumerate(children + [None], 1):
if child is None or child == ',':
params.append(Param(children[start:end], parent))
start = end
return params
else:
return [Param(lst[0], function)]
class Function(ClassOrFunc):
"""
Used to store the parsed contents of a python function.
:param name: The Function name.
:type name: str
:param params: The parameters (Statement) of a Function.
:type params: list
:param start_pos: The start position (line, column) the Function.
:type start_pos: tuple(int, int)
"""
__slots__ = ('listeners', 'params')
type = 'funcdef'
@@ -745,8 +735,12 @@ class Function(ClassOrFunc):
def __init__(self, children):
super(Function, self).__init__(children)
self.listeners = set() # not used here, but in evaluation.
lst = self.children[2].children[1:-1] # After `def foo`
self.params = _create_params(self, lst)
parameters = self.children[2] # After `def foo`
parameters.children[1:-1] = _create_params(parameters, parameters.children[1:-1])
@property
def params(self):
return self.children[2].children[1:-1]
@property
def name(self):
@@ -796,10 +790,11 @@ class Lambda(Function):
__slots__ = ()
def __init__(self, children):
# We don't want to call the Function constructor, call its parent.
super(Function, self).__init__(children)
self.listeners = set() # not used here, but in evaluation.
lst = self.children[1:-2] # After `def foo`
self.params = _create_params(self, lst)
self.children[1:-2] = _create_params(self, lst)
def is_generator(self):
return False
@@ -1119,48 +1114,51 @@ class ExprStmt(BaseNode, DocstringMixin):
return None
class Param(Base):
class Param(BaseNode):
"""
The class which shows definitions of params of classes and functions.
But this is not to define function calls.
A helper class for functions. Read only.
It's a helper class that makes business logic with params much easier. The
Python grammar defines no ``param`` node. It defines it in a different way
that is not really suited to working with parameters.
"""
__slots__ = ('tfpdef', 'default', 'stars', 'parent')
# Even though it's not not an official node, just give it one, because that
# makes checking more consistent.
type = 'param'
def __init__(self, tfpdef, parent, default=None, stars=0):
self.tfpdef = tfpdef # tfpdef: see grammar.txt
self.default = default
self.stars = stars
def __init__(self, children, parent):
super(Param, self).__init__(children)
self.parent = parent
# Here we reset the parent of our name. IMHO this is ok.
self.get_name().parent = self
for child in children:
child.parent = self
@property
def stars(self):
first = self.children[0]
if first in ('*', '**'):
return len(first.value)
return 0
@property
def default(self):
try:
return self.children[int(self.children[0] in ('*', '**')) + 1]
except IndexError:
return None
def annotation(self):
# Generate from tfpdef.
raise NotImplementedError
@property
def children(self):
return []
@property
def start_pos(self):
return self.tfpdef.start_pos
def get_name(self):
# TODO remove!
return self.name
def _tfpdef(self):
"""
tfpdef: see grammar.txt.
"""
offset = int(self.children[0] in ('*', '**'))
return self.children[offset]
@property
def name(self):
if is_node(self.tfpdef, 'tfpdef'):
return self.tfpdef.children[0]
if is_node(self._tfpdef(), 'tfpdef'):
return self._tfpdef().children[0]
else:
return self.tfpdef
return self._tfpdef()
@property
def position_nr(self):
@@ -1172,11 +1170,11 @@ class Param(Base):
def get_code(self):
df = '' if self.default is None else '=' + self.default.get_code()
return self.tfpdef.get_code() + df
return self._tfpdef().get_code() + df
def __repr__(self):
default = '' if self.default is None else '=%s' % self.default
return '<%s: %s>' % (type(self).__name__, str(self.tfpdef) + default)
return '<%s: %s>' % (type(self).__name__, str(self._tfpdef()) + default)
class CompFor(BaseNode):