mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 23:34:45 +08:00
First dynamic params working.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user