mirror of
https://github.com/davidhalter/jedi.git
synced 2026-05-25 17:58:35 +08:00
Very temporary solution for doing deep_ast_copy.
This commit is contained in:
+23
-11
@@ -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):
|
||||||
|
|||||||
@@ -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([])
|
||||||
|
|||||||
Reference in New Issue
Block a user