Skip to content

Commit e9b7154

Browse files
Merge branch 'main' of github.com:codeflash-ai/codeflash into fix/js-jest30-loop-runner
2 parents 536c1d0 + 2e6903a commit e9b7154

30 files changed

Lines changed: 2473 additions & 423 deletions

.github/workflows/claude.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
with:
4949
use_foundry: "true"
5050
use_sticky_comment: true
51-
allowed_bots: "claude[bot]"
51+
allowed_bots: "claude[bot],codeflash-ai[bot]"
5252
prompt: |
5353
REPO: ${{ github.repository }}
5454
PR NUMBER: ${{ github.event.pull_request.number }}

CLAUDE.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,29 @@ uv run ruff format codeflash/ # Format
2727
# Linting (run before committing)
2828
uv run prek run --from-ref origin/main
2929

30+
# Mypy type checking (run on changed files before committing)
31+
uv run mypy --non-interactive --config-file pyproject.toml <changed_files>
32+
3033
# Running the CLI
3134
uv run codeflash --help
3235
uv run codeflash init # Initialize in a project
3336
uv run codeflash --all # Optimize entire codebase
3437
```
3538

39+
## Mypy Type Checking
40+
41+
When modifying code, fix any mypy type errors in the files you changed. Run mypy on changed files:
42+
43+
```bash
44+
uv run mypy --non-interactive --config-file pyproject.toml <changed_files>
45+
```
46+
47+
Rules:
48+
- Fix type annotation issues: missing return types, incorrect types, Optional/None unions, import errors for type hints
49+
- Do NOT add `# type: ignore` comments — always fix the root cause
50+
- Do NOT fix type errors that require logic changes, complex generic type rework, or anything that could change runtime behavior
51+
- Files in `mypy_allowlist.txt` are checked in CI — ensure they remain error-free
52+
3653
<!-- Section below is auto-generated by `tessl install` - do not edit manually -->
3754

3855
# Agent Rules <!-- tessl-managed -->

MULTI_LANGUAGE_ARCHITECTURE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ class JavaScriptTransformer:
386386

387387
from pathlib import Path
388388
from codeflash.languages.base import LanguageSupport, FunctionInfo, CodeContext
389-
from codeflash.languages.treesitter_utils import TreeSitterAnalyzer
389+
from codeflash.languages.javascript.treesitter import TreeSitterAnalyzer
390390
from codeflash.languages.javascript.transformer import JavaScriptTransformer
391391

392392
class JavaScriptSupport(LanguageSupport):
@@ -523,7 +523,7 @@ class JavaScriptSupport(LanguageSupport):
523523
# codeflash/languages/javascript/test_discovery.py
524524

525525
from pathlib import Path
526-
from codeflash.languages.treesitter_utils import TreeSitterAnalyzer
526+
from codeflash.languages.javascript.treesitter import TreeSitterAnalyzer
527527

528528
class JestTestDiscovery:
529529
"""Static analysis-based test discovery for Jest."""

codeflash/code_utils/code_extractor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1772,7 +1772,7 @@ def _extract_calling_function_js(source_code: str, function_name: str, ref_line:
17721772
17731773
"""
17741774
try:
1775-
from codeflash.languages.treesitter_utils import TreeSitterAnalyzer, TreeSitterLanguage
1775+
from codeflash.languages.javascript.treesitter import TreeSitterAnalyzer, TreeSitterLanguage
17761776

17771777
# Try TypeScript first, fall back to JavaScript
17781778
for lang in [TreeSitterLanguage.TYPESCRIPT, TreeSitterLanguage.TSX, TreeSitterLanguage.JAVASCRIPT]:

codeflash/code_utils/code_replacer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
2828
from codeflash.languages.base import Language, LanguageSupport
29-
from codeflash.languages.treesitter_utils import TreeSitterAnalyzer
29+
from codeflash.languages.javascript.treesitter import TreeSitterAnalyzer
3030
from codeflash.models.models import CodeOptimizationContext, CodeStringsMarkdown, OptimizedCandidate, ValidCode
3131

3232
ASTNodeT = TypeVar("ASTNodeT", bound=ast.AST)
@@ -640,7 +640,7 @@ def _add_global_declarations_for_language(
640640
return original_source
641641

642642
try:
643-
from codeflash.languages.treesitter_utils import get_analyzer_for_file
643+
from codeflash.languages.javascript.treesitter import get_analyzer_for_file
644644

645645
analyzer = get_analyzer_for_file(module_abspath)
646646

codeflash/code_utils/concolic_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ def clean_concolic_tests(test_suite_code: str) -> str:
105105
can_parse = False
106106
tree = None
107107

108-
if not can_parse:
108+
if not can_parse or tree is None:
109109
return AssertCleanup().transform_asserts(test_suite_code)
110110

111111
for node in ast.walk(tree):
112112
if isinstance(node, ast.FunctionDef) and node.name.startswith("test_"):
113-
new_body = []
113+
new_body: list[ast.stmt] = []
114114
for stmt in node.body:
115115
if isinstance(stmt, ast.Assert):
116116
if isinstance(stmt.test, ast.Compare) and isinstance(stmt.test.left, ast.Call):

codeflash/code_utils/coverage_utils.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,28 @@
1313
def extract_dependent_function(main_function: str, code_context: CodeOptimizationContext) -> str | Literal[False]:
1414
"""Extract the single dependent function from the code context excluding the main function."""
1515
dependent_functions = set()
16+
17+
# Compare using bare name since AST extracts bare function names
18+
bare_main = main_function.rsplit(".", 1)[-1] if "." in main_function else main_function
19+
1620
for code_string in code_context.testgen_context.code_strings:
17-
ast_tree = ast.parse(code_string.code)
18-
dependent_functions.update(
19-
{node.name for node in ast_tree.body if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))}
20-
)
21+
# Quick heuristic: skip parsing entirely if there is no 'def' token,
22+
# since no function definitions can be present without it.
23+
if "def" not in code_string.code:
24+
continue
2125

22-
if main_function in dependent_functions:
23-
dependent_functions.discard(main_function)
26+
ast_tree = ast.parse(code_string.code)
27+
# Add function names directly, skipping the bare main name.
28+
for node in ast_tree.body:
29+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
30+
name = node.name
31+
if name == bare_main:
32+
continue
33+
dependent_functions.add(name)
34+
# If more than one dependent function (other than the main) is found,
35+
# we can return False early since the final result cannot be a single name.
36+
if len(dependent_functions) > 1:
37+
return False
2438

2539
if not dependent_functions:
2640
return False
@@ -32,6 +46,9 @@ def extract_dependent_function(main_function: str, code_context: CodeOptimizatio
3246

3347

3448
def build_fully_qualified_name(function_name: str, code_context: CodeOptimizationContext) -> str:
49+
# If the name is already qualified (contains a dot), return as-is
50+
if "." in function_name:
51+
return function_name
3552
full_name = function_name
3653
for obj_name, parents in code_context.preexisting_objects:
3754
if obj_name == function_name:

codeflash/code_utils/normalizers/javascript.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def normalize(self, code: str) -> str:
233233
234234
"""
235235
try:
236-
from codeflash.languages.treesitter_utils import TreeSitterAnalyzer, TreeSitterLanguage
236+
from codeflash.languages.javascript.treesitter import TreeSitterAnalyzer, TreeSitterLanguage
237237

238238
lang_map = {"javascript": TreeSitterLanguage.JAVASCRIPT, "typescript": TreeSitterLanguage.TYPESCRIPT}
239239
lang = lang_map.get(self._get_tree_sitter_language(), TreeSitterLanguage.JAVASCRIPT)

codeflash/discovery/functions_to_optimize.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def _is_js_ts_function_exported(file_path: Path, function_name: str) -> tuple[bo
201201
Tuple of (is_exported, export_name). export_name may be 'default' for default exports.
202202
203203
"""
204-
from codeflash.languages.treesitter_utils import get_analyzer_for_file
204+
from codeflash.languages.javascript.treesitter import get_analyzer_for_file
205205

206206
try:
207207
source = file_path.read_text(encoding="utf-8")

codeflash/github/PrComment.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ class PrComment:
2626

2727
def to_json(self) -> dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]]:
2828
report_table: dict[str, dict[str, int]] = {}
29-
for test_type, test_result in self.winning_behavior_test_results.get_test_pass_fail_report_by_type().items():
29+
for test_type, counts in self.winning_behavior_test_results.get_test_pass_fail_report_by_type().items():
3030
name = test_type.to_name()
3131
if name:
32-
report_table[name] = test_result
32+
report_table[name] = counts
3333

3434
result: dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]] = {
3535
"optimization_explanation": self.optimization_explanation,

0 commit comments

Comments
 (0)