diff --git a/src/Compilation.zig b/src/Compilation.zig index 623635a6b0..71d91b8d2a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -8,6 +8,7 @@ const log = std.log.scoped(.compilation); const Target = std.Target; const Value = @import("value.zig").Value; +const Type = @import("type.zig").Type; const target_util = @import("target.zig"); const Package = @import("Package.zig"); const link = @import("link.zig"); @@ -638,15 +639,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const root_scope = rs: { if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) { + const struct_payload = try gpa.create(Type.Payload.EmptyStruct); const root_scope = try gpa.create(Module.Scope.File); + struct_payload.* = .{ .scope = &root_scope.root_container }; root_scope.* = .{ - .sub_file_path = root_pkg.root_src_path, + // TODO this is duped so it can be freed in Container.deinit + .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path), .source = .{ .unloaded = {} }, .contents = .{ .not_available = {} }, .status = .never_loaded, .root_container = .{ .file_scope = root_scope, .decls = .{}, + .ty = Type.initPayload(&struct_payload.base), }, }; break :rs &root_scope.base; @@ -1022,6 +1027,17 @@ pub fn update(self: *Compilation) !void { else => |e| return e, }; } + + // TODO only analyze imports if they are still referenced + for (module.import_table.items()) |entry| { + entry.value.unload(module.gpa); + module.analyzeContainer(&entry.value.root_container) catch |err| switch (err) { + error.AnalysisFail => { + assert(self.totalErrorCount() != 0); + }, + else => |e| return e, + }; + } } } diff --git a/src/Module.zig b/src/Module.zig index 46628de651..75b6afffcd 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -70,14 +70,14 @@ deletion_set: ArrayListUnmanaged(*Decl) = .{}, /// Error tags and their values, tag names are duped with mod.gpa. global_error_set: std.StringHashMapUnmanaged(u16) = .{}, +/// Keys are fully qualified paths +import_table: std.StringArrayHashMapUnmanaged(*Scope.File) = .{}, + /// Incrementing integer used to compare against the corresponding Decl /// field to determine whether a Decl's status applies to an ongoing update, or a /// previous analysis. generation: u32 = 0, -/// Keys are fully qualified paths -import_table: std.StringArrayHashMapUnmanaged(*Scope.File) = .{}, - stage1_flags: packed struct { have_winmain: bool = false, have_wwinmain: bool = false, @@ -2392,10 +2392,7 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst, pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File { // TODO if (package_table.get(target_string)) |pkg| - - const file_path = try std.fs.path.join(scope.arena(), &[_][]const u8{ self.root_pkg.root_src_dir_path, target_string }); - - if (self.import_table.get(file_path)) |some| { + if (self.import_table.get(target_string)) |some| { return some; } @@ -2404,10 +2401,15 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: [] // TODO Scope.Container arena for ty and sub_file_path const struct_payload = try self.gpa.create(Type.Payload.EmptyStruct); + errdefer self.gpa.destroy(struct_payload); const file_scope = try self.gpa.create(Scope.File); + errdefer self.gpa.destroy(file_scope); + const file_path = try self.gpa.dupe(u8, target_string); + errdefer self.gpa.free(file_path); + struct_payload.* = .{ .scope = &file_scope.root_container }; file_scope.* = .{ - .sub_file_path = try self.gpa.dupe(u8, file_path), + .sub_file_path = file_path, .source = .{ .unloaded = {} }, .contents = .{ .not_available = {} }, .status = .never_loaded, @@ -2419,7 +2421,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: [] }; self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) { error.AnalysisFail => { - assert(self.totalErrorCount() != 0); + assert(self.comp.totalErrorCount() != 0); }, else => |e| return e, }; diff --git a/src/main.zig b/src/main.zig index d421322c17..5b83bac9ca 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1446,6 +1446,11 @@ fn buildOutputType( cleanup_root_dir = dir; root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; root_pkg_memory.root_src_path = try fs.path.relative(arena, p, src_path); + } else if (fs.path.dirname(src_path)) |p| { + const dir = try fs.cwd().openDir(p, .{}); + cleanup_root_dir = dir; + root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; + root_pkg_memory.root_src_path = fs.path.basename(src_path); } else { root_pkg_memory.root_src_directory = .{ .path = null, .handle = fs.cwd() }; root_pkg_memory.root_src_path = src_path;