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.