diff --git a/src/serena/agent.py b/src/serena/agent.py index 157b78c..b6f66ee 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -184,7 +184,7 @@ def index_project(project: str, log_level: str = "INFO") -> None: ls = create_ls_for_project(project, log_level=log_level_int) save_after_n_files = 10 with ls.start_server(): - parsed_files = project_instance.request_parsed_files() + parsed_files = project_instance.gather_source_files() files_processed = 0 pbar = tqdm(parsed_files, disable=False) for relative_file_path in pbar: diff --git a/src/serena/project.py b/src/serena/project.py index c9d0510..97edbde 100644 --- a/src/serena/project.py +++ b/src/serena/project.py @@ -122,10 +122,10 @@ class Project: return match_path(relative_path, self.get_ignore_spec(), root_path=self.project_root) - def request_parsed_files(self, relative_path: str = "") -> list[str]: - """Retrieves relative paths of all files analyzed by the Language Server. + def gather_source_files(self, relative_path: str = "") -> list[str]: + """Retrieves relative paths of all source files, optionally limited to the given path - :param relative_path: will only retrieve files that are subpaths of this. + :param relative_path: if provided, restrict search to this path """ rel_file_paths = [] start_path = os.path.join(self.project_root, relative_path) @@ -147,7 +147,7 @@ class Project: ) return rel_file_paths - def search_files_for_pattern( + def search_source_files_for_pattern( self, pattern: str, relative_path: str = "", @@ -167,7 +167,7 @@ class Project: :param paths_exclude_glob: Glob pattern to filter which files to exclude from the search. Takes precedence over paths_include_glob. :return: List of matched consecutive lines with context """ - relative_file_paths = self.request_parsed_files(relative_path=relative_path) + relative_file_paths = self.gather_source_files(relative_path=relative_path) return search_files( relative_file_paths, pattern, diff --git a/src/serena/tools/file_tools.py b/src/serena/tools/file_tools.py index 4618d8b..5cff6d9 100644 --- a/src/serena/tools/file_tools.py +++ b/src/serena/tools/file_tools.py @@ -358,7 +358,7 @@ class SearchForPatternTool(Tool): raise FileNotFoundError(f"Relative path {relative_path} does not exist.") if restrict_search_to_code_files: - matches = self.project.search_files_for_pattern( + matches = self.project.search_source_files_for_pattern( pattern=substring_pattern, relative_path=relative_path, context_lines_before=context_lines_before, diff --git a/test/solidlsp/clojure/test_clojure_basic.py b/test/solidlsp/clojure/test_clojure_basic.py index 56b80ac..28c2cd3 100644 --- a/test/solidlsp/clojure/test_clojure_basic.py +++ b/test/solidlsp/clojure/test_clojure_basic.py @@ -204,7 +204,7 @@ class TestLanguageServerBasics: class TestProjectBasics: @pytest.mark.parametrize("project", [Language.CLOJURE], indirect=True) def test_search_files_for_pattern(self, project: Project) -> None: - result = project.search_files_for_pattern("defn.*greet") + result = project.search_source_files_for_pattern("defn.*greet") assert result is not None, "Pattern search should return results" assert len(result) > 0, "Should find at least one match for 'defn.*greet'" @@ -212,7 +212,7 @@ class TestProjectBasics: core_matches = [match for match in result if match.source_file_path and "core.clj" in match.source_file_path] assert len(core_matches) > 0, "Should find greet function in core.clj" - result = project.search_files_for_pattern(":require") + result = project.search_source_files_for_pattern(":require") assert result is not None, "Should find require statements" utils_matches = [match for match in result if match.source_file_path and "utils.clj" in match.source_file_path] diff --git a/test/solidlsp/python/test_python_basic.py b/test/solidlsp/python/test_python_basic.py index 77df693..d19c380 100644 --- a/test/solidlsp/python/test_python_basic.py +++ b/test/solidlsp/python/test_python_basic.py @@ -193,35 +193,37 @@ class TestProjectBasics: """Test search_files_for_pattern with various patterns and glob filters.""" # Test 1: Search for class definitions across all files class_pattern = r"class\s+\w+\s*(?:\([^{]*\)|:)" - matches = project.search_files_for_pattern(class_pattern) + matches = project.search_source_files_for_pattern(class_pattern) assert len(matches) > 0 # Should find multiple classes like User, Item, BaseModel, etc. assert len(matches) >= 5 # Test 2: Search for specific class with include glob user_class_pattern = r"class\s+User\s*(?:\([^{]*\)|:)" - matches = project.search_files_for_pattern(user_class_pattern, paths_include_glob="**/models.py") + matches = project.search_source_files_for_pattern(user_class_pattern, paths_include_glob="**/models.py") assert len(matches) == 1 # Should only find User class in models.py assert matches[0].source_file_path is not None assert "models.py" in matches[0].source_file_path # Test 3: Search for method definitions with exclude glob method_pattern = r"def\s+\w+\s*\([^)]*\):" - matches = project.search_files_for_pattern(method_pattern, paths_exclude_glob="**/models.py") + matches = project.search_source_files_for_pattern(method_pattern, paths_exclude_glob="**/models.py") assert len(matches) > 0 # Should find methods in services.py but not in models.py assert all(match.source_file_path is not None and "models.py" not in match.source_file_path for match in matches) # Test 4: Search for specific method with both include and exclude globs create_user_pattern = r"def\s+create_user\s*\([^)]*\)(?:\s*->[^:]+)?:" - matches = project.search_files_for_pattern(create_user_pattern, paths_include_glob="**/*.py", paths_exclude_glob="**/models.py") + matches = project.search_source_files_for_pattern( + create_user_pattern, paths_include_glob="**/*.py", paths_exclude_glob="**/models.py" + ) assert len(matches) == 1 # Should only find create_user in services.py assert matches[0].source_file_path is not None assert "services.py" in matches[0].source_file_path # Test 5: Search for a pattern that should appear in multiple files init_pattern = r"def\s+__init__\s*\([^)]*\):" - matches = project.search_files_for_pattern(init_pattern) + matches = project.search_source_files_for_pattern(init_pattern) assert len(matches) > 1 # Should find __init__ in multiple classes # Should find __init__ in both models.py and services.py assert any(match.source_file_path is not None and "models.py" in match.source_file_path for match in matches) @@ -229,5 +231,5 @@ class TestProjectBasics: # Test 6: Search with a pattern that should have no matches no_match_pattern = r"def\s+this_method_does_not_exist\s*\([^)]*\):" - matches = project.search_files_for_pattern(no_match_pattern) + matches = project.search_source_files_for_pattern(no_match_pattern) assert len(matches) == 0