Coverage for src\llm_code_lens\analyzer\javascript.py: 100%
35 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-12 10:23 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-12 10:23 +0200
1# src/codelens/analyzer/javascript.py
2import re
3from pathlib import Path
4from typing import Dict, List
6class JavaScriptAnalyzer:
7 """JavaScript/TypeScript code analyzer using regex patterns."""
9 def analyze_file(self, file_path: Path) -> dict:
10 """Analyze a JavaScript/TypeScript file."""
11 with open(file_path, 'r', encoding='utf-8') as f:
12 content = f.read()
14 analysis = {
15 'imports': [],
16 'exports': [],
17 'functions': [],
18 'classes': [],
19 'comments': [],
20 'todos': [],
21 'metrics': {
22 'loc': len(content.splitlines()),
23 'classes': 0,
24 'functions': 0,
25 'imports': 0,
26 }
27 }
29 # Extract imports and exports
30 import_pattern = r'^(?:import|export)\s+.*?[\n;]'
31 for match in re.finditer(import_pattern, content, re.MULTILINE):
32 stmt = match.group().strip()
33 analysis['metrics']['imports'] += 1
34 if stmt.startswith('import'):
35 analysis['imports'].append(stmt)
36 else:
37 analysis['exports'].append(stmt)
39 # Extract functions
40 function_pattern = r'(?:async\s+)?(?:function\s+(\w+)|const\s+(\w+)\s*=\s*(?:async\s+)?(?:\([^)]*\)\s*=>|\function\s*\([^)]*\)))'
41 for match in re.finditer(function_pattern, content):
42 analysis['metrics']['functions'] += 1
43 name = match.group(1) or match.group(2)
44 if name:
45 analysis['functions'].append({
46 'name': name,
47 'line_number': content[:match.start()].count('\n') + 1
48 })
50 # Extract classes
51 class_pattern = r'class\s+(\w+)(?:\s+extends\s+(\w+))?\s*\{'
52 for match in re.finditer(class_pattern, content):
53 analysis['metrics']['classes'] += 1
54 analysis['classes'].append({
55 'name': match.group(1),
56 'extends': match.group(2),
57 'line_number': content[:match.start()].count('\n') + 1
58 })
60 # Extract comments and TODOs
61 comment_patterns = [
62 r'//.*$', # Single-line comments
63 r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/' # Multi-line comments
64 ]
66 for pattern in comment_patterns:
67 for match in re.finditer(pattern, content, re.MULTILINE):
68 comment = match.group()
69 # Clean up comment markers
70 comment = (comment.strip('/') # For single-line
71 .strip('*') # For multi-line
72 .strip())
74 line_number = content[:match.start()].count('\n') + 1
76 if any(marker in comment.upper()
77 for marker in ['TODO', 'FIXME', 'XXX']):
78 analysis['todos'].append({
79 'line': line_number,
80 'text': comment
81 })
82 else:
83 analysis['comments'].append({
84 'line': line_number,
85 'text': comment
86 })
88 return analysis