284 lines
6.7 KiB
Markdown
284 lines
6.7 KiB
Markdown
# Dependency Resolution System
|
|
|
|
The parser automatically detects and resolves type dependencies from SDL headers.
|
|
|
|
## Overview
|
|
|
|
When parsing a header like SDL_gpu.h, functions often reference types defined in other headers (SDL_Window, SDL_Rect, etc.). The dependency resolver automatically finds and includes these types.
|
|
|
|
## How It Works
|
|
|
|
### Step 1: Detect Missing Types
|
|
|
|
After parsing the primary header, the system:
|
|
1. Scans all function signatures and struct fields
|
|
2. Extracts all referenced type names
|
|
3. Compares against types defined in the header
|
|
4. Identifies missing types
|
|
|
|
**Example**:
|
|
```c
|
|
// SDL_gpu.h
|
|
extern void SDL_ClaimWindow(SDL_GPUDevice *device, SDL_Window *window);
|
|
```
|
|
|
|
- `SDL_GPUDevice` is defined in SDL_gpu.h ✓
|
|
- `SDL_Window` is NOT defined in SDL_gpu.h ✗
|
|
|
|
**Result**: SDL_Window added to missing types list
|
|
|
|
### Step 2: Parse Include Directives
|
|
|
|
Extracts `#include` directives from the header:
|
|
```c
|
|
#include <SDL3/SDL_stdinc.h>
|
|
#include <SDL3/SDL_video.h>
|
|
#include <SDL3/SDL_rect.h>
|
|
```
|
|
|
|
**Result**: List of headers to search: [`SDL_stdinc.h`, `SDL_video.h`, `SDL_rect.h`]
|
|
|
|
### Step 3: Search for Missing Types
|
|
|
|
For each missing type:
|
|
1. Try each included header in order
|
|
2. Parse the header completely
|
|
3. Search for matching type definition
|
|
4. If found, clone the declaration and stop searching
|
|
5. If not found, continue to next header
|
|
|
|
**Example Search for SDL_Window**:
|
|
```
|
|
Try SDL_stdinc.h → Not found
|
|
Try SDL_video.h → Found! ✓
|
|
└─ Extract SDL_Window definition
|
|
└─ Stop searching
|
|
```
|
|
|
|
### Step 4: Combine Declarations
|
|
|
|
```zig
|
|
final_declarations = [
|
|
// Dependencies FIRST (so types are defined before use)
|
|
SDL_Window,
|
|
SDL_Rect,
|
|
SDL_FColor,
|
|
|
|
// Primary declarations
|
|
SDL_GPUDevice,
|
|
SDL_GPUTexture,
|
|
...
|
|
]
|
|
```
|
|
|
|
### Step 5: Generate Unified Output
|
|
|
|
```zig
|
|
pub const c = @import("c.zig").c;
|
|
|
|
// Dependencies (automatically included)
|
|
pub const Window = opaque {};
|
|
pub const Rect = extern struct { x: c_int, y: c_int, w: c_int, h: c_int };
|
|
|
|
// Primary declarations
|
|
pub const GPUDevice = opaque {
|
|
pub fn claimWindow(device: *GPUDevice, window: ?*Window) bool {
|
|
return c.SDL_ClaimWindowForGPUDevice(device, window);
|
|
}
|
|
};
|
|
```
|
|
|
|
## Type Extraction Details
|
|
|
|
### Type String Normalization
|
|
|
|
C type strings often have pointer and const decorators that need to be stripped:
|
|
|
|
```
|
|
"SDL_Window *" → "SDL_Window"
|
|
"?*SDL_GPUDevice" → "SDL_GPUDevice"
|
|
"*const SDL_Rect" → "SDL_Rect"
|
|
"SDL_Buffer *const *" → "SDL_Buffer"
|
|
"[*c]const u8" → "u8"
|
|
```
|
|
|
|
**Algorithm**:
|
|
1. Remove leading: `const`, `struct`, `?`, `*`
|
|
2. Handle C arrays: `[*c]T` → `T`
|
|
3. Remove trailing: `*`, `*const`, ` const`
|
|
4. Repeat until no changes
|
|
|
|
### SDL Type Detection
|
|
|
|
A type is considered "SDL" if:
|
|
- Name starts with `SDL_` prefix, OR
|
|
- Name is in known SDL types list (Window, Rect, etc.)
|
|
|
|
Non-SDL types (primitives) are ignored:
|
|
- `bool`, `int`, `float`, `void`, etc.
|
|
|
|
### Declaration Cloning
|
|
|
|
When extracting types from dependency headers, we must clone them because:
|
|
1. The temporary scanner will be freed
|
|
2. Original strings will be deallocated
|
|
3. We need owned copies with stable lifetime
|
|
|
|
**Cloning Process**:
|
|
```zig
|
|
fn cloneDeclaration(allocator: Allocator, decl: Declaration) !Declaration {
|
|
return switch (decl) {
|
|
.struct_decl => |s| .{
|
|
.struct_decl = .{
|
|
.name = try allocator.dupe(u8, s.name),
|
|
.fields = try cloneFields(allocator, s.fields),
|
|
.doc_comment = if (s.doc_comment) |doc|
|
|
try allocator.dupe(u8, doc) else null,
|
|
},
|
|
},
|
|
// ... similar for other types
|
|
};
|
|
}
|
|
```
|
|
|
|
All strings are duplicated so the cloned declaration owns them.
|
|
|
|
## Success Metrics
|
|
|
|
### SDL_gpu.h Results
|
|
|
|
**Missing Types Detected**: 5
|
|
1. SDL_FColor
|
|
2. SDL_PropertiesID
|
|
3. SDL_Rect
|
|
4. SDL_Window
|
|
5. SDL_FlipMode
|
|
|
|
**Resolution Results**: 5/5 (100%) ✅
|
|
|
|
**Where Found**:
|
|
- SDL_FColor → SDL_pixels.h (struct)
|
|
- SDL_PropertiesID → SDL_properties.h (typedef)
|
|
- SDL_Rect → SDL_rect.h (struct)
|
|
- SDL_Window → SDL_video.h (opaque)
|
|
- SDL_FlipMode → SDL_surface.h (enum)
|
|
|
|
## Configuration
|
|
|
|
### Behavior
|
|
|
|
The dependency resolver is **always enabled** - no configuration needed.
|
|
|
|
When missing types are detected, it automatically:
|
|
- ✅ Searches included headers
|
|
- ✅ Extracts matching types
|
|
- ✅ Combines into output
|
|
- ✅ Reports progress
|
|
|
|
### Error Handling
|
|
|
|
**Warnings** (non-fatal):
|
|
- Type not found in any header
|
|
- Dependency header not readable
|
|
- Parsing errors in dependency
|
|
|
|
**Result**: Partial output with warnings
|
|
|
|
## Performance
|
|
|
|
### Timing Breakdown (SDL_gpu.h)
|
|
|
|
| Phase | Time | Notes |
|
|
|-------|------|-------|
|
|
| Primary parsing | 50ms | Parse SDL_gpu.h |
|
|
| Dependency analysis | 10ms | Build HashMaps |
|
|
| Include parsing | 1ms | Extract #includes |
|
|
| Type extraction | 300ms | Parse 5 dependency headers |
|
|
| Code generation | 150ms | Generate + validate |
|
|
| **Total** | **~520ms** | Acceptable |
|
|
|
|
### Optimization
|
|
|
|
**Current**:
|
|
- Selective parsing (only types needed)
|
|
- Early exit (stop when found)
|
|
- HashMap deduplication
|
|
|
|
**Future**:
|
|
- Cache parsed headers
|
|
- Parallel header parsing
|
|
- Header dependency graph
|
|
|
|
## Limitations
|
|
|
|
### Not Resolved
|
|
|
|
1. **Function pointer typedefs** - Not yet supported
|
|
```c
|
|
typedef void (*SDL_Callback)(void *userdata);
|
|
```
|
|
|
|
2. **#define-based types** - Requires preprocessor
|
|
```c
|
|
#define SDL_VALUE (1u << 0)
|
|
typedef Uint32 SDL_Type; // Not found by scanner
|
|
```
|
|
|
|
3. **External library types** - Expected
|
|
```c
|
|
SDL_EGLConfig // From EGL, not SDL
|
|
```
|
|
|
|
### Workarounds
|
|
|
|
**Manual Definitions**: Add missing types to a separate file
|
|
```zig
|
|
// manual_types.zig
|
|
pub const Callback = *const fn(?*anyopaque) void;
|
|
```
|
|
|
|
**Preprocessor**: Use clang to preprocess before parsing
|
|
```bash
|
|
clang -E -I/path/to/SDL3 header.h | zig build run --
|
|
```
|
|
|
|
## Debugging
|
|
|
|
### Enable Verbose Output
|
|
|
|
The parser already prints detailed progress:
|
|
```
|
|
Analyzing dependencies...
|
|
Found 5 missing types:
|
|
- SDL_FColor
|
|
- SDL_Rect
|
|
...
|
|
|
|
Resolving dependencies from included headers...
|
|
✓ Found SDL_FColor in SDL_pixels.h
|
|
✓ Found SDL_Rect in SDL_rect.h
|
|
⚠ Warning: Could not find definition for type: SDL_Unknown
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
**"Could not find definition for type"**
|
|
- Type might be typedef (check if recently added)
|
|
- Type might be in different include
|
|
- Type might be external (EGL, GL, etc.)
|
|
|
|
**"Syntax errors in generated code"**
|
|
- Check generated file line numbers
|
|
- Usually struct/enum parsing issues
|
|
- See [Known Issues](KNOWN_ISSUES.md)
|
|
|
|
## Technical Details
|
|
|
|
For implementation details, see:
|
|
- [Technical Flow](DEPENDENCY_FLOW.md) - Step-by-step walkthrough
|
|
- [Visual Guide](VISUAL_FLOW.md) - Diagrams and quick reference
|
|
|
|
---
|
|
|
|
**Next**: See [API Reference](API_REFERENCE.md) for command-line options.
|