Very temporary solution for doing deep_ast_copy.

This commit is contained in:
Dave Halter
2014-12-04 11:19:33 +01:00
parent aa9057be38
commit 8f1002218d
2 changed files with 31 additions and 17 deletions
+23 -11
View File
@@ -6,7 +6,7 @@ from jedi.parser import tree as pr
from jedi import debug 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 Much, much faster than copy.deepcopy, but just for Parser elements (Doesn't
copy parents). 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') return key_value[0] not in ('_expression_list', '_assignment_details')
new_elements = new_elements_default or {} 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. # If it's already in the cache, just return it.
try: try:
return new_elements[obj] new_obj = new_elements[obj]
if not check_first:
return new_obj
except KeyError: except KeyError:
pass # Actually copy and set attributes.
new_obj = copy.copy(obj)
new_elements[obj] = new_obj
if isinstance(obj, pr.Statement): if isinstance(obj, pr.Statement):
# Need to set _set_vars, otherwise the cache is not working # 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. # tree in there.
items = sorted(items, key=sort_stmt) items = sorted(items, key=sort_stmt)
else: 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. #if hasattr(new_obj, 'parent'): print(new_obj, new_obj.parent)
new_obj = copy.copy(obj)
new_elements[obj] = new_obj
for key, value in items: for key, value in items:
# replace parent (first try _parent and then parent) # 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 # parent can be a property
continue continue
try: try:
setattr(new_obj, key, new_elements[value]) if not check_first:
setattr(new_obj, key, new_elements[value])
except KeyError: except KeyError:
pass unfinished_parents.append(new_obj)
elif key in ['parent_function', 'use_as_parent', '_sub_module']: elif key in ['parent_function', 'use_as_parent', '_sub_module']:
continue continue
elif key == 'names_dict': elif key == 'names_dict':
@@ -94,7 +99,14 @@ def deep_ast_copy(obj, new_elements_default=None):
return tuple(copied_array) return tuple(copied_array)
return 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): def call_of_name(name, cut_own_trailer=False):
+8 -6
View File
@@ -584,7 +584,9 @@ class FunctionExecution(Executed):
def __init__(self, evaluator, base, *args, **kwargs): def __init__(self, evaluator, base, *args, **kwargs):
super(FunctionExecution, self).__init__(evaluator, base, *args, **kwargs) super(FunctionExecution, self).__init__(evaluator, base, *args, **kwargs)
# for deep_ast_copy # 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, # We definitely want the params to be generated. Params are special,
# because they have been altered and are not normal "children". # because they have been altered and are not normal "children".
self.params self.params
@@ -624,6 +626,7 @@ class FunctionExecution(Executed):
break break
return types return types
"""
@common.safe_property @common.safe_property
@underscore_memoization @underscore_memoization
def names_dict(self): def names_dict(self):
@@ -634,6 +637,7 @@ class FunctionExecution(Executed):
return d return d
self.base.names_dict self.base.names_dict
return LazyDict(self.base.names_dict, self._copy_list) return LazyDict(self.base.names_dict, self._copy_list)
"""
@memoize_default(default=NO_DEFAULT) @memoize_default(default=NO_DEFAULT)
def _get_params(self): def _get_params(self):
@@ -685,11 +689,6 @@ class FunctionExecution(Executed):
self._scope_copy(scope.parent) self._scope_copy(scope.parent)
helpers.deep_ast_copy(scope, self._copy_dict) 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 @common.safe_property
@memoize_default([]) @memoize_default([])
def returns(self): def returns(self):
@@ -700,14 +699,17 @@ class FunctionExecution(Executed):
def yields(self): def yields(self):
return self._copy_list(self.base.yields) return self._copy_list(self.base.yields)
"""
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def children(self): def children(self):
helpers.deep_ast_copy(self.base.base_func, self._copy_dict, check_first=True)
if isinstance(self.base, InstanceElement): if isinstance(self.base, InstanceElement):
children = self.base.var.children children = self.base.var.children
else: else:
children = self.base.children children = self.base.children
return self._copy_list(children) return self._copy_list(children)
"""
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])