> For the complete documentation index, see [llms.txt](https://gofast.disasm.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gofast.disasm.dev/basics/manipulating-ast.md).

# Manipulating ASTs

The `go-fAST` library provides a powerful and flexible mechanism to walk and transform Abstract Syntax Trees (ASTs). This guide explains how you can **safely and correctly modify ASTs** during traversal using custom visitors.

### 💡 Key Concepts

#### Node Replacement Rules

When modifying the AST, it’s **critical** that replacement nodes conform to the expected type. For example:

* You **can** replace an `*ast.Expression` with another `*ast.Expression` wrapping a different inner `Expr`.
* Since you must replace nodes with their equivilent types, as an example what you **cannot** do is replace an `*ast.ForStatement` with an `*ast.Identifier`.

#### Statement vs Expression

All nodes in the AST are either:

* A **statement**, implementing the `ast.Stmt` interface.
* An **expression**, implementing the `ast.Expr` interface.

Always ensure you're replacing nodes **with compatible interface types**.

### 🔁 Example: Replacing Number Literals with Strings

Below is an example demonstrating how to replace every number literal with a string literal containing `"foo"`:

```go
goCopyEdittype ExampleVisitor struct {
    ast.NoopVisitor
}

func (v *ExampleVisitor) VisitExpression(n *ast.Expression) {
    // Step 1: Visit child expressions first
    n.VisitChildrenWith(v)

    // Step 2: Check if this is a number literal
    _, isNumberLiteral := n.Expr.(*ast.NumberLiteral)
    if !isNumberLiteral {
        return // Not a number literal; no replacement needed
    }

    // Step 3: Create a new string literal expression
    replacement := "foo"
    *n = ast.Expression{
        Expr: &ast.StringLiteral{
            Value:   replacement,
        },
    }
}
```

### 🔍 Input JavaScript (Before Visitor)

```js
var x = 42;
var y = x + 8;
console.log(y);
```

### 🔄 Transformed JavaScript (After Visitor)

```js
var x = "foo";
var y = x + "foo";
console.log(y);
```

#### Notes:

* The `VisitChildrenWith(v)` call ensures recursive traversal before mutation (to ensure children of this Expression are visited and replaced)
* The replacement assigns directly to `*n`, ensuring the parent retains the correct `*ast.Expression` type.

### Statement & Expression Types

If a node is a statement, it will implement the `ast.Stmt` interface. If it is an expression, it will implement the `ast.Expr` interface.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gofast.disasm.dev/basics/manipulating-ast.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
