Skip to content

Commit d5e506f

Browse files
gkorlandCopilot
andcommitted
fix: address review feedback for Python import tracking
- Remove unused Path and File imports from test_py_imports.py - Add explicit Entity and File imports to Java analyzer - Fix resolve_type to also resolve function_definition (not just classes) - Add _resolve_import_name helper to try both type and method resolution - Fix invalid Java package name in test-project/c.java (hyphens not allowed) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8a8ade2 commit d5e506f

File tree

4 files changed

+20
-14
lines changed

4 files changed

+20
-14
lines changed

api/analyzers/java/analyzer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from pathlib import Path
33
import subprocess
44
from ...entities import *
5+
from ...entities.entity import Entity
6+
from ...entities.file import File
57
from typing import Optional
68
from ..analyzer import AbstractAnalyzer
79

api/analyzers/python/analyzer.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ def resolve_type(self, files: dict[Path, File], lsp: SyncLanguageServer, file_pa
9696
if node.type == 'attribute':
9797
node = node.child_by_field_name('attribute')
9898
for file, resolved_node in self.resolve(files, lsp, file_path, path, node):
99-
type_dec = self.find_parent(resolved_node, ['class_definition'])
100-
if type_dec in file.entities:
101-
res.append(file.entities[type_dec])
99+
decl = resolved_node
100+
if decl.type not in ['class_definition', 'function_definition']:
101+
decl = self.find_parent(resolved_node, ['class_definition', 'function_definition'])
102+
if decl in file.entities:
103+
res.append(file.entities[decl])
102104
return res
103105

104106
def resolve_method(self, files: dict[Path, File], lsp: SyncLanguageServer, file_path: Path, path: Path, node: Node) -> list[Entity]:
@@ -157,6 +159,13 @@ def add_file_imports(self, file: File) -> None:
157159
except Exception as e:
158160
logger.debug(f"Failed to extract imports from {file.path}: {e}")
159161

162+
def _resolve_import_name(self, files, lsp, file_path, path, identifier):
163+
"""Try to resolve an imported name as both a type and a function."""
164+
resolved = self.resolve_type(files, lsp, file_path, path, identifier)
165+
if not resolved:
166+
resolved = self.resolve_method(files, lsp, file_path, path, identifier)
167+
return resolved
168+
160169
def resolve_import(self, files: dict[Path, File], lsp: SyncLanguageServer, file_path: Path, path: Path, import_node: Node) -> list[Entity]:
161170
"""
162171
Resolve an import statement to the entities it imports.
@@ -171,8 +180,7 @@ def resolve_import(self, files: dict[Path, File], lsp: SyncLanguageServer, file_
171180
if child.type == 'dotted_name':
172181
# Try to resolve the module/name
173182
identifier = child.children[0] if child.child_count > 0 else child
174-
resolved = self.resolve_type(files, lsp, file_path, path, identifier)
175-
res.extend(resolved)
183+
res.extend(self._resolve_import_name(files, lsp, file_path, path, identifier))
176184
elif child.type == 'aliased_import':
177185
# Get the actual name from aliased import (before 'as')
178186
if child.child_count > 0:
@@ -181,8 +189,7 @@ def resolve_import(self, files: dict[Path, File], lsp: SyncLanguageServer, file_
181189
identifier = actual_name.children[0]
182190
else:
183191
identifier = actual_name
184-
resolved = self.resolve_type(files, lsp, file_path, path, identifier)
185-
res.extend(resolved)
192+
res.extend(self._resolve_import_name(files, lsp, file_path, path, identifier))
186193

187194
elif import_node.type == 'import_from_statement':
188195
# Handle "from module import name1, name2"
@@ -197,8 +204,7 @@ def resolve_import(self, files: dict[Path, File], lsp: SyncLanguageServer, file_
197204
if import_keyword_found and child.type == 'dotted_name':
198205
# Try to resolve the imported name
199206
identifier = child.children[0] if child.child_count > 0 else child
200-
resolved = self.resolve_type(files, lsp, file_path, path, identifier)
201-
res.extend(resolved)
207+
res.extend(self._resolve_import_name(files, lsp, file_path, path, identifier))
202208
elif import_keyword_found and child.type == 'aliased_import':
203209
# Handle "from module import name as alias"
204210
if child.child_count > 0:
@@ -207,8 +213,7 @@ def resolve_import(self, files: dict[Path, File], lsp: SyncLanguageServer, file_
207213
identifier = actual_name.children[0]
208214
else:
209215
identifier = actual_name
210-
resolved = self.resolve_type(files, lsp, file_path, path, identifier)
211-
res.extend(resolved)
216+
res.extend(self._resolve_import_name(files, lsp, file_path, path, identifier))
212217

213218
except Exception as e:
214219
logger.debug(f"Failed to resolve import: {e}")

test-project/c.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package test-project;
1+
package test_project;
22

33
public class c {
44

tests/test_py_imports.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import os
22
import unittest
3-
from pathlib import Path
43

5-
from api import SourceAnalyzer, File, Graph
4+
from api import SourceAnalyzer, Graph
65

76

87
class Test_PY_Imports(unittest.TestCase):

0 commit comments

Comments
 (0)