refactor(ir): move declaration maps into ProgramIndex (A1.1b)
Architecture phase A1.1b — mechanical storage relocation. Move the 9
declaration-fact maps out of the Lowering state bag into ProgramIndex:
high-fanout: fn_ast_map, foreign_class_map, global_names, type_alias_map
medium-fanout: struct_template_map, protocol_decl_map, protocol_ast_map,
module_const_map, ufcs_alias_map
168 self.<map> sites in lower.zig repointed to self.program_index.<map>;
external readers repointed too (core.zig foreign_class_map iteration;
lower.test.zig fn_ast_map / foreign_class_map). No duplicate storage, no
fallback path; zig build enforces no missed reference.
The four maps whose value types were Lowering-private pull those types into
program_index.zig as pub (GlobalInfo, StructTemplate + TemplateParam,
ProtocolDeclInfo + ProtocolMethodInfo, ModuleConstInfo); lower.zig aliases
them at file scope so call sites are unchanged.
Behavior is preserved exactly:
- per-map allocator unchanged — import_flags/fn_ast_map/global_names use the
lowering allocator (ProgramIndex.init), the other 7 keep their page_allocator
inline defaults;
- ProgramIndex.deinit frees only the 10 owned maps, never the borrowed
module_scopes / import_graph;
- TypeTable.aliases still borrows &self.program_index.type_alias_map, loaned at
lowerRoot with the same late-binding lifetime.
Extends program_index.test.zig with declaration-map round-trips (fn AST, type
alias, global, module const, foreign class, protocol decl/AST, struct template,
ufcs alias).
Registration logic (registerStructDecl / registerProtocolDecl /
registerForeignClassDecl, ...) stays in Lowering, writing through the index.
Gate green: zig build, zig build test, bash tests/run_examples.sh
(350 passed, 0 failed). lower.zig 19433 -> 19393 lines.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
const std = @import("std");
|
||||
const ProgramIndex = @import("program_index.zig").ProgramIndex;
|
||||
const pi = @import("program_index.zig");
|
||||
const ProgramIndex = pi.ProgramIndex;
|
||||
const ast = @import("../ast.zig");
|
||||
const types = @import("types.zig");
|
||||
const inst = @import("inst.zig");
|
||||
|
||||
test "ProgramIndex.init starts empty with unset borrowed views" {
|
||||
var idx = ProgramIndex.init(std.testing.allocator);
|
||||
@@ -38,3 +42,57 @@ test "ProgramIndex borrows module_scopes / import_graph without owning them" {
|
||||
try std.testing.expect(idx.import_graph.? == &graph);
|
||||
try std.testing.expectEqual(@as(u32, 0), idx.module_scopes.?.count());
|
||||
}
|
||||
|
||||
test "ProgramIndex declaration maps round-trip (A1.1b)" {
|
||||
var idx = ProgramIndex.init(std.testing.allocator);
|
||||
defer idx.deinit();
|
||||
|
||||
// Minimal AST node reused wherever a *Node is required.
|
||||
var blk = ast.Node{ .span = .{ .start = 0, .end = 0 }, .data = .{ .block = .{ .stmts = &.{} } } };
|
||||
|
||||
// fn_ast_map: function name → AST decl.
|
||||
const fd = ast.FnDecl{ .name = "main", .params = &.{}, .return_type = null, .body = &blk };
|
||||
try idx.fn_ast_map.put("main", &fd);
|
||||
try std.testing.expect(idx.fn_ast_map.get("main").? == &fd);
|
||||
|
||||
// type_alias_map: alias name → target TypeId.
|
||||
try idx.type_alias_map.put("ShaderHandle", .s64);
|
||||
try std.testing.expectEqual(@as(?types.TypeId, .s64), idx.type_alias_map.get("ShaderHandle"));
|
||||
|
||||
// global_names: #run global name → GlobalInfo.
|
||||
try idx.global_names.put("g", .{ .id = inst.GlobalId.fromIndex(0), .ty = .s64 });
|
||||
try std.testing.expect(idx.global_names.get("g").?.id == inst.GlobalId.fromIndex(0));
|
||||
|
||||
// module_const_map: const name → ModuleConstInfo.
|
||||
try idx.module_const_map.put("AF_INET", .{ .value = &blk, .ty = .s32 });
|
||||
try std.testing.expect(idx.module_const_map.get("AF_INET").?.value == &blk);
|
||||
|
||||
// foreign_class_map: sx alias → ForeignClassDecl.
|
||||
const fcd = ast.ForeignClassDecl{
|
||||
.name = "NSString",
|
||||
.foreign_path = "NSString",
|
||||
.runtime = .objc_class,
|
||||
.members = &.{},
|
||||
.is_foreign = true,
|
||||
.is_main = false,
|
||||
};
|
||||
try idx.foreign_class_map.put("NSString", &fcd);
|
||||
try std.testing.expect(idx.foreign_class_map.get("NSString").? == &fcd);
|
||||
|
||||
// protocol_decl_map: protocol name → ProtocolDeclInfo.
|
||||
try idx.protocol_decl_map.put("Show", .{ .name = "Show", .is_inline = false, .methods = &.{} });
|
||||
try std.testing.expectEqualStrings("Show", idx.protocol_decl_map.get("Show").?.name);
|
||||
|
||||
// protocol_ast_map: protocol name → AST decl.
|
||||
const pd = ast.ProtocolDecl{ .name = "Show", .methods = &.{} };
|
||||
try idx.protocol_ast_map.put("Show", &pd);
|
||||
try std.testing.expect(idx.protocol_ast_map.get("Show").? == &pd);
|
||||
|
||||
// struct_template_map: generic struct name → template.
|
||||
try idx.struct_template_map.put("List", .{ .name = "List", .type_params = &.{}, .field_names = &.{}, .field_type_nodes = &.{} });
|
||||
try std.testing.expectEqualStrings("List", idx.struct_template_map.get("List").?.name);
|
||||
|
||||
// ufcs_alias_map: alias name → target function name.
|
||||
try idx.ufcs_alias_map.put("len", "list_len");
|
||||
try std.testing.expectEqualStrings("list_len", idx.ufcs_alias_map.get("len").?);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user