Codegen’s GraphSitter library provides powerful APIs for identifying and removing dead code from your codebase. This guide will walk you through the process of detecting and deleting unused functions, classes, and imports.

Common use cases include:

  • Removing unused functions and methods
  • Eliminating dead imports
  • Cleaning up unused variables and parameters

Overview

Deleting dead code involves identifying unused elements and safely removing them. Here’s a basic example:

# Iterate through all functions in the codebase
for function in codebase.functions:
    # Skip test files
    if "test" in function.file.filepath:
        continue

    # Skip decorated functions
    if function.decorators:
        continue

    # Remove functions with no usages
    if not function.usages:
        print(f"Removing unused function '{function.name}' from '{function.file.filepath}'")
        function.remove()

Removing Unused Functions

To remove unused functions, you can check for the absence of usages and call sites:

for function in codebase.functions:
    # Check if the function has no usages and no call sites
    if not function.usages and not function.call_sites:
        # Print a message indicating the removal of the function
        print(f"Removing unused function: {function.name}")
        # Remove the function from the file
        function.remove()

Eliminating Dead Imports

To remove unused imports, you can check if the imported symbol has any usages:

for import_stmt in codebase.imports:
    # Check if the import statement has no usages
    if not import_stmt.usages:
        # Print a message indicating the removal of the unused import
        print(f"Removing unused import: {import_stmt.name}")
        # Remove the import statement from the file
        import_stmt.remove()

Cleaning Up Unused Variables

To remove unused variables, you can check for their usages within their scope:

for func in codebase.functions:
    # Iterate through local variable assignments in the function
    for var_assignments in func.code_block.local_var_assignments:
        # Check if the local variable assignment has no usages
        if not var_assignments.local_usages:
            # Remove the local variable assignment
            var_assignments.remove()

Ignoring False Positives

Every codebase is different, and usually there’s a (small) set of things that could look like dead code but aren’t.

Simply tell the assistant to avoid certain cases (like files starting with test_, or children of a specific class).

Removing Dead Classes

To remove unused classes, check for the absence of usages:

for cls in codebase.classes:
    # Check if the class has no usages
    if not cls.usages:
        # Print a message indicating the removal of the unused class
        print(f"Removing unused class: {cls.name}")
        # Remove the class from the file
        cls.remove()

Cleaning Up After Removal

After removing dead code, you may need to clean up any remaining artifacts:

for file in codebase.files:
    # Check if the file is empty
    if not file.content.strip():
        # Print a message indicating the removal of the empty file
        print(f"Removing empty file: {file.filepath}")
        # Remove the empty file
        file.remove()

# commit is NECESSARY to remove the files from the codebase
codebase.commit()

# Remove redundant newlines
for file in codebase.files:
    # Replace three or more consecutive newlines with two newlines
    file.edit(re.sub(r"\n{3,}", "\n\n", file.content))

Best Practices

  1. Use Caution: Always double-check before removing code, especially for elements that might be used dynamically or in hard-to-detect ways.

  2. Incremental Removal: Remove dead code in stages, committing and testing after each stage to ensure you haven’t broken anything.

  3. Consider Visibility: Be extra cautious when removing public APIs or elements that might be used by external code.

  4. Update Documentation: After removing dead code, update any related documentation or comments to maintain consistency.

  5. Use Version Control: Always perform these operations in a version-controlled environment, so you can easily revert changes if needed.

By following these guidelines, you can effectively clean up your codebase by removing dead code while maintaining its integrity and functionality.

Was this page helpful?