Skip to content

Commit 7ad4624

Browse files
authored
Add duplicate_dependencies strategy to move_to_file (#238)
# Motivation <!-- Why is this change necessary? --> # Content <!-- Please include a summary of the change --> # Testing <!-- How was the change tested? --> # Please check the following before marking your PR as ready for review - [ ] I have added tests for my changes - [ ] I have updated the documentation or added new documentation as needed
1 parent c322214 commit 7ad4624

File tree

4 files changed

+666
-18
lines changed

4 files changed

+666
-18
lines changed

src/codegen/sdk/core/symbol.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,12 @@ def insert_before(self, new_src: str, fix_indentation: bool = False, newline: bo
266266
return first_node.insert_before(new_src, fix_indentation, newline, priority, dedupe)
267267
return super().insert_before(new_src, fix_indentation, newline, priority, dedupe)
268268

269-
def move_to_file(self, file: SourceFile, include_dependencies: bool = True, strategy: str = "update_all_imports") -> None:
269+
def move_to_file(
270+
self,
271+
file: SourceFile,
272+
include_dependencies: bool = True,
273+
strategy: Literal["add_back_edge", "update_all_imports", "duplicate_dependencies"] = "update_all_imports",
274+
) -> None:
270275
"""Moves the given symbol to a new file and updates its imports and references.
271276
272277
This method moves a symbol to a new file and updates all references to that symbol throughout the codebase. The way imports are handled can be controlled via the strategy parameter.
@@ -288,7 +293,13 @@ def move_to_file(self, file: SourceFile, include_dependencies: bool = True, stra
288293
self._move_to_file(file, encountered_symbols, include_dependencies, strategy)
289294

290295
@noapidoc
291-
def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Import], include_dependencies: bool = True, strategy: str = "update_all_imports") -> tuple[NodeId, NodeId]:
296+
def _move_to_file(
297+
self,
298+
file: SourceFile,
299+
encountered_symbols: set[Symbol | Import],
300+
include_dependencies: bool = True,
301+
strategy: Literal["add_back_edge", "update_all_imports", "duplicate_dependencies"] = "update_all_imports",
302+
) -> tuple[NodeId, NodeId]:
292303
"""Helper recursive function for `move_to_file`"""
293304
from codegen.sdk.core.import_resolution import Import
294305

@@ -342,11 +353,20 @@ def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Impo
342353
usage.file == self.file and usage.node_type == NodeType.SYMBOL and usage not in encountered_symbols and (usage.start_byte < self.start_byte or usage.end_byte > self.end_byte) # HACK
343354
for usage in self.symbol_usages
344355
)
356+
357+
# ======[ Strategy: Duplicate Dependencies ]=====
358+
if strategy == "duplicate_dependencies":
359+
# If not used in the original file. or if not imported from elsewhere, we can just remove the original symbol
360+
if not is_used_in_file and not any(usage.kind is UsageKind.IMPORTED and usage.usage_symbol not in encountered_symbols for usage in self.usages):
361+
self.remove()
362+
345363
# ======[ Strategy: Add Back Edge ]=====
346364
# Here, we will add a "back edge" to the old file importing the symbol
347-
if strategy == "add_back_edge":
365+
elif strategy == "add_back_edge":
348366
if is_used_in_file or any(usage.kind is UsageKind.IMPORTED and usage.usage_symbol not in encountered_symbols for usage in self.usages):
349367
self.file.add_import_from_import_string(import_line)
368+
# Delete the original symbol
369+
self.remove()
350370

351371
# ======[ Strategy: Update All Imports ]=====
352372
# Update the imports in all the files which use this symbol to get it from the new file now
@@ -365,10 +385,11 @@ def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Impo
365385
usage.match.edit(self.name)
366386
usage.usage_symbol.file.add_import_from_import_string(import_line)
367387

388+
# Add the import to the original file
368389
if is_used_in_file:
369390
self.file.add_import_from_import_string(import_line)
370-
# =====[ Delete the original symbol ]=====
371-
self.remove()
391+
# Delete the original symbol
392+
self.remove()
372393

373394
@property
374395
@reader

src/codegen/sdk/typescript/symbol.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING
3+
from typing import TYPE_CHECKING, Literal
44

55
from codegen.sdk.core.assignment import Assignment
66
from codegen.sdk.core.autocommit import reader, writer
7-
from codegen.sdk.core.dataclasses.usage import UsageType
7+
from codegen.sdk.core.dataclasses.usage import UsageKind, UsageType
88
from codegen.sdk.core.detached_symbols.function_call import FunctionCall
99
from codegen.sdk.core.expressions import Value
1010
from codegen.sdk.core.expressions.chained_attribute import ChainedAttribute
@@ -253,9 +253,14 @@ def has_semicolon(self) -> bool:
253253
return self.semicolon_node is not None
254254

255255
@noapidoc
256-
def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Import], include_dependencies: bool = True, strategy: str = "update_all_imports") -> tuple[NodeId, NodeId]:
256+
def _move_to_file(
257+
self,
258+
file: SourceFile,
259+
encountered_symbols: set[Symbol | Import],
260+
include_dependencies: bool = True,
261+
strategy: Literal["add_back_edge", "update_all_imports", "duplicate_dependencies"] = "update_all_imports",
262+
) -> tuple[NodeId, NodeId]:
257263
# TODO: Prevent creation of import loops (!) - raise a ValueError and make the agent fix it
258-
# TODO: Implement `update_all_imports` strategy
259264
# =====[ Arg checking ]=====
260265
if file == self.file:
261266
return file.file_node_id, self.node_id
@@ -318,16 +323,25 @@ def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Impo
318323
# =====[ Checks if symbol is used in original file ]=====
319324
# Takes into account that it's dependencies will be moved
320325
is_used_in_file = any(usage.file == self.file and usage.node_type == NodeType.SYMBOL and usage not in encountered_symbols for usage in self.symbol_usages)
326+
327+
# ======[ Strategy: Duplicate Dependencies ]=====
328+
if strategy == "duplicate_dependencies":
329+
# If not used in the original file. or if not imported from elsewhere, we can just remove the original symbol
330+
if not is_used_in_file and not any(usage.kind is UsageKind.IMPORTED and usage.usage_symbol not in encountered_symbols for usage in self.usages):
331+
self.remove()
332+
321333
# ======[ Strategy: Add Back Edge ]=====
322334
# Here, we will add a "back edge" to the old file importing the self
323-
if strategy == "add_back_edge":
335+
elif strategy == "add_back_edge":
324336
if is_used_in_file:
325337
self.file.add_import_from_import_string(import_line)
326338
if self.is_exported:
327339
self.file.add_import_from_import_string(f"export {{ {self.name} }}")
328340
elif self.is_exported:
329341
module_name = file.name
330342
self.file.add_import_from_import_string(f"export {{ {self.name} }} from '{module_name}'")
343+
# Delete the original symbol
344+
self.remove()
331345

332346
# ======[ Strategy: Update All Imports ]=====
333347
# Update the imports in all the files which use this symbol to get it from the new file now
@@ -348,8 +362,8 @@ def _move_to_file(self, file: SourceFile, encountered_symbols: set[Symbol | Impo
348362
usage.usage_symbol.file.add_import_from_import_string(import_line)
349363
if is_used_in_file:
350364
self.file.add_import_from_import_string(import_line)
351-
# =====[ Delete the original symbol ]=====
352-
self.remove()
365+
# Delete the original symbol
366+
self.remove()
353367

354368
def _convert_proptype_to_typescript(self, prop_type: Editable, param: Parameter | None, level: int) -> str:
355369
"""Converts a PropType definition to its TypeScript equivalent."""

0 commit comments

Comments
 (0)