First dynamic params working.

This commit is contained in:
Dave Halter
2014-11-17 16:22:47 +01:00
parent 22f20ec715
commit 259aa6bd5f
3 changed files with 44 additions and 9 deletions

View File

@@ -87,7 +87,7 @@ from jedi.evaluate import finder
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import precedence from jedi.evaluate import precedence
from jedi.evaluate import param from jedi.evaluate import param
from jedi.evaluate.helpers import FakeStatement, deep_ast_copy from jedi.evaluate.helpers import FakeStatement, deep_ast_copy, call_of_name
class Evaluator(object): class Evaluator(object):
@@ -424,6 +424,10 @@ class Evaluator(object):
debug.dbg('execute result: %s in %s', types, obj) debug.dbg('execute result: %s in %s', types, obj)
return types return types
def goto_definition(self, name):
call = call_of_name(name)
return self.eval_element(call)
def goto(self, stmt, call_path): def goto(self, stmt, call_path):
if isinstance(stmt, pr.Import): if isinstance(stmt, pr.Import):
# Nowhere to goto for aliases # Nowhere to goto for aliases

View File

@@ -73,22 +73,23 @@ def search_params(evaluator, param):
stmt = name.get_definition() stmt = name.get_definition()
if not isinstance(stmt, pr.ExprStmt): if not isinstance(stmt, pr.ExprStmt):
continue continue
print(stmt, stmt.start_pos, name.parent)
try: try:
trailer = name.parent.children[1] trailer = name.parent.children[1]
except IndexError: except IndexError:
continue continue
else: else:
types = evaluator.goto(name) types = evaluator.goto_definition(name)
if compare in types: # TODO why not a direct comparison? functions seem to be
# decorated in types and not in compare...
if compare.base in [t.base for t in types if hasattr(t, 'base')]:
# Only if we have the correct function we execute # Only if we have the correct function we execute
# it, otherwise just ignore it. # it, otherwise just ignore it.
evaluator.eval_trailer(types, trailer) evaluator.eval_trailer(types, trailer)
# TODO REMOVE
continue continue
calls = helpers.scan_statement_for_calls(stmt, func_name) calls = helpers.scan_statement_for_calls(stmt, func_name)
for c in calls: for c in calls:
# no execution means that params cannot be set # no execution means that params cannot be set
@@ -115,7 +116,6 @@ def search_params(evaluator, param):
if before: if before:
scopes = evaluator.eval_call_path(iter(before), c.parent, pos) scopes = evaluator.eval_call_path(iter(before), c.parent, pos)
pos = None pos = None
from jedi.evaluate import representation as er
for scope in scopes: for scope in scopes:
# Not resolving decorators is a speed hack: # Not resolving decorators is a speed hack:
# By ignoring them, we get the function that is # By ignoring them, we get the function that is
@@ -138,8 +138,8 @@ def search_params(evaluator, param):
result = [] result = []
for params in get_posibilities(evaluator, module, func_name): for params in get_posibilities(evaluator, module, func_name):
for p in params: for p in params:
if str(p) == param.name: if str(p) == str(param.get_name()):
result += evaluator.eval_statement(p.get_definition()) result += p.parent.eval(evaluator)
return result return result
func = param.get_parent_until(pr.Function) func = param.get_parent_until(pr.Function)
@@ -149,6 +149,7 @@ def search_params(evaluator, param):
if func_name == '__init__' and isinstance(func.parent, pr.Class): if func_name == '__init__' and isinstance(func.parent, pr.Class):
func_name = unicode(func.parent.name) func_name = unicode(func.parent.name)
compare = func.parent compare = func.parent
compare = er.wrap(evaluator, compare)
# add the listener # add the listener
listener = ParamListener() listener = ParamListener()

View File

@@ -97,6 +97,36 @@ def deep_ast_copy(obj, new_elements_default=None):
return recursion(obj) return recursion(obj)
def call_of_name(name):
"""
Creates a "call" node that consist of all ``trailer`` and ``power``
objects. E.g. if you call it with ``append``::
list([]).append(3) or None
You would get a node with the content ``list([]).append`` back.
This generates a copy of the original ast node.
"""
par = name
if pr.is_node(par.parent, 'trailer'):
par = par.parent
power = par.parent
if pr.is_node(power, 'power') and power.children[0] != name \
and not (power.children[-2] == '**' and
name.start_pos > power.children[-1].start_pos):
par = power
# Now the name must be part of a trailer
index = par.children.index(name.parent)
if index != len(par.children) - 1:
# Now we have to cut the other trailers away.
par = deep_ast_copy(par)
par.children[index + 1:] = []
return par
def call_signature_array_for_pos(stmt, pos): def call_signature_array_for_pos(stmt, pos):
""" """
Searches for the array and position of a tuple. Searches for the array and position of a tuple.