Caching for get_parent_scope

This commit is contained in:
Dave Halter
2019-06-18 10:04:10 +02:00
parent f2f54f2864
commit 2cf1797465
3 changed files with 26 additions and 7 deletions

View File

@@ -38,7 +38,7 @@ py__doc__() Returns the docstring for a context.
"""
from jedi import debug
from jedi._compatibility import use_metaclass
from jedi.parser_utils import get_parent_scope
from jedi.parser_utils import get_cached_parent_scope
from jedi.evaluate.cache import evaluator_method_cache, CachedMetaClass, \
evaluator_method_generator_cache
from jedi.evaluate import compiled
@@ -106,7 +106,7 @@ class ClassFilter(ParserTreeFilter):
while node is not None:
if node == self._parser_scope or node == self.context:
return True
node = get_parent_scope(node)
node = get_cached_parent_scope(self._used_names, node)
return False
def _access_possible(self, name):

View File

@@ -11,13 +11,13 @@ from jedi._compatibility import use_metaclass
from jedi.evaluate import flow_analysis
from jedi.evaluate.base_context import ContextSet, Context, ContextWrapper, \
LazyContextWrapper
from jedi.parser_utils import get_parent_scope
from jedi.parser_utils import get_cached_parent_scope
from jedi.evaluate.utils import to_list
from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate.names import TreeNameDefinition, ParamName, AbstractNameDefinition
_definition_name_cache = weakref.WeakKeyDictionary()
class AbstractFilter(object):
_until_position = None
@@ -75,8 +75,6 @@ class AbstractUsedNamesFilter(AbstractFilter):
self.context = context
def get(self, name):
#print(self, self.context, name, type(self).__name__)
#import traceback, sys; traceback.print_stack(file=sys.stdout)
return self._convert_names(self._filter(
_get_definition_names(self._used_names, name)
))
@@ -124,7 +122,7 @@ class ParserTreeFilter(AbstractUsedNamesFilter):
if parent.type == 'trailer':
return False
base_node = parent if parent.type in ('classdef', 'funcdef') else name
return get_parent_scope(base_node) == self._parser_scope
return get_cached_parent_scope(self._used_names, base_node) == self._parser_scope
def _check_flows(self, names):
for name in sorted(names, key=lambda name: name.start_pos, reverse=True):

View File

@@ -1,6 +1,7 @@
import re
import textwrap
from inspect import cleandoc
from weakref import WeakKeyDictionary
from parso.python import tree
from parso.cache import parser_cache
@@ -226,6 +227,23 @@ def is_scope(node):
return t in ('file_input', 'classdef', 'funcdef', 'lambdef', 'sync_comp_for')
def _get_parent_scope_cache(func):
cache = WeakKeyDictionary()
def wrapper(used_names, node, include_flows=False):
try:
for_module = cache[used_names]
except KeyError:
for_module = cache[used_names] = {}
try:
return for_module[node]
except KeyError:
result = for_module[node] = func(node, include_flows)
return result
return wrapper
def get_parent_scope(node, include_flows=False):
"""
Returns the underlying scope.
@@ -251,6 +269,9 @@ def get_parent_scope(node, include_flows=False):
return scope
get_cached_parent_scope = _get_parent_scope_cache(get_parent_scope)
def get_cached_code_lines(grammar, path):
"""
Basically access the cached code lines in parso. This is not the nicest way