@@ -73,7 +73,76 @@ def dir_excludes(self) -> frozenset[str]:
7373 def discover_functions (
7474 self , file_path : Path , filter_criteria : FunctionFilterCriteria | None = None
7575 ) -> list [FunctionToOptimize ]:
76- raise NotImplementedError
76+ """Find all optimizable functions in a JavaScript file.
77+
78+ Uses tree-sitter to parse the file and find functions.
79+
80+ Args:
81+ file_path: Path to the JavaScript file to analyze.
82+ filter_criteria: Optional criteria to filter functions.
83+
84+ Returns:
85+ List of FunctionToOptimize objects for discovered functions.
86+
87+ """
88+ criteria = filter_criteria or FunctionFilterCriteria ()
89+
90+ try :
91+ source = file_path .read_text (encoding = "utf-8" )
92+ except Exception as e :
93+ logger .warning ("Failed to read %s: %s" , file_path , e )
94+ return []
95+
96+ try :
97+ analyzer = get_analyzer_for_file (file_path )
98+ tree_functions = analyzer .find_functions (
99+ source , include_methods = criteria .include_methods , include_arrow_functions = True , require_name = True
100+ )
101+
102+ functions : list [FunctionToOptimize ] = []
103+ for func in tree_functions :
104+ # Check for return statement if required
105+ if criteria .require_return and not analyzer .has_return_statement (func , source ):
106+ continue
107+
108+ # Check async filter
109+ if not criteria .include_async and func .is_async :
110+ continue
111+
112+ # Skip non-exported functions (can't be imported in tests)
113+ # Exception: nested functions and methods are allowed if their parent is exported
114+ if not func .is_exported and not func .parent_function :
115+ logger .debug (f"Skipping non-exported function: { func .name } " ) # noqa: G004
116+ continue
117+
118+ # Build parents list
119+ parents : list [FunctionParent ] = []
120+ if func .class_name :
121+ parents .append (FunctionParent (name = func .class_name , type = "ClassDef" ))
122+ if func .parent_function :
123+ parents .append (FunctionParent (name = func .parent_function , type = "FunctionDef" ))
124+
125+ functions .append (
126+ FunctionToOptimize (
127+ function_name = func .name ,
128+ file_path = file_path ,
129+ parents = parents ,
130+ starting_line = func .start_line ,
131+ ending_line = func .end_line ,
132+ starting_col = func .start_col ,
133+ ending_col = func .end_col ,
134+ is_async = func .is_async ,
135+ is_method = func .is_method ,
136+ language = str (self .language ),
137+ doc_start_line = func .doc_start_line ,
138+ )
139+ )
140+
141+ return functions
142+
143+ except Exception as e :
144+ logger .warning ("Failed to parse %s: %s" , file_path , e )
145+ return []
77146
78147 def discover_functions_from_source (self , source : str , file_path : Path | None = None ) -> list [FunctionToOptimize ]:
79148 """Find all functions in source code string.
0 commit comments