> ## Documentation Index
> Fetch the complete documentation index at: https://codegeninc-codegen-bot-sdk-docs-2-0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Statements and Code Blocks

Codegen uses two classes to represent code structure at the highest level:

* [Statement](../api-reference/core/Statement): Represents a single line or block of code

  * Can be assignments, imports, loops, conditionals, etc.
  * Contains source code, dependencies, and type information
  * May contain nested code blocks (like in functions or loops)

* [CodeBlock](../api-reference/core/CodeBlock): A container for multiple Statements
  * Found in files, functions, classes, and control flow blocks
  * Provides APIs for analyzing and manipulating statements
  * Handles scope, variables, and dependencies

Codegen provides rich APIs for working with code statements and blocks, allowing you to analyze and manipulate code structure at a granular level.

## Working with Statements

### Basic Usage

Every file, function, and class in Codegen has a [CodeBlock](../api-reference/core/CodeBlock) that contains its statements:

```python
# Access statements in a file
file = codebase.get_file("main.py")
for statement in file.code_block.statements:
    print(f"Statement type: {statement.statement_type}")

# Access statements in a function
function = file.get_function("process_data")
for statement in function.code_block.statements:
    print(f"Statement: {statement.source}")
```

### Filtering Statements

Filter through statements using Python's builtin `isinstance` function.

```python
# Filter statements by type
for stmt in file.code_block.statements:
    if isinstance(stmt, ImportStatement):
        print(stmt)
```

### Adding Statements

Functions and Files support [.prepend\_statement(...)](../api-reference/core/Symbol#prepend-statement) and [.add\_statement(...)](../api-reference/core/Function#add-statement) to add statements to the symbol.

<Tip>
  See [Adding
  Statements](/building-with-codegen/symbol-api#function-statement-manipulation)
  for details.
</Tip>

### Working with Nested Structures

Frequently you will want to check if a statement is nested within another structure, for example if a statement is inside an `if` block or a `try/catch` statement.

Codegen supports this functionality with the [Editable.is\_wrapped\_in(...)](../api-reference/core/Editable#is-wrapped-in) method.

```python
func = codebase.get_function("process_data")
for usage in func.local_variable_usages:
    if usage.is_wrapped_in(IfStatement):
        print(f"Usage of {usage.name} is inside an if block")
```

Similarly, all Editable objects support the `.parent_statement`, which can be used to navigate the statement hierarchy.

```python
func = codebase.get_function("process_data")
for usage in func.local_variable_usages:
    if isinstance(usage.parent_statement, IfStatement):
        print(f"Usage of {usage.name} is directly beneath an IfStatement")
```

### Wrapping and Unwrapping Statements

[CodeBlocks](../api-reference/core/CodeBlock) support wrapping and unwrapping with the following APIs:

* [.wrap(...)](../api-reference/core/CodeBlock#wrap) - allows you to wrap a statement in a new structure.
* [.unwrap(...)](../api-reference/core/CodeBlock#unwrap) - allows you to remove the wrapping structure while preserving the code block's contents.

```python
# Wrap code blocks with new structures
function.code_block.wrap("with open('test.txt', 'w') as f:")
# Result:
#   with open('test.txt', 'w') as f:
#       original_code_here...

# Wrap code in a function
file.code_block.wrap("def process_data(a, b):")
# Result:
#   def process_data(a, b):
#       original_code_here...

# Unwrap code from its container
if_block.code_block.unwrap()  # Removes the if statement but keeps its body
while_loop.code_block.unwrap()  # Removes the while loop but keeps its body
```

<Warning>
  Both `wrap` and `unwrap` are potentially unsafe changes and will modify
  business logic.
</Warning>

<Note>
  The `unwrap()` method preserves the indentation of the code block's contents
  while removing the wrapping structure. This is useful for refactoring nested
  code structures.
</Note>

## Statement Types

Codegen supports various statement types, each with specific APIs:

### [Import Statements](../api-reference/core/ImportStatement) / [Export Statements](../api-reference/core/ExportStatement)

<Tip>
  See [imports](/building-with-codegen/imports) and [exports](../building-with-codegen/exports) for
  more details.
</Tip>

```python
# Access import statements
for import_stmt in file.import_statements:
    print(f"Module: {import_stmt.module}")
    for imported in import_stmt.imports:
        print(f"  Imported: {imported.name}")

# Remove specific imports
import_stmt = file.import_statements[0]
import_stmt.imports[0].remove()  # Remove first import

# Remove entire import statement
import_stmt.remove()
```

### [If/Else Statements](../api-reference/core/IfBlockStatement)

If/Else statements provide rich APIs for analyzing and manipulating conditional logic:

```python
# Access if/else blocks
if_block = file.code_block.statements[0]
print(f"Condition: {if_block.condition.source}")

# Check block types
if if_block.is_if_statement:
    print("Main if block")
elif if_block.is_elif_statement:
    print("Elif block")
elif if_block.is_else_statement:
    print("Else block")

# Access alternative blocks
for elif_block in if_block.elif_statements:
    print(f"Elif condition: {elif_block.condition.source}")

if else_block := if_block.else_statement:
    print("Has else block")

# Access nested code blocks
for block in if_block.nested_code_blocks:
    print(f"Block statements: {len(block.statements)}")
```

If blocks also support condition reduction, which can simplify conditional logic:

```python
# Reduce if condition to True
if_block.reduce_condition(True)
# Before:
#   if condition:
#       print("a")
#   else:
#       print("b")
# After:
#   print("a")

# Reduce elif condition to False
elif_block.reduce_condition(False)
# Before:
#   if a:
#       print("a")
#   elif condition:
#       print("b")
#   else:
#       print("c")
# After:
#   if a:
#       print("a")
#   else:
#       print("c")
```

<Note>
  When reducing conditions, Codegen automatically handles the restructuring of
  elif/else chains and preserves the correct control flow.
</Note>

### [Switch](../api-reference/core/SwitchStatement)/[Match](../api-reference/python/PyMatchStatement) Statements

```python
# TypeScript switch statements
switch_stmt = file.code_block.statements[0]
for case_stmt in switch_stmt.cases:
    print(f"Case condition: {case_stmt.condition}")
    print(f"Is default: {case_stmt.default}")

    # Access statements in each case
    for statement in case_stmt.code_block.statements:
        print(f"Statement: {statement.source}")

# Python match statements
match_stmt = file.code_block.statements[0]
for case in match_stmt.cases:
    print(f"Pattern: {case.pattern}")
    for statement in case.code_block.statements:
        print(f"Statement: {statement.source}")
```

### [While Statements](../api-reference/core/WhileStatement)

```python
while_stmt = file.code_block.statements[0]
print(f"Condition: {while_stmt.condition}")

# Access loop body
for statement in while_stmt.code_block.statements:
    print(f"Body statement: {statement.source}")

# Get function calls within the loop
for call in while_stmt.function_calls:
    print(f"Function call: {call.source}")
```

### [Assignment Statements](../api-reference/core/AssignmentStatement)

```python
# Access assignments in a code block
for statement in code_block.statements:
    if statement.statement_type == StatementType.ASSIGNMENT:
        for assignment in statement.assignments:
            print(f"Variable: {assignment.name}")
            print(f"Value: {assignment.value}")
```

## Working with Code Blocks

Code blocks provide several ways to analyze and manipulate their content:

### Statement Access

```python
code_block = function.code_block

# Get all statements
all_statements = code_block.statements

# Get statements by type
if_blocks = code_block.if_blocks
while_loops = code_block.while_loops
try_blocks = code_block.try_blocks

# Get local variables
local_vars = code_block.get_local_var_assignments()
```

### Statement Dependencies

```python
# Get dependencies between statements
function = file.get_function("process")
for statement in function.code_block.statements:
    deps = statement.dependencies
    print(f"Statement {statement.source} depends on: {[d.name for d in deps]}")
```

### Parent-Child Relationships

```python
# Access parent statements
function = file.get_function("main")
parent_stmt = function.parent_statement

# Access nested symbols
class_def = file.get_class("MyClass")
for method in class_def.methods:
    parent = method.parent_statement
    print(f"Method {method.name} is defined in {parent.source}")
```

## Common Operations

### Finding Statements

```python
# Find specific statements
assignments = [s for s in code_block.statements
              if s.statement_type == StatementType.ASSIGNMENT]

# Find statements by content
matching = [s for s in code_block.statements
           if "specific_function()" in s.source]
```

### Analyzing Flow Control

```python
# Analyze control flow
for statement in code_block.statements:
    if statement.statement_type == StatementType.IF_BLOCK:
        print("Condition:", statement.condition)
        print("Then:", statement.consequence_block.statements)
        if statement.alternative_block:
            print("Else:", statement.alternative_block.statements)
```

### Working with Functions

```python
# Analyze function calls in statements
for statement in code_block.statements:
    for call in statement.function_calls:
        print(f"Calls function: {call.name}")
        print(f"With arguments: {[arg.source for arg in call.arguments]}")
```
