|
12 | 12 |
|
13 | 13 | import git |
14 | 14 | import libcst as cst |
15 | | -from pydantic import Field |
16 | 15 | from pydantic.dataclasses import dataclass |
17 | 16 | from rich.tree import Tree |
18 | 17 |
|
|
30 | 29 | from codeflash.languages.language_enum import Language |
31 | 30 | from codeflash.languages.registry import get_language_support, get_supported_extensions, is_language_supported |
32 | 31 | from codeflash.lsp.helpers import is_LSP_enabled |
33 | | -from codeflash.models.models import FunctionParent |
| 32 | +from codeflash.models.function_types import FunctionParent, FunctionToOptimize |
34 | 33 | from codeflash.telemetry.posthog_cf import ph |
35 | 34 |
|
| 35 | +# Re-export for backward compatibility |
| 36 | +__all__ = ["FunctionParent", "FunctionToOptimize"] |
| 37 | + |
36 | 38 | if TYPE_CHECKING: |
37 | 39 | from argparse import Namespace |
38 | 40 |
|
39 | 41 | from libcst import CSTNode |
40 | 42 | from libcst.metadata import CodeRange |
41 | 43 |
|
42 | | - from codeflash.languages.base import FunctionInfo |
43 | 44 | from codeflash.models.models import CodeOptimizationContext |
44 | 45 | from codeflash.verification.verification_utils import TestConfig |
45 | 46 | import contextlib |
@@ -130,97 +131,6 @@ def generic_visit(self, node: ast.AST) -> None: |
130 | 131 | self.ast_path.pop() |
131 | 132 |
|
132 | 133 |
|
133 | | -@dataclass(frozen=True, config={"arbitrary_types_allowed": True}) |
134 | | -class FunctionToOptimize: |
135 | | - """Represent a function that is a candidate for optimization. |
136 | | -
|
137 | | - This is the canonical dataclass for representing functions across all languages |
138 | | - (Python, JavaScript, TypeScript). It captures all information needed to identify, |
139 | | - locate, and work with a function. |
140 | | -
|
141 | | - Attributes |
142 | | - ---------- |
143 | | - function_name: The name of the function. |
144 | | - file_path: The absolute file path where the function is located. |
145 | | - parents: A list of parent scopes, which could be classes or functions. |
146 | | - starting_line: The starting line number of the function in the file (1-indexed). |
147 | | - ending_line: The ending line number of the function in the file (1-indexed). |
148 | | - starting_col: The starting column offset (0-indexed, for precise location). |
149 | | - ending_col: The ending column offset (0-indexed, for precise location). |
150 | | - is_async: Whether this function is defined as async. |
151 | | - is_method: Whether this is a method (belongs to a class). |
152 | | - language: The programming language of this function (default: "python"). |
153 | | - doc_start_line: Line where docstring/JSDoc starts (or None if no doc comment). |
154 | | -
|
155 | | - The qualified_name property provides the full name of the function, including |
156 | | - any parent class or function names. The qualified_name_with_modules_from_root |
157 | | - method extends this with the module name from the project root. |
158 | | -
|
159 | | - """ |
160 | | - |
161 | | - function_name: str |
162 | | - file_path: Path |
163 | | - parents: list[FunctionParent] = Field(default_factory=list) # list[ClassDef | FunctionDef | AsyncFunctionDef] |
164 | | - starting_line: Optional[int] = None |
165 | | - ending_line: Optional[int] = None |
166 | | - starting_col: Optional[int] = None # Column offset for precise location |
167 | | - ending_col: Optional[int] = None # Column offset for precise location |
168 | | - is_async: bool = False |
169 | | - is_method: bool = False # Whether this is a method (belongs to a class) |
170 | | - language: str = "python" # Language identifier for multi-language support |
171 | | - doc_start_line: Optional[int] = None # Line where docstring/JSDoc starts |
172 | | - |
173 | | - @property |
174 | | - def top_level_parent_name(self) -> str: |
175 | | - return self.function_name if not self.parents else self.parents[0].name |
176 | | - |
177 | | - @property |
178 | | - def class_name(self) -> str | None: |
179 | | - """Get the immediate parent class name, if any.""" |
180 | | - for parent in reversed(self.parents): |
181 | | - if parent.type == "ClassDef": |
182 | | - return parent.name |
183 | | - return None |
184 | | - |
185 | | - def __str__(self) -> str: |
186 | | - qualified = f"{'.'.join([p.name for p in self.parents])}{'.' if self.parents else ''}{self.function_name}" |
187 | | - line_info = f":{self.starting_line}-{self.ending_line}" if self.starting_line and self.ending_line else "" |
188 | | - return f"{self.file_path}:{qualified}{line_info}" |
189 | | - |
190 | | - @property |
191 | | - def qualified_name(self) -> str: |
192 | | - if not self.parents: |
193 | | - return self.function_name |
194 | | - # Join all parent names with dots to handle nested classes properly |
195 | | - parent_path = ".".join(parent.name for parent in self.parents) |
196 | | - return f"{parent_path}.{self.function_name}" |
197 | | - |
198 | | - def qualified_name_with_modules_from_root(self, project_root_path: Path) -> str: |
199 | | - return f"{module_name_from_file_path(self.file_path, project_root_path)}.{self.qualified_name}" |
200 | | - |
201 | | - @classmethod |
202 | | - def from_function_info(cls, func_info: FunctionInfo) -> FunctionToOptimize: |
203 | | - """Create a FunctionToOptimize from a FunctionInfo instance. |
204 | | -
|
205 | | - This is a temporary method for backward compatibility during migration. |
206 | | - Once FunctionInfo is fully removed, this method can be deleted. |
207 | | - """ |
208 | | - parents = [FunctionParent(name=p.name, type=p.type) for p in func_info.parents] |
209 | | - return cls( |
210 | | - function_name=func_info.name, |
211 | | - file_path=func_info.file_path, |
212 | | - parents=parents, |
213 | | - starting_line=func_info.start_line, |
214 | | - ending_line=func_info.end_line, |
215 | | - starting_col=func_info.start_col, |
216 | | - ending_col=func_info.end_col, |
217 | | - is_async=func_info.is_async, |
218 | | - is_method=func_info.is_method, |
219 | | - language=func_info.language.value, |
220 | | - doc_start_line=func_info.doc_start_line, |
221 | | - ) |
222 | | - |
223 | | - |
224 | 134 | # ============================================================================= |
225 | 135 | # Multi-language support helpers |
226 | 136 | # ============================================================================= |
@@ -421,7 +331,7 @@ def get_functions_to_optimize( |
421 | 331 | # It's a standalone function - check if the function is exported |
422 | 332 | name_to_check = found_function.function_name |
423 | 333 |
|
424 | | - is_exported, export_name = _is_js_ts_function_exported(file, name_to_check) |
| 334 | + is_exported, _ = _is_js_ts_function_exported(file, name_to_check) |
425 | 335 | if not is_exported: |
426 | 336 | if found_function.parents: |
427 | 337 | logger.debug( |
|
0 commit comments