The Symbol is the primary way developers interact with code in Codegen. It maps to how developers think about code - as functions, classes, variables, and other named entities.

Both the Function and Class symbols are subclasses of the Symbol class.

Accessing Symbols

The Codebase class provides getters and iterators for functions, classes and symbols:

# Core symbol types
symbol = codebase.get_symbol("process_data") # will return a Function, Class, etc.
function = codebase.get_function("process_data")
class_def = codebase.get_class("DataProcessor")

# Iterate over all symbols (includes functions + classes)
for symbol in codebase.symbols:
    print(symbol.name)

# Iterate over all functions and classes
for symbol in codebase.functions + codebase.classes:
    print(symbol.name)

Shared APIs

All symbols share common APIs for manipulation:

Name operations

# Name operations
print(symbol.name)
symbol.rename("new_name")

# Source code
print(symbol.source)  # Get source code
symbol.edit("new source code")  # Modify source

# Documentation
print(symbol.docstring)  # Get docstring
symbol.set_docstring("New documentation")

# Move symbol to new file
symbol.move_to_file(new_file)

# Add before/after other symbols
symbol.insert_before("# deprecated")
symbol.insert_after("# end deprecated")

Function Statement Manipulation

Functions provide special APIs for adding statements to their body:

# Add statements at the start of a function
function.prepend_statements("print('Starting function')")
method.prepend_statements("self.validate_input()")

# Add statements at the end of a function
function.add_statements("print('Done')")
method.add_statements("return self.result")

The statement manipulation APIs (prepend_statements and add_statements) are only available on Function objects. For other symbols, use the general Editable APIs like insert_before and insert_after.

Common Patterns

Most Codegen programs focus on finding and manipulating symbols:

# Find and modify functions
for function in codebase.functions:
    if function.name.startswith("old_"):
        # Rename function
        function.rename(function.name.replace("old_", "new_"))
        # Update docstring
        function.set_docstring("Updated version of function")

# Update class methods
for method in class_def.methods:
    # Add logging
    method.prepend_statements("logger.info('Called {}'".format(method.name))

The Symbol API is designed to be intuitive and match how developers think about code. Most transformations start with finding relevant symbols and then applying changes to them.

Was this page helpful?