> 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/built-in-visitors/resolver.md).

# Resolver

The **Resolver** module enables **lexical scope resolution** for all `Identifier` nodes in an AST. Since `go-fAST` does not maintain any concept of scope natively, this module fills the gap by assigning scope contexts to each identifier—allowing you to differentiate between otherwise identical names that exist in different scopes.

### 🧠 Why Is This Useful?

Consider this JavaScript example:

```js
var name = "Alice";

function greet() {
  var name = "Bob"; // This 'name' shadows the outer 'name'
  console.log("Hello, " + name);
}

greet();
console.log(name);
```

In this code:

* There are **two different `name` identifiers**, even though their text content is the same.
* Without scope tracking, a transformation or analysis pass might treat both `name`s as referring to the same variable.

By running `resolver.Resolve()`, each `Identifier` node is assigned a **ScopeContext**, a numeric marker unique to its lexical scope. You can then use `.ToId()` to disambiguate:

```go
if id1.ToId() == id2.ToId() {
    fmt.Println("Same scoped variable")
} else {
    fmt.Println("Different scopes")
}
```

### ⚙️ How It Works

Internally, the resolver:

* Traverses the AST using a visitor pattern.
* Creates new **`Scope`** instances for:
  * Function bodies
  * Block statements
  * Loop constructs
* Tracks variable **declarations** and **references** via a `declaredSymbols` map.
* Assigns a unique `ScopeContext` value (a `uint64`) to each scope and identifier.

The resolver also accounts for **JavaScript-specific semantics**, such as:

* **Variable hoisting**
* **Function declarations before usage**
* **Catch parameter exclusions**
* **Rest and computed parameters**

***

### ✅ When to Use `resolver.Resolve()`

You should run the resolver **before any identifier analysis or transformation**:

* 🔍 **Analyzing references**: e.g., finding unused variables or scope violations.
* 🔁 **Replacing identifiers**: e.g., renaming variables safely.
* ✂️ **Removing code**: ensuring you don’t break bindings.

#### Re-running After Modifications

If you modify the AST and introduce **new `Identifier`s** (e.g., via transformations or visitors), you **must re-run** `resolver.Resolve()` to ensure the new nodes have correct scope information.

***

### 🧪 Example Usage

```go
import (
	"fmt"
	"os"

	"github.com/t14raptor/go-fast/parser"
	"github.com/t14raptor/go-fast/resolver"
)

func main() {
	code, err := os.ReadFile("example.js")
	if err != nil {
		panic(err)
	}
	ast, err := parser.ParseFile(string(code))
	if err != nil {
		panic(err)
	}

	// Run scope resolution
	resolver.Resolve(ast)

	// Inspect resolved identifiers
	visitor := &ExampleVisitor{}
	visitor.V = visitor
	ast.VisitWith(visitor)
}

type ExampleVisitor struct {
	ast.NoopVisitor
}

func (v *ExampleVisitor) VisitIdentifier(n *ast.Identifier) {
	fmt.Println(n.Name, "-> ScopeContext:", n.ScopeContext)
}
```

### 🧠 What `.ToId()` Does

Calling `.ToId()` on an `*ast.Identifier` returns an `ast.Id` struct that combines:

* The identifier’s name
* Its resolved `ScopeContext`

This guarantees a unique ID per variable **per scope**, enabling safe comparisons and replacements.

***

### 💥 Common Mistakes

* **Skipping resolver** before analysis: all `ScopeContext` values will remain `0` (unresolved).
* **Modifying AST without re-running resolver**: new nodes will have `ScopeContext = 0` and will break future comparisons.
* **Assuming name equality means reference equality**: always use `.ToId()`.

### 🛠️ Advanced: Hoisting Support

The resolver includes a built-in **hoister**, which mimics JavaScript’s hoisting behavior:

* Function declarations and `var` are registered **before** their use.
* Works even with catch blocks, IIFEs, and shadowing.


---

# 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/built-in-visitors/resolver.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.
