# GDScript Parser — Usage Guide

## Quick Start

```python
from godotiq.parsers.gd_parser import parse_gd

# Parse a .gd file
result = parse_gd("path/to/script.gd")

# With autoload detection
result = parse_gd(
    "path/to/script.gd",
    known_autoloads=["EconomyManager", "ResearchManager"]
)
```

## API Reference

### `parse_gd(path: str, known_autoloads: list[str] | None = None) -> GdScript`

Parses a `.gd` file into a structured representation.

- **path**: Absolute or relative path to a `.gd` file
- **known_autoloads**: Optional list of autoload singleton names for direct-pattern detection
- **Returns**: `GdScript` dataclass
- **Raises**: `FileNotFoundError` if file doesn't exist

### GdScript Container

```python
@dataclass
class GdScript:
    class_name: str          # e.g., "EconomyManagerClass"
    extends: str             # e.g., "Node"
    signals: list[GdSignal]
    functions: list[GdFunction]
    variables: list[GdVariable]
    enums: list[GdEnum]
    inner_classes: list[str]
    signal_connections: list[GdSignalConnection]
    signal_emissions: list[GdSignalEmission]
    autoload_refs: list[GdAutoloadRef]
    preload_refs: list[GdPreloadRef]
    is_instance_valid_lines: list[int]
```

### Dataclasses

| Class | Key Fields |
|-------|-----------|
| `GdSignal` | `name`, `args: list[(name, type)]`, `line` |
| `GdFunction` | `name`, `args: list[(name, type, default)]`, `return_type`, `is_static`, `is_virtual`, `line`, `end_line` |
| `GdVariable` | `name`, `type_hint`, `default_value`, `is_const`, `is_static`, `annotation`, `scope` |
| `GdEnum` | `name`, `values: dict[str, int|None]` |
| `GdSignalConnection` | `signal_source`, `target`, `has_bind`, `bind_args` |
| `GdSignalEmission` | `signal_name`, `arg_count` |
| `GdAutoloadRef` | `autoload_name`, `access`, `pattern` (direct/has_node/get_node/get_node_or_null) |
| `GdPreloadRef` | `path`, `is_preload` |

## Example Output

```python
from godotiq.parsers.gd_parser import parse_gd

r = parse_gd("economy_manager.gd")
print(r.class_name)     # "EconomyManagerClass"
print(r.extends)         # "Node"
print(len(r.signals))    # 3
print(r.signals[0].name) # "cash_changed"
print(r.signals[0].args) # [("new_amount", "float"), ("delta", "float")]
print(len(r.functions))  # 8
print(len(r.variables))  # 5

# Signal emissions tracked
for em in r.signal_emissions:
    print(f"{em.signal_name}.emit() with {em.arg_count} args on line {em.line}")

# Autoload references (with known_autoloads)
r = parse_gd("game_manager.gd", known_autoloads=["EconomyManager"])
for ref in r.autoload_refs:
    print(f"{ref.autoload_name}.{ref.access} ({ref.pattern}) on line {ref.line}")
```

## Internal API

For unit testing, use `_parse_gd_content()` directly with inline strings:

```python
from godotiq.parsers.gd_parser import _parse_gd_content

result = _parse_gd_content("extends Node\nsignal foo\n")
assert result.signals[0].name == "foo"
```
