Skip to content

Commit 7f963d8

Browse files
refactor(goal): code analysis engine
changes: - file: analyzer.py area: analyzer modified: [_scan_files, ProjectAnalyzer] - file: cli.py area: cli modified: [main] dependencies: flow: "cli→analyzer" - cli.py -> analyzer.py stats: lines: "+74/-46 (net +28)" files: 2 complexity: "Large structural change (normalized)"
1 parent 64242a2 commit 7f963d8

File tree

10 files changed

+93
-53
lines changed

10 files changed

+93
-53
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## [1.0.46] - 2026-02-26
2+
3+
### Summary
4+
5+
refactor(goal): code analysis engine
6+
7+
### Other
8+
9+
- update code2logic/analyzer.py
10+
- update code2logic/cli.py
11+
12+
113
## [1.0.45] - 2026-02-26
214

315
### Summary

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.45
1+
1.0.46

code2logic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
>>> print(output)
1919
"""
2020

21-
__version__ = "1.0.45"
21+
__version__ = "1.0.46"
2222
__author__ = "Softreck"
2323
__email__ = "info@softreck.dev"
2424
__license__ = "MIT"

code2logic/analyzer.py

Lines changed: 73 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
import logging
8+
import os
89
import sys
910
import time
1011
from collections import defaultdict
@@ -218,63 +219,89 @@ def analyze(self) -> ProjectInfo:
218219

219220
def _scan_files(self):
220221
"""Scan and parse all source files."""
221-
for fp in self.root_path.rglob('*'):
222-
if not fp.is_file():
223-
continue
224-
225-
# Skip ignored directories
226-
if any(d in fp.parts for d in self.IGNORE_DIRS):
227-
continue
228-
229-
# Skip ignored files
230-
if fp.name in self.IGNORE_FILES:
231-
continue
222+
scan_start = time.time()
223+
files_seen = 0
224+
files_parsed = 0
225+
files_matched = 0
226+
scan_progress_every = 500
227+
228+
for root, dirnames, filenames in os.walk(self.root_path):
229+
dirnames[:] = [d for d in dirnames if d not in self.IGNORE_DIRS]
230+
for filename in filenames:
231+
files_seen += 1
232+
fp = Path(root) / filename
233+
234+
if filename in self.IGNORE_FILES:
235+
continue
232236

233-
ext = fp.suffix.lower()
234-
language = self.LANGUAGE_EXTENSIONS.get(ext)
235-
if language is None and ext == '':
236-
try:
237-
with fp.open('r', encoding='utf-8', errors='ignore') as f:
238-
language = self._language_from_shebang(f.readline())
239-
except Exception:
240-
language = None
237+
ext = fp.suffix.lower()
238+
language = self.LANGUAGE_EXTENSIONS.get(ext)
239+
if language is None and ext == '':
240+
try:
241+
with fp.open('r', encoding='utf-8', errors='ignore') as f:
242+
language = self._language_from_shebang(f.readline())
243+
except Exception:
244+
language = None
241245

242-
if language is None:
243-
continue
246+
if language is None:
247+
continue
244248

245-
self.languages[language] += 1
249+
files_matched += 1
250+
self.languages[language] += 1
246251

247-
# Read file
248-
try:
249-
content = fp.read_text(encoding='utf-8', errors='ignore')
250-
except Exception:
251-
continue
252+
if self.verbose and files_seen > 0 and (files_seen % scan_progress_every) == 0:
253+
log.info(
254+
"Scan progress: seen=%d matched=%d parsed=%d modules=%d time=%.2fs",
255+
files_seen,
256+
files_matched,
257+
files_parsed,
258+
len(self.modules),
259+
time.time() - scan_start,
260+
)
252261

253-
rel_path = str(fp.relative_to(self.root_path))
262+
try:
263+
content = fp.read_text(encoding='utf-8', errors='ignore')
264+
except Exception:
265+
continue
254266

255-
# Try Tree-sitter first, then fallback
256-
module = None
257-
try:
258-
if self.ts_parser and self.ts_parser.is_available(language):
259-
module = self.ts_parser.parse(rel_path, content, language)
260-
except Exception as e:
261-
if self.verbose:
262-
log.debug("Tree-sitter parser failed for %s: %s", rel_path, e)
267+
try:
268+
rel_path = str(fp.relative_to(self.root_path))
269+
except Exception:
270+
rel_path = str(fp)
263271

264-
if module is None:
272+
module = None
265273
try:
266-
module = self.fallback_parser.parse(rel_path, content, language)
274+
if self.ts_parser and self.ts_parser.is_available(language):
275+
module = self.ts_parser.parse(rel_path, content, language)
267276
except Exception as e:
268277
if self.verbose:
269-
log.debug("Fallback parser failed for %s: %s", rel_path, e)
270-
continue
278+
log.debug("Tree-sitter parser failed for %s: %s", rel_path, e)
279+
280+
if module is None:
281+
try:
282+
module = self.fallback_parser.parse(rel_path, content, language)
283+
except Exception as e:
284+
if self.verbose:
285+
log.debug("Fallback parser failed for %s: %s", rel_path, e)
286+
continue
287+
288+
if module:
289+
files_parsed += 1
290+
try:
291+
module.file_bytes = fp.stat().st_size
292+
except Exception:
293+
module.file_bytes = len(content.encode('utf-8', errors='ignore'))
294+
self.modules.append(module)
271295

272-
if module:
273-
try:
274-
module.file_bytes = fp.stat().st_size
275-
except Exception:
276-
module.file_bytes = len(content.encode('utf-8', errors='ignore'))
277-
self.modules.append(module)
296+
if self.verbose:
297+
log.info(
298+
"Scan finished: seen=%d matched=%d parsed=%d modules=%d time=%.2fs",
299+
files_seen,
300+
files_matched,
301+
files_parsed,
302+
len(self.modules),
303+
time.time() - scan_start,
304+
)
278305

279306
def _detect_entrypoints(self) -> List[str]:
280307
"""Detect project entry points."""

code2logic/cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ def _code2logic_llm_cli(argv: list[str]) -> None:
510510

511511

512512
def main(argv=None):
513+
cli_start = time.time()
513514
parser = argparse.ArgumentParser(
514515
description='Analyze source code and generate logical representations',
515516
formatter_class=argparse.RawDescriptionHelpFormatter

logic2code/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
from .generator import CodeGenerator, GeneratorConfig, GenerationResult
1515
from .renderers import PythonRenderer
1616

17-
__version__ = '1.0.45'
17+
__version__ = '1.0.46'
1818
__all__ = ['CodeGenerator', 'GeneratorConfig', 'GenerationResult', 'PythonRenderer']

logic2test/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
from .parsers import LogicParser
1616
from .templates import TestTemplate
1717

18-
__version__ = '1.0.45'
18+
__version__ = '1.0.46'
1919
__all__ = ['TestGenerator', 'GeneratorConfig', 'GenerationResult', 'LogicParser', 'TestTemplate']

lolm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
)
7777
from .clients import LLMRateLimitError
7878

79-
__version__ = '1.0.45'
79+
__version__ = '1.0.46'
8080
__all__ = [
8181
# Config
8282
'LLMConfig',

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "code2logic"
7-
version = "1.0.45"
7+
version = "1.0.46"
88
description = "Code2Logic - Source code to logical representation converter for LLM analysis, featuring Tree-sitter parsing, dependency graph analysis, and multi-language support."
99
readme = "README.md"
1010
license = "Apache-2.0"

tests/samples/sample_reexport/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@
1818
"ProcessingError",
1919
]
2020

21-
__version__ = "1.0.45"
21+
__version__ = "1.0.46"

0 commit comments

Comments
 (0)