diff --git a/jedi/api/project.py b/jedi/api/project.py index f4cbd72a..e9f6b921 100644 --- a/jedi/api/project.py +++ b/jedi/api/project.py @@ -6,10 +6,13 @@ from jedi._compatibility import FileNotFoundError, PermissionError, IsADirectory from jedi._compatibility import scandir from jedi.api.environment import get_cached_default_environment, create_environment from jedi.api.exceptions import WrongVersion +from jedi.api.classes import Definition from jedi._compatibility import force_unicode from jedi.inference.sys_path import discover_buildout_paths from jedi.inference.cache import inference_state_as_method_param_cache -from jedi.inference.references import recurse_find_python_files +from jedi.inference.references import recurse_find_python_files, search_in_file_ios +from jedi.inference.helpers import get_module_names +from jedi.inference import InferenceState from jedi.file_io import FolderIO from jedi.common.utils import traverse_parents @@ -172,9 +175,11 @@ class Project(object): """ Returns a generator of names """ - for file_io in recurse_find_python_files(FolderIO(self._path)): - for name in get_names(all_scopes=True): - yield name + inference_state = InferenceState(self) + file_io_iterator = recurse_find_python_files(FolderIO(self._path)) + for module_context in search_in_file_ios(inference_state, file_io_iterator, string): + for name in get_module_names(module_context.ree_node, all_scopes=all_scopes): + yield Definition(inference_state, module_context.create_name(name)) def __repr__(self): return '<%s: %s>' % (self.__class__.__name__, self._path) diff --git a/jedi/inference/references.py b/jedi/inference/references.py index 53128dd0..0465ce75 100644 --- a/jedi/inference/references.py +++ b/jedi/inference/references.py @@ -3,6 +3,7 @@ import re from parso import python_bytes_to_unicode +from jedi.debug import dbg from jedi.file_io import KnownContentFileIO from jedi.inference.imports import SubModuleName, load_module_from_path from jedi.inference.filters import ParserTreeFilter @@ -254,19 +255,28 @@ def get_module_contexts_containing_name(inference_state, module_contexts, name, if len(name) <= 2: return + file_io_iterator = _find_python_files_in_sys_path(inference_state, module_contexts) + for x in search_in_file_ios(inference_state, file_io_iterator, name, + limit_reduction=limit_reduction): + yield x # Python 2... + + +def search_in_file_ios(inference_state, file_io_iterator, name, limit_reduction=1): parse_limit = _PARSED_FILE_LIMIT / limit_reduction open_limit = _OPENED_FILE_LIMIT / limit_reduction file_io_count = 0 parsed_file_count = 0 regex = re.compile(r'\b' + re.escape(name) + r'\b') - for file_io in _find_python_files_in_sys_path(inference_state, module_contexts): + for file_io in file_io_iterator: file_io_count += 1 m = _check_fs(inference_state, file_io, regex) if m is not None: parsed_file_count += 1 yield m if parsed_file_count >= parse_limit: + dbg('Hit limit of parsed files: %s', parse_limit) break if file_io_count >= open_limit: + dbg('Hit limit of opened files: %s', open_limit) break