Remove the ImportWrapper and replace it with something simpler.

This commit is contained in:
Dave Halter
2016-12-17 16:08:37 +01:00
parent 173c939956
commit 57857b6332
7 changed files with 53 additions and 74 deletions

View File

@@ -338,7 +338,7 @@ class Script(object):
if node.is_nested(): if node.is_nested():
import_names |= set(path[-1] for path in node.paths()) import_names |= set(path[-1] for path in node.paths())
for n in import_names: for n in import_names:
imports.ImportWrapper(context, n).follow() imports.infer_import(context, n)
elif node.type == 'expr_stmt': elif node.type == 'expr_stmt':
types = context.eval_node(node) types = context.eval_node(node)
for testlist in node.children[:-1:2]: for testlist in node.children[:-1:2]:

View File

@@ -500,8 +500,7 @@ class Completion(BaseDefinition):
definition = self._definition definition = self._definition
if definition.isinstance(tree.Import): if definition.isinstance(tree.Import):
raise DeprecationWarning raise DeprecationWarning
i = imports.ImportWrapper(self._evaluator, self._name) return imports.infer_import(self._evaluator, self._name)
return i.follow()
return super(Completion, self)._follow_statements_imports() return super(Completion, self)._follow_statements_imports()
@memoize_method @memoize_method

View File

@@ -59,6 +59,10 @@ def resolve_potential_imports(evaluator, definitions):
if isinstance(d, TreeNameDefinition): if isinstance(d, TreeNameDefinition):
imp_or_stmt = d.tree_name.get_definition() imp_or_stmt = d.tree_name.get_definition()
if isinstance(imp_or_stmt, tree.Import): if isinstance(imp_or_stmt, tree.Import):
s = imports.ImportWrapper(d.parent_context, d.tree_name) new |= resolve_potential_imports(
new |= resolve_potential_imports(evaluator, set(s.follow(is_goto=True))) evaluator,
set(imports.infer_import(
d.parent_context, d.tree_name, is_goto=True
))
)
return set(definitions) | new return set(definitions) | new

View File

@@ -451,21 +451,11 @@ class Evaluator(object):
for_types = iterable.py__iter__types(self, container_types, def_.children[3]) for_types = iterable.py__iter__types(self, container_types, def_.children[3])
return finder.check_tuple_assignments(self, for_types, name) return finder.check_tuple_assignments(self, for_types, name)
elif def_.type in ('import_from', 'import_name'): elif def_.type in ('import_from', 'import_name'):
return imports.ImportWrapper(context, name).follow() return imports.infer_import(context, name)
return helpers.evaluate_call_of_leaf(context, name) return helpers.evaluate_call_of_leaf(context, name)
def goto(self, context, name): def goto(self, context, name):
def resolve_implicit_imports(names):
for name in names:
if isinstance(name.parent, helpers.FakeImport):
# Those are implicit imports.
s = imports.ImportWrapper(context, name)
for n in s.follow(is_goto=True):
yield n
else:
yield name
stmt = name.get_definition() stmt = name.get_definition()
par = name.parent par = name.parent
if par.type == 'argument' and par.children[1] == '=' and par.children[0] == name: if par.type == 'argument' and par.children[1] == '=' and par.children[0] == name:
@@ -500,9 +490,8 @@ class Evaluator(object):
elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name: elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name:
return [TreeNameDefinition(context, name)] return [TreeNameDefinition(context, name)]
elif isinstance(stmt, tree.Import): elif isinstance(stmt, tree.Import):
module_names = imports.ImportWrapper(context, name).follow(is_goto=True) module_names = imports.infer_import(context, name, is_goto=True)
return module_names return module_names
return list(resolve_implicit_imports(module_names))
elif par.type == 'dotted_name': # Is a decorator. elif par.type == 'dotted_name': # Is a decorator.
index = par.children.index(name) index = par.children.index(name)
if index > 0: if index > 0:
@@ -513,9 +502,6 @@ class Evaluator(object):
value.py__getattribute__(name, name_context=context, is_goto=True) value.py__getattribute__(name, name_context=context, is_goto=True)
for value in values for value in values
) )
#return resolve_implicit_imports(iterable.unite(
#self.find_types(typ, name, is_goto=True) for typ in types
#))
if tree.is_node(par, 'trailer') and par.children[0] == '.': if tree.is_node(par, 'trailer') and par.children[0] == '.':
values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True)
@@ -523,9 +509,6 @@ class Evaluator(object):
value.py__getattribute__(name, name_context=context, is_goto=True) value.py__getattribute__(name, name_context=context, is_goto=True)
for value in values for value in values
) )
#return resolve_implicit_imports(iterable.unite(
#self.find_types(typ, name, is_goto=True) for typ in types
#))
else: else:
if stmt.type != 'expr_stmt': if stmt.type != 'expr_stmt':
# We only need to adjust the start_pos for statements, because # We only need to adjust the start_pos for statements, because

View File

@@ -362,7 +362,7 @@ def _name_to_types(evaluator, context, name):
elif node.isinstance(tree.WithStmt): elif node.isinstance(tree.WithStmt):
types = context.eval_node(node.node_from_name(name)) types = context.eval_node(node.node_from_name(name))
elif isinstance(node, tree.Import): elif isinstance(node, tree.Import):
types = imports.ImportWrapper(context, name).follow() types = imports.infer_import(context, name)
elif node.type in ('funcdef', 'classdef'): elif node.type in ('funcdef', 'classdef'):
types = _apply_decorators(evaluator, context, node) types = _apply_decorators(evaluator, context, node)
elif node.type == 'global_stmt': elif node.type == 'global_stmt':

View File

@@ -56,18 +56,12 @@ def completion_names(evaluator, imp, pos):
return importer.completion_names(evaluator, only_modules) return importer.completion_names(evaluator, only_modules)
class ImportWrapper(object): def infer_import(context, tree_name, is_goto=False):
def __init__(self, context, name): module_context = context.get_root_context()
self._context = context import_node = tree_name.get_parent_until(tree.Import)
self._name = name import_path = import_node.path_for_name(tree_name)
# TODO move this whole thing to a function
def follow(self, is_goto=False):
module_context = self._context.get_root_context()
import_node = self._name.get_parent_until(tree.Import)
import_path = import_node.path_for_name(self._name)
from_import_name = None from_import_name = None
evaluator = self._context.evaluator evaluator = context.evaluator
try: try:
from_names = import_node.get_from_names() from_names = import_node.get_from_names()
except AttributeError: except AttributeError:
@@ -83,7 +77,6 @@ class ImportWrapper(object):
importer = Importer(evaluator, tuple(import_path), importer = Importer(evaluator, tuple(import_path),
module_context, import_node.level) module_context, import_node.level)
# TODO This is terrible, why different Importer instances?
types = importer.follow() types = importer.follow()
#if import_node.is_nested() and not self.nested_resolve: #if import_node.is_nested() and not self.nested_resolve:
@@ -93,7 +86,7 @@ class ImportWrapper(object):
types = unite( types = unite(
t.py__getattribute__( t.py__getattribute__(
unicode(from_import_name), unicode(from_import_name),
name_context=self._context, name_context=context,
is_goto=is_goto is_goto=is_goto
) for t in types ) for t in types
) )

View File

@@ -505,7 +505,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
for i in self.module_node.imports: for i in self.module_node.imports:
if i.is_star_import(): if i.is_star_import():
name = i.star_import_name() name = i.star_import_name()
new = imports.ImportWrapper(self, name).follow() new = imports.infer_import(self, name)
for module in new: for module in new:
if isinstance(module, ModuleContext): if isinstance(module, ModuleContext):
modules += module.star_imports() modules += module.star_imports()