Skip to content

Commit 7e34379

Browse files
Merge pull request #1214 from codeflash-ai/fix/validate-js-function-exports
fix: validate JS/TS functions are exported before optimization
2 parents 13e35ca + c9e75f8 commit 7e34379

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

codeflash/discovery/functions_to_optimize.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,32 @@ def get_files_for_language(
216216
return files
217217

218218

219+
def _is_js_ts_function_exported(file_path: Path, function_name: str) -> tuple[bool, str | None]:
220+
"""Check if a JavaScript/TypeScript function is exported from its module.
221+
222+
For JS/TS, functions that are not exported cannot be imported by tests,
223+
making them impossible to optimize.
224+
225+
Args:
226+
file_path: Path to the source file.
227+
function_name: Name of the function to check.
228+
229+
Returns:
230+
Tuple of (is_exported, export_name). export_name may be 'default' for default exports.
231+
232+
"""
233+
from codeflash.languages.treesitter_utils import get_analyzer_for_file
234+
235+
try:
236+
source = file_path.read_text(encoding="utf-8")
237+
analyzer = get_analyzer_for_file(file_path)
238+
return analyzer.is_function_exported(source, function_name)
239+
except Exception as e:
240+
logger.debug(f"Failed to check export status for {function_name}: {e}")
241+
# Return True to avoid blocking in case of errors
242+
return True, None
243+
244+
219245
def _find_all_functions_in_python_file(file_path: Path) -> dict[Path, list[FunctionToOptimize]]:
220246
"""Find all optimizable functions in a Python file using AST parsing.
221247
@@ -338,6 +364,36 @@ def get_functions_to_optimize(
338364
exit_with_message(
339365
f"Function {only_get_this_function} not found in file {file}\nor the function does not have a 'return' statement or is a property"
340366
)
367+
368+
# For JavaScript/TypeScript, verify that the function (or its parent class) is exported
369+
# Non-exported functions cannot be imported by tests
370+
if found_function.language in ("javascript", "typescript"):
371+
# For class methods, check if the parent class is exported
372+
# For standalone functions, check if the function itself is exported
373+
if found_function.parents:
374+
# It's a class method - check if the class is exported
375+
name_to_check = found_function.top_level_parent_name
376+
else:
377+
# It's a standalone function - check if the function is exported
378+
name_to_check = found_function.function_name
379+
380+
is_exported, export_name = _is_js_ts_function_exported(file, name_to_check)
381+
if not is_exported:
382+
if found_function.parents:
383+
logger.debug(
384+
f"Class '{name_to_check}' containing method '{found_function.function_name}' "
385+
f"is not exported from {file}. "
386+
f"In JavaScript/TypeScript, only exported classes/functions can be optimized "
387+
f"because tests need to import them."
388+
)
389+
else:
390+
logger.debug(
391+
f"Function '{found_function.function_name}' is not exported from {file}. "
392+
f"In JavaScript/TypeScript, only exported functions can be optimized because "
393+
f"tests need to import them."
394+
)
395+
return {}, 0, None
396+
341397
functions[file] = [found_function]
342398
else:
343399
logger.info("Finding all functions modified in the current git diff ...")

tests/test_javascript_function_discovery.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,11 @@ def test_get_specific_function(self, tmp_path):
346346
"""Test getting a specific function by name."""
347347
js_file = tmp_path / "math_utils.js"
348348
js_file.write_text("""
349-
function add(a, b) {
349+
export function add(a, b) {
350350
return a + b;
351351
}
352352
353-
function subtract(a, b) {
353+
export function subtract(a, b) {
354354
return a - b;
355355
}
356356
""")
@@ -378,7 +378,7 @@ def test_get_class_method(self, tmp_path):
378378
"""Test getting a specific class method."""
379379
js_file = tmp_path / "calculator.js"
380380
js_file.write_text("""
381-
class Calculator {
381+
export class Calculator {
382382
add(a, b) {
383383
return a + b;
384384
}
@@ -388,7 +388,7 @@ class Calculator {
388388
}
389389
}
390390
391-
function standaloneFunc() {
391+
export function standaloneFunc() {
392392
return 42;
393393
}
394394
""")

0 commit comments

Comments
 (0)