Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ hiredis>=2.3.0
tree-sitter>=0.23.0
tree-sitter-python>=0.23.0
tree-sitter-javascript>=0.23.0
tree-sitter-typescript>=0.23.0

# AI/ML
openai>=1.54.0
Expand Down
30 changes: 22 additions & 8 deletions backend/services/dependency_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# Tree-sitter
import tree_sitter_python as tspython
import tree_sitter_javascript as tsjavascript
import tree_sitter_typescript as tstypescript
Comment thread
coderabbitai[bot] marked this conversation as resolved.
from tree_sitter import Language, Parser

from services.observability import logger, metrics
Expand All @@ -22,7 +23,8 @@ def __init__(self):
self.parsers = {
'python': Parser(Language(tspython.language())),
'javascript': Parser(Language(tsjavascript.language())),
'typescript': Parser(Language(tsjavascript.language())),
'typescript': Parser(Language(tstypescript.language_typescript())),
'tsx': Parser(Language(tstypescript.language_tsx())),
}
logger.info("DependencyAnalyzer initialized")

Expand All @@ -34,7 +36,7 @@ def _detect_language(self, file_path: str) -> str:
'.js': 'javascript',
'.jsx': 'javascript',
'.ts': 'typescript',
'.tsx': 'typescript',
'.tsx': 'tsx',
}
return lang_map.get(ext, 'unknown')

Expand Down Expand Up @@ -122,8 +124,8 @@ def analyze_file_dependencies(self, file_path: str) -> Dict:
logger.error("Error analyzing file", file_path=file_path, error=str(e))
return {"file": str(file_path), "imports": [], "language": language, "error": str(e)}

def build_dependency_graph(self, repo_path: str) -> Dict:
"""Build complete dependency graph for repository"""
def build_dependency_graph(self, repo_path: str, include_paths: List[str] = None) -> Dict:
"""Build dependency graph. If include_paths set, only analyze those dirs."""
Comment thread
DevanshuNEU marked this conversation as resolved.
repo_path = Path(repo_path)

# Discover code files
Expand All @@ -136,8 +138,16 @@ def build_dependency_graph(self, repo_path: str) -> Dict:
continue
if any(skip in file_path.parts for skip in skip_dirs):
continue
if file_path.suffix in extensions:
code_files.append(file_path)
if file_path.suffix not in extensions:
continue
if include_paths:
rel_parts = file_path.relative_to(repo_path).parts
if not any(
rel_parts[:len(Path(p).parts)] == Path(p).parts
for p in include_paths
):
continue
Comment thread
coderabbitai[bot] marked this conversation as resolved.
code_files.append(file_path)

logger.info("Building dependency graph", file_count=len(code_files))

Expand Down Expand Up @@ -236,6 +246,10 @@ def _resolve_import_to_file(
source_path = Path(source_file)
source_dir = source_path.parent

# TS imports use .js extension but actual file is .ts on disk
if import_path.endswith('.js') or import_path.endswith('.jsx'):
import_path = re.sub(r'\.(jsx?)$', '', import_path)

# Relative imports
if import_path.startswith('.'):
clean_import = import_path.lstrip('./')
Expand All @@ -250,7 +264,7 @@ def _resolve_import_to_file(
else:
potential_base = source_dir / clean_import

extensions = ['', '.ts', '.tsx', '.js', '.jsx', '.py']
extensions = ['', '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.py']

for ext in extensions:
# Build the potential path
Expand All @@ -269,7 +283,7 @@ def _resolve_import_to_file(
if not import_path.startswith('.'):
module_path = import_path.replace('.', '/')

for ext in ['.py', '.js', '.ts']:
for ext in ['', '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.py']:
test_path = module_path + ext
if test_path in internal_files:
return test_path
Expand Down
Loading