Skip to content

Commit 36a235a

Browse files
authored
Merge pull request #280 from DevanshuNEU/fix/ts-dependency-analyzer
fix: TypeScript dependency analysis -- proper parser, .js resolution, include_paths (OPE-120)
2 parents c3288da + c204ec0 commit 36a235a

6 files changed

Lines changed: 863 additions & 8 deletions

File tree

backend/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ hiredis>=2.3.0
1818
tree-sitter>=0.23.0
1919
tree-sitter-python>=0.23.0
2020
tree-sitter-javascript>=0.23.0
21+
tree-sitter-typescript>=0.23.0
2122

2223
# AI/ML
2324
openai>=1.54.0

backend/services/dependency_analyzer.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# Tree-sitter
1010
import tree_sitter_python as tspython
1111
import tree_sitter_javascript as tsjavascript
12+
import tree_sitter_typescript as tstypescript
1213
from tree_sitter import Language, Parser
1314

1415
from services.observability import logger, metrics
@@ -22,7 +23,8 @@ def __init__(self):
2223
self.parsers = {
2324
'python': Parser(Language(tspython.language())),
2425
'javascript': Parser(Language(tsjavascript.language())),
25-
'typescript': Parser(Language(tsjavascript.language())),
26+
'typescript': Parser(Language(tstypescript.language_typescript())),
27+
'tsx': Parser(Language(tstypescript.language_tsx())),
2628
}
2729
logger.info("DependencyAnalyzer initialized")
2830

@@ -34,7 +36,7 @@ def _detect_language(self, file_path: str) -> str:
3436
'.js': 'javascript',
3537
'.jsx': 'javascript',
3638
'.ts': 'typescript',
37-
'.tsx': 'typescript',
39+
'.tsx': 'tsx',
3840
}
3941
return lang_map.get(ext, 'unknown')
4042

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

125-
def build_dependency_graph(self, repo_path: str) -> Dict:
126-
"""Build complete dependency graph for repository"""
127+
def build_dependency_graph(self, repo_path: str, include_paths: List[str] = None) -> Dict:
128+
"""Build dependency graph. If include_paths set, only analyze those dirs."""
127129
repo_path = Path(repo_path)
128130

129131
# Discover code files
@@ -136,8 +138,16 @@ def build_dependency_graph(self, repo_path: str) -> Dict:
136138
continue
137139
if any(skip in file_path.parts for skip in skip_dirs):
138140
continue
139-
if file_path.suffix in extensions:
140-
code_files.append(file_path)
141+
if file_path.suffix not in extensions:
142+
continue
143+
if include_paths:
144+
rel_parts = file_path.relative_to(repo_path).parts
145+
if not any(
146+
rel_parts[:len(Path(p).parts)] == Path(p).parts
147+
for p in include_paths
148+
):
149+
continue
150+
code_files.append(file_path)
141151

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

@@ -236,6 +246,10 @@ def _resolve_import_to_file(
236246
source_path = Path(source_file)
237247
source_dir = source_path.parent
238248

249+
# TS imports use .js extension but actual file is .ts on disk
250+
if import_path.endswith('.js') or import_path.endswith('.jsx'):
251+
import_path = re.sub(r'\.(jsx?)$', '', import_path)
252+
239253
# Relative imports
240254
if import_path.startswith('.'):
241255
clean_import = import_path.lstrip('./')
@@ -250,7 +264,7 @@ def _resolve_import_to_file(
250264
else:
251265
potential_base = source_dir / clean_import
252266

253-
extensions = ['', '.ts', '.tsx', '.js', '.jsx', '.py']
267+
extensions = ['', '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.py']
254268

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

272-
for ext in ['.py', '.js', '.ts']:
286+
for ext in ['', '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.py']:
273287
test_path = module_path + ext
274288
if test_path in internal_files:
275289
return test_path

0 commit comments

Comments
 (0)