From 8f1002218dc9ceb25b5c80868cf448c1db48b518 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 4 Dec 2014 11:19:33 +0100 Subject: [PATCH] Very temporary solution for doing deep_ast_copy. --- jedi/evaluate/helpers.py | 34 ++++++++++++++++++++++----------- jedi/evaluate/representation.py | 14 ++++++++------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index fecf49db..cad9873d 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -6,7 +6,7 @@ from jedi.parser import tree as pr from jedi import debug -def deep_ast_copy(obj, new_elements_default=None): +def deep_ast_copy(obj, new_elements_default=None, check_first=False): """ Much, much faster than copy.deepcopy, but just for Parser elements (Doesn't copy parents). @@ -15,13 +15,18 @@ def deep_ast_copy(obj, new_elements_default=None): return key_value[0] not in ('_expression_list', '_assignment_details') new_elements = new_elements_default or {} + unfinished_parents = [] - def recursion(obj): + def recursion(obj, check_first=False): # If it's already in the cache, just return it. try: - return new_elements[obj] + new_obj = new_elements[obj] + if not check_first: + return new_obj except KeyError: - pass + # Actually copy and set attributes. + new_obj = copy.copy(obj) + new_elements[obj] = new_obj if isinstance(obj, pr.Statement): # Need to set _set_vars, otherwise the cache is not working @@ -51,11 +56,10 @@ def deep_ast_copy(obj, new_elements_default=None): # tree in there. items = sorted(items, key=sort_stmt) else: - items = sorted(items, key=lambda x: (x[0] != 'params', x[0] == 'names_dict')) + # names_dict should be the last item. + items = sorted(items, key=lambda x: (x[0] == 'names_dict', x[0] == 'params')) - # Actually copy and set attributes. - new_obj = copy.copy(obj) - new_elements[obj] = new_obj + #if hasattr(new_obj, 'parent'): print(new_obj, new_obj.parent) for key, value in items: # replace parent (first try _parent and then parent) @@ -64,9 +68,10 @@ def deep_ast_copy(obj, new_elements_default=None): # parent can be a property continue try: - setattr(new_obj, key, new_elements[value]) + if not check_first: + setattr(new_obj, key, new_elements[value]) except KeyError: - pass + unfinished_parents.append(new_obj) elif key in ['parent_function', 'use_as_parent', '_sub_module']: continue elif key == 'names_dict': @@ -94,7 +99,14 @@ def deep_ast_copy(obj, new_elements_default=None): return tuple(copied_array) return copied_array - return recursion(obj) + result = recursion(obj, check_first=check_first) + + # TODO this sucks... we need to change it. + # DOESNT WORK + for unfinished in unfinished_parents: + unfinished.parent = new_elements[unfinished.parent] + + return result def call_of_name(name, cut_own_trailer=False): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 06e6a928..28175304 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -584,7 +584,9 @@ class FunctionExecution(Executed): def __init__(self, evaluator, base, *args, **kwargs): super(FunctionExecution, self).__init__(evaluator, base, *args, **kwargs) # for deep_ast_copy - self._copy_dict = {base.base_func: self} + func = base.base_func + self._copy_dict = {func: self, func.parent: func.parent} + helpers.deep_ast_copy(self.base.base_func, self._copy_dict, check_first=True) # We definitely want the params to be generated. Params are special, # because they have been altered and are not normal "children". self.params @@ -624,6 +626,7 @@ class FunctionExecution(Executed): break return types + """ @common.safe_property @underscore_memoization def names_dict(self): @@ -634,6 +637,7 @@ class FunctionExecution(Executed): return d self.base.names_dict return LazyDict(self.base.names_dict, self._copy_list) +""" @memoize_default(default=NO_DEFAULT) def _get_params(self): @@ -685,11 +689,6 @@ class FunctionExecution(Executed): self._scope_copy(scope.parent) helpers.deep_ast_copy(scope, self._copy_dict) - @common.safe_property - @memoize_default([]) - def params(self): - return self._copy_list(self.base.params) - @common.safe_property @memoize_default([]) def returns(self): @@ -700,14 +699,17 @@ class FunctionExecution(Executed): def yields(self): return self._copy_list(self.base.yields) + """ @common.safe_property @memoize_default([]) def children(self): + helpers.deep_ast_copy(self.base.base_func, self._copy_dict, check_first=True) if isinstance(self.base, InstanceElement): children = self.base.var.children else: children = self.base.children return self._copy_list(children) + """ @common.safe_property @memoize_default([])