1
0
forked from VimPlug/jedi

Fix comprehensions type issues.

This commit is contained in:
Dave Halter
2015-09-22 02:13:20 +02:00
parent 4ffc24a919
commit 3a306a4f25
5 changed files with 47 additions and 26 deletions

View File

@@ -30,6 +30,7 @@ from jedi.evaluate import Evaluator
from jedi.evaluate import representation as er
from jedi.evaluate import compiled
from jedi.evaluate import imports
from jedi.evaluate.param import try_iter_content
from jedi.evaluate.cache import memoize_default
from jedi.evaluate.helpers import FakeName, get_module_names
from jedi.evaluate.finder import global_names_dict_generator, filter_definition_names
@@ -524,32 +525,27 @@ class Script(object):
for o in origins if hasattr(o, 'py__call__')]
def _analysis(self):
def check_types(types):
for typ in types:
try:
f = typ.iter_content
except AttributeError:
pass
self._evaluator.is_analysis = True
try:
for node in self._parser.module().nodes_to_execute():
if node.type in ('funcdef', 'classdef'):
if node.type == 'classdef':
continue
raise NotImplementedError
er.Function(self._evaluator, node).get_decorated_func()
elif isinstance(node, tree.Import):
import_names = set(node.get_defined_names())
if node.is_nested():
import_names |= set(path[-1] for path in node.paths())
for n in import_names:
imports.ImportWrapper(self._evaluator, n).follow()
else:
check_types(f())
try_iter_content(self._evaluator.eval_element(node))
for node in self._parser.module().nodes_to_execute():
if node.type in ('funcdef', 'classdef'):
if node.type == 'classdef':
continue
raise NotImplementedError
er.Function(self._evaluator, node).get_decorated_func()
elif isinstance(node, tree.Import):
import_names = set(node.get_defined_names())
if node.is_nested():
import_names |= set(path[-1] for path in node.paths())
for n in import_names:
imports.ImportWrapper(self._evaluator, n).follow()
else:
check_types(self._evaluator.eval_element(node))
ana = [a for a in self._evaluator.analysis if self.path == a.path]
return sorted(set(ana), key=lambda x: x.line)
ana = [a for a in self._evaluator.analysis if self.path == a.path]
return sorted(set(ana), key=lambda x: x.line)
finally:
self._evaluator.is_analysis = False
class Interpreter(Script):

View File

@@ -89,6 +89,7 @@ class Evaluator(object):
self.execution_recursion_detector = recursion.ExecutionRecursionDetector()
self.analysis = []
self.predefined_if_name_dict_dict = {}
self.is_analysis = False
def wrap(self, element):
if isinstance(element, tree.Class):
@@ -343,6 +344,9 @@ class Evaluator(object):
if not isinstance(arguments, param.Arguments):
arguments = param.Arguments(self, arguments, trailer)
if self.is_analysis:
arguments.eval_all()
if obj.isinstance(er.Function):
obj = obj.get_decorated_func()

View File

@@ -148,7 +148,7 @@ class Comprehension(IterableWrapper):
return [self._evaluator.eval_element(self.eval_node())[index]]
def __repr__(self):
return "<e%s of %s>" % (type(self).__name__, self._atom)
return "<%s of %s>" % (type(self).__name__, self._atom)
class ArrayMixin(object):

View File

@@ -12,6 +12,17 @@ from jedi.evaluate.helpers import FakeName
from jedi.cache import underscore_memoization
def try_iter_content(types):
"""Helper method for static analysis."""
for typ in types:
try:
f = typ.iter_content
except AttributeError:
pass
else:
try_iter_content(f())
class Arguments(tree.Base):
def __init__(self, evaluator, argument_node, trailer=None):
"""
@@ -160,6 +171,16 @@ class Arguments(tree.Base):
else:
return None
def eval_all(self, func=None):
"""
Evaluates all arguments as a support for static analysis
(normally Jedi).
"""
for key, element_values in self.unpack():
for element in element_values:
types = self._evaluator.eval_element(element)
try_iter_content(types)
class ExecutedParam(tree.Param):
"""Fake a param and give it values."""

View File

@@ -517,7 +517,7 @@ class Node(BaseNode):
For static analysis.
"""
result = []
if self.type not in Node._IGNORE_EXECUTE_NODES:
if self.type not in Node._IGNORE_EXECUTE_NODES and not last_added:
result.append(self)
last_added = True