Backlog/lib/sdl3/parser/docs/archive/DEPENDENCY_PLAN.md

171 lines
4.9 KiB
Markdown

# SDL3 Header Parser: Dependency Resolution Plan
## Problem Statement
The generated `gpu.zig` references types from other SDL headers:
- `FColor` (SDL_pixels.h)
- `Rect` (SDL_rect.h)
- `PropertiesID` (SDL_properties.h)
- `Window` (SDL_video.h - opaque type)
- `FlipMode` (SDL_surface.h)
- `GPUShaderFormat` (special case: #define flags)
Without these types, the generated code won't compile.
## Analysis of SDL Header Structure
SDL_gpu.h includes:
```c
#include <SDL3/SDL_stdinc.h> // Basic types (Uint32, etc.)
#include <SDL3/SDL_pixels.h> // SDL_FColor
#include <SDL3/SDL_properties.h> // SDL_PropertiesID
#include <SDL3/SDL_rect.h> // SDL_Rect
#include <SDL3/SDL_surface.h> // SDL_FlipMode
#include <SDL3/SDL_video.h> // SDL_Window (opaque)
```
## Solution Options
### Option 1: Parse Dependencies Recursively (REJECTED - Too Complex)
- Parse all included headers
- Build dependency graph
- Generate all files in correct order
- **Issues**:
- SDL has circular dependencies
- Would need to parse entire SDL API
- Overkill for our use case
### Option 2: Manual Type Imports (REJECTED - Not Maintainable)
- Manually copy type definitions
- **Issues**:
- Not automated
- Breaks on SDL updates
- Defeats purpose of parser
### Option 3: Hybrid Approach - Parse Referenced Types Only (RECOMMENDED)
#### Phase 1: Dependency Detection
1. Parse target header (e.g., SDL_gpu.h)
2. Collect all non-GPU SDL types referenced in signatures
3. Map types to their source headers (from #include directives)
#### Phase 2: Selective Type Extraction
For each dependency header, extract ONLY referenced types:
- Parse dependency header in "extract mode"
- Only output declarations that match our needed types
- Generate minimal `<module>.zig` files (e.g., `pixels.zig`, `rect.zig`)
#### Phase 3: Code Generation
Generate main file with imports:
```zig
pub const c = @import("c.zig").c;
// Import minimal dependencies
const pixels = @import("pixels.zig");
const rect = @import("rect.zig");
const properties = @import("properties.zig");
const video = @import("video.zig");
const surface = @import("surface.zig");
// Re-export needed types
pub const FColor = pixels.FColor;
pub const Rect = rect.Rect;
pub const PropertiesID = properties.PropertiesID;
pub const Window = video.Window;
pub const FlipMode = surface.FlipMode;
// Manual override for #define-based types
pub const GPUShaderFormat = packed struct(u32) {
// ... handwritten
};
// Generated GPU declarations follow...
```
## Implementation Plan
### Step 1: Add Dependency Analysis
```zig
const DependencyInfo = struct {
types_needed: []const []const u8,
source_headers: std.StringHashMap([]const u8), // type -> header
};
fn analyzeDependencies(decls: []Declaration) !DependencyInfo {
// Scan all function signatures for SDL_ types
// Map types to headers based on SDL conventions
}
```
### Step 2: Extract Types from Dependencies
```zig
fn extractTypesFromHeader(
header_path: []const u8,
types_to_extract: []const []const u8,
) ![]Declaration {
// Parse dependency header
// Filter to only needed types
// Return minimal declaration set
}
```
### Step 3: Generate Import Structure
```zig
fn generateWithDependencies(
main_decls: []Declaration,
deps: DependencyInfo,
output_dir: []const u8,
) !void {
// Generate dependency .zig files
// Generate main file with imports
}
```
### Step 4: Handle Special Cases
**Opaque Types (e.g., Window)**:
- SDL_Window is `typedef struct SDL_Window SDL_Window;` (forward decl)
- Generate as: `pub const Window = opaque {};` or `pub const Window = c.SDL_Window;`
- Decision: Use `c.SDL_Window` for true opaque types
**#define Flags (e.g., GPUShaderFormat)**:
- Cannot be auto-parsed
- Maintain "overrides" file: `overrides.zig`
- User can provide manual definitions for unparseable types
## File Structure
```
v2/
├── gpu.zig # Main generated file with imports
├── pixels.zig # Minimal: FColor only
├── rect.zig # Minimal: Rect only
├── properties.zig # Minimal: PropertiesID only
├── video.zig # Minimal: Window only
├── surface.zig # Minimal: FlipMode only
└── overrides.zig # Manual definitions (GPUShaderFormat)
```
## Advantages
1. ✅ Automated - no manual copying
2. ✅ Minimal - only extracts needed types
3. ✅ Maintainable - regenerate on SDL updates
4. ✅ Avoids circular dependencies - only extracts leaf types
5. ✅ Flexible - handles special cases via overrides
## Testing Strategy
1. Parse SDL_gpu.h → detect dependencies
2. Parse dependency headers → extract types
3. Generate all files
4. Run `zig build` to verify compilation
5. Compare API compatibility with handwritten version
## Future Enhancements
- Cache parsed headers to avoid re-parsing
- Support transitive dependencies (if type A needs type B)
- Auto-generate overrides file with placeholders
- Support multiple target headers in one run