Deprecate Evaluator.wrap.

This commit is contained in:
Dave Halter
2016-11-01 23:38:06 +01:00
parent 2eb701d2d2
commit f57455f0ad
5 changed files with 74 additions and 65 deletions

View File

@@ -132,15 +132,19 @@ class Script(object):
debug.speed('init') debug.speed('init')
@cache.memoize_method @cache.memoize_method
def _get_module(self): def _get_module_node(self):
cache.invalidate_star_import_cache(self._path) cache.invalidate_star_import_cache(self._path)
parser = FastParser(self._grammar, self._source, self.path) parser = FastParser(self._grammar, self._source, self.path)
save_parser(self.path, parser, pickling=False) save_parser(self.path, parser, pickling=False)
module = self._evaluator.wrap(parser.module, parent_context=None)
imports.add_module(self._evaluator, unicode(module.name), module)
return parser.module return parser.module
@cache.memoize_method
def _get_module(self):
module = er.ModuleContext(self._evaluator, self._get_module_node())
imports.add_module(self._evaluator, unicode(module.name), module)
return module
@property @property
def source_path(self): def source_path(self):
""" """
@@ -183,13 +187,14 @@ class Script(object):
:rtype: list of :class:`classes.Definition` :rtype: list of :class:`classes.Definition`
""" """
leaf = self._get_module().name_for_position(self._pos) module_node = self._get_module_node()
leaf = module_node.name_for_position(self._pos)
if leaf is None: if leaf is None:
leaf = self._get_module().get_leaf_for_position(self._pos) leaf = module_node.get_leaf_for_position(self._pos)
if leaf is None: if leaf is None:
return [] return []
context = self._evaluator.create_context(leaf) context = self._evaluator.create_context(self._get_module(), leaf)
definitions = helpers.evaluate_goto_definition(self._evaluator, context, leaf) definitions = helpers.evaluate_goto_definition(self._evaluator, context, leaf)
names = [s.name for s in definitions] names = [s.name for s in definitions]
@@ -229,7 +234,7 @@ class Script(object):
""" """
Used for goto_assignments and usages. Used for goto_assignments and usages.
""" """
name = self._get_module().name_for_position(self._pos) name = self._get_module_node().name_for_position(self._pos)
if name is None: if name is None:
return [] return []
return list(self._evaluator.goto(name)) return list(self._evaluator.goto(name))
@@ -248,7 +253,8 @@ class Script(object):
temp, settings.dynamic_flow_information = \ temp, settings.dynamic_flow_information = \
settings.dynamic_flow_information, False settings.dynamic_flow_information, False
try: try:
user_stmt = self._get_module().get_statement_for_position(self._pos) module_node = self._get_module_node()
user_stmt = module_node.get_statement_for_position(self._pos)
definitions = self._goto() definitions = self._goto()
if not definitions and isinstance(user_stmt, tree.Import): if not definitions and isinstance(user_stmt, tree.Import):
# For not defined imports (goto doesn't find something, we take # For not defined imports (goto doesn't find something, we take
@@ -270,7 +276,7 @@ class Script(object):
definitions) definitions)
module = set([d.get_parent_until() for d in definitions]) module = set([d.get_parent_until() for d in definitions])
module.add(self._get_module()) module.add(module_node)
names = usages.usages(self._evaluator, definitions, module) names = usages.usages(self._evaluator, definitions, module)
for d in set(definitions): for d in set(definitions):
@@ -297,7 +303,7 @@ class Script(object):
:rtype: list of :class:`classes.CallSignature` :rtype: list of :class:`classes.CallSignature`
""" """
call_signature_details = \ call_signature_details = \
helpers.get_call_signature_details(self._get_module(), self._pos) helpers.get_call_signature_details(self._get_module_node(), self._pos)
if call_signature_details is None: if call_signature_details is None:
return [] return []
@@ -320,9 +326,10 @@ class Script(object):
def _analysis(self): def _analysis(self):
self._evaluator.is_analysis = True self._evaluator.is_analysis = True
self._evaluator.analysis_modules = [self._get_module()] module_node = self._get_module_node()
self._evaluator.analysis_modules = [module_node]
try: try:
for node in self._get_module().nodes_to_execute(): for node in module_node.nodes_to_execute():
if node.type in ('funcdef', 'classdef'): if node.type in ('funcdef', 'classdef'):
if node.type == 'classdef': if node.type == 'classdef':
continue continue
@@ -387,11 +394,9 @@ class Interpreter(Script):
super(Interpreter, self).__init__(source, **kwds) super(Interpreter, self).__init__(source, **kwds)
self.namespaces = namespaces self.namespaces = namespaces
parser_module = super(Interpreter, self)._get_module() def _get_module_node(self):
self._module = interpreter.MixedModule(self._evaluator, parser_module, self.namespaces) parser_module = super(Interpreter, self)._get_module_node()
return interpreter.MixedModule(self._evaluator, parser_module, self.namespaces)
def _get_module(self):
return self._module
def defined_names(source, path=None, encoding='utf-8'): def defined_names(source, path=None, encoding='utf-8'):
@@ -437,7 +442,7 @@ def names(source=None, path=None, encoding='utf-8', all_scopes=False,
# Set line/column to a random position, because they don't matter. # Set line/column to a random position, because they don't matter.
script = Script(source, line=1, column=0, path=path, encoding=encoding) script = Script(source, line=1, column=0, path=path, encoding=encoding)
defs = [classes.Definition(script._evaluator, name_part) defs = [classes.Definition(script._evaluator, name_part)
for name_part in get_module_names(script._get_module(), all_scopes)] for name_part in get_module_names(script._get_module().module_node, all_scopes)]
return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column)) return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column))

View File

@@ -47,11 +47,11 @@ def filter_names(evaluator, completion_names, stack, like_name):
yield new yield new
def get_user_scope(module, position): def get_user_scope(module_context, position):
""" """
Returns the scope in which the user resides. This includes flows. Returns the scope in which the user resides. This includes flows.
""" """
user_stmt = module.get_statement_for_position(position) user_stmt = module_context.module_node.get_statement_for_position(position)
if user_stmt is None: if user_stmt is None:
def scan(scope): def scan(scope):
for s in scope.children: for s in scope.children:
@@ -62,20 +62,20 @@ def get_user_scope(module, position):
return scan(s) return scan(s)
return None return None
return scan(module) or module return scan(module) or module_context
else: else:
return user_stmt.get_parent_scope(include_flows=True) return user_stmt.get_parent_scope(include_flows=True)
class Completion: class Completion:
def __init__(self, evaluator, module_node, code_lines, position, call_signatures_method): def __init__(self, evaluator, module, code_lines, position, call_signatures_method):
self._evaluator = evaluator self._evaluator = evaluator
self._module_node = module_node self._module_context = module
self._module = evaluator.wrap(module_node, parent_context=None) self._module_node = module.module_node
self._code_lines = code_lines self._code_lines = code_lines
# The first step of completions is to get the name # The first step of completions is to get the name
self._like_name = helpers.get_on_completion_name(module_node, code_lines, position) self._like_name = helpers.get_on_completion_name(self._module_node, code_lines, position)
# The actual cursor position is not what we need to calculate # The actual cursor position is not what we need to calculate
# everything. We want the start of the name we're on. # everything. We want the start of the name we're on.
self._position = position[0], position[1] - len(self._like_name) self._position = position[0], position[1] - len(self._like_name)
@@ -172,10 +172,10 @@ class Completion:
yield keywords.keyword(self._evaluator, k).name yield keywords.keyword(self._evaluator, k).name
def _global_completions(self): def _global_completions(self):
scope = get_user_scope(self._module_node, self._position) scope = get_user_scope(self._module_context, self._position)
if not scope.is_scope(): # Might be a flow (if/while/etc). if not scope.is_scope(): # Might be a flow (if/while/etc).
scope = scope.get_parent_scope() scope = scope.get_parent_scope()
scope = self._evaluator.create_context(scope) scope = self._evaluator.create_context(self._module_context, scope)
debug.dbg('global completion scope: %s', scope) debug.dbg('global completion scope: %s', scope)
filters = get_global_filters( filters = get_global_filters(
self._evaluator, self._evaluator,
@@ -189,8 +189,9 @@ class Completion:
return completion_names return completion_names
def _trailer_completions(self, atom_expr): def _trailer_completions(self, atom_expr):
user_scope = get_user_scope(self._module_node, self._position) user_scope = get_user_scope(self._module_context, self._position)
contexts = self._evaluator.eval_element(self._evaluator.create_context(atom_expr), atom_expr) evaluation_context = self._evaluator.create_context(self._module_context, atom_expr)
contexts = self._evaluator.eval_element(evaluation_context, atom_expr)
completion_names = [] completion_names = []
debug.dbg('trailer completion contexts: %s', contexts) debug.dbg('trailer completion contexts: %s', contexts)
for context in contexts: for context in contexts:
@@ -215,7 +216,7 @@ class Completion:
def _get_importer_names(self, names, level=0, only_modules=True): def _get_importer_names(self, names, level=0, only_modules=True):
names = [str(n) for n in names] names = [str(n) for n in names]
i = imports.Importer(self._evaluator, names, self._module, level) i = imports.Importer(self._evaluator, names, self._module_context, level)
return i.completion_names(self._evaluator, only_modules=only_modules) return i.completion_names(self._evaluator, only_modules=only_modules)
def _get_class_context_completions(self, is_function=True): def _get_class_context_completions(self, is_function=True):

View File

@@ -110,19 +110,6 @@ class Evaluator(object):
self.recursion_detector = recursion.RecursionDetector(self) self.recursion_detector = recursion.RecursionDetector(self)
self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self) self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self)
def wrap(self, element, parent_context):
if element.type == 'classdef':
return er.ClassContext(self, element, parent_context)
elif element.type == 'funcdef':
return er.AnonymousFunctionExecution(self, parent_context, element)
elif element.type == 'lambda':
return er.LambdaWrapper(self, element)
elif element.type == 'file_input':
return er.ModuleContext(self, element)
else:
raise DeprecationWarning
return element
def find_types(self, context, name_str, position=None, search_global=False, def find_types(self, context, name_str, position=None, search_global=False,
is_goto=False): is_goto=False):
""" """
@@ -515,16 +502,33 @@ class Evaluator(object):
return self.find_types(scope, name, stmt.start_pos, return self.find_types(scope, name, stmt.start_pos,
search_global=True, is_goto=True) search_global=True, is_goto=True)
def create_context(self, node): def wrap(self, element, parent_context):
def from_scope(scope): raise DeprecationWarning
if element.type == 'classdef':
return er.ClassContext(self, element, parent_context)
elif element.type == 'lambda':
return er.LambdaWrapper(self, element)
elif element.type == 'file_input':
return er.ModuleContext(self, element)
else:
raise DeprecationWarning
return element
def create_context(self, module_context, node):
def from_scope_node(scope_node):
parent_context = None parent_context = None
parent_scope = scope.get_parent_scope() parent_scope = scope_node.get_parent_scope()
if parent_scope is not None: if parent_scope is not None:
parent_context = from_scope(parent_scope) parent_context = from_scope_node(parent_scope)
if scope_node == module_context.module_node:
return module_context
elif scope_node.type == 'funcdef':
return er.AnonymousFunctionExecution(self, parent_context, scope_node)
raise DeprecationWarning
return self.wrap(scope, parent_context=parent_context) return self.wrap(scope, parent_context=parent_context)
if node.is_scope(): if node.is_scope():
scope = node scope_node = node
else: else:
scope = node.get_parent_scope() scope_node = node.get_parent_scope()
return from_scope(scope) return from_scope_node(scope_node)

View File

@@ -734,10 +734,9 @@ class GlobalName(helpers.FakeName):
class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)): class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
parent_context = None parent_context = None
def __init__(self, evaluator, module, parent_module=None): def __init__(self, evaluator, module_node):
self._evaluator = evaluator super(ModuleContext, self).__init__(evaluator, parent_context=None)
self.base = self._module = module self.module_node = module_node
self._parent_module = parent_module
self.path = None self.path = None
def names_dicts(self, search_global): def names_dicts(self, search_global):
@@ -754,11 +753,11 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
yield ParserTreeFilter( yield ParserTreeFilter(
self._evaluator, self._evaluator,
self, self,
self._module, self.module_node,
until_position, until_position,
origin_scope=origin_scope origin_scope=origin_scope
) )
yield GlobalNameFilter(self, self._module) yield GlobalNameFilter(self, self.module_node)
yield DictFilter(self._sub_modules_dict()) yield DictFilter(self._sub_modules_dict())
yield DictFilter(self._module_attributes_dict()) yield DictFilter(self._module_attributes_dict())
# TODO # TODO
@@ -774,7 +773,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
@memoize_default([]) @memoize_default([])
def star_imports(self): def star_imports(self):
modules = [] modules = []
for i in self.base.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._evaluator, name).follow() new = imports.ImportWrapper(self._evaluator, name).follow()
@@ -798,7 +797,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
@property @property
@memoize_default() @memoize_default()
def name(self): def name(self):
return ContextName(self, self.base.name) return ContextName(self, self.module_node.name)
def _get_init_directory(self): def _get_init_directory(self):
""" """
@@ -824,10 +823,10 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
""" """
In contrast to Python's __file__ can be None. In contrast to Python's __file__ can be None.
""" """
if self._module.path is None: if self.module_node.path is None:
return None return None
return os.path.abspath(self._module.path) return os.path.abspath(self.module_node.path)
def py__package__(self): def py__package__(self):
if self._get_init_directory() is None: if self._get_init_directory() is None:
@@ -884,7 +883,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
Lists modules in the directory of this module (if this module is a Lists modules in the directory of this module (if this module is a
package). package).
""" """
path = self._module.path path = self.module_node.path
names = {} names = {}
if path is not None and path.endswith(os.path.sep + '__init__.py'): if path is not None and path.endswith(os.path.sep + '__init__.py'):
mods = pkgutil.iter_modules([os.path.dirname(path)]) mods = pkgutil.iter_modules([os.path.dirname(path)])
@@ -909,4 +908,4 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
return compiled.get_special_object(self._evaluator, 'MODULE_CLASS') return compiled.get_special_object(self._evaluator, 'MODULE_CLASS')
def __repr__(self): def __repr__(self):
return "<%s: %s>" % (type(self).__name__, self._module) return "<%s: %s>" % (type(self).__name__, self.module_node)

View File

@@ -122,6 +122,7 @@ from jedi import debug
from jedi._compatibility import unicode, is_py3 from jedi._compatibility import unicode, is_py3
from jedi.parser import Parser, load_grammar from jedi.parser import Parser, load_grammar
from jedi.api.classes import Definition from jedi.api.classes import Definition
from jedi.evaluate.representation import ModuleContext
TEST_COMPLETIONS = 0 TEST_COMPLETIONS = 0
@@ -189,13 +190,12 @@ class IntegrationTestCase(object):
parser = Parser(load_grammar(), string, start_symbol='eval_input') parser = Parser(load_grammar(), string, start_symbol='eval_input')
parser.get_root_node().move(self.line_nr) parser.get_root_node().move(self.line_nr)
element = parser.get_parsed_node() element = parser.get_parsed_node()
module = script._get_module() module_context = script._get_module()
# TODO remove # TODO remove
element.parent = jedi.api.completion.get_user_scope( element.parent = jedi.api.completion.get_user_scope(
module, module_context,
(self.line_nr, self.column) (self.line_nr, self.column)
) )
module_context = evaluator.wrap(module, parent_context=None)
results = evaluator.eval_element(module_context, element) results = evaluator.eval_element(module_context, element)
if not results: if not results:
raise Exception('Could not resolve %s on line %s' raise Exception('Could not resolve %s on line %s'