From 21644ef7f03af96be842b5f152b7217c2abe31cc Mon Sep 17 00:00:00 2001 From: ktkk Date: Sun, 5 Jul 2026 13:58:11 +0200 Subject: [PATCH] Add module attribute --- src/Class/AttributeInfo.zig | 178 +++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 1 deletion(-) diff --git a/src/Class/AttributeInfo.zig b/src/Class/AttributeInfo.zig index df0dc1a..1b4c6af 100644 --- a/src/Class/AttributeInfo.zig +++ b/src/Class/AttributeInfo.zig @@ -33,7 +33,7 @@ pub const AttributeInfo = union(enum) { annotation_default: AnnotationDefault, bootstrap_methods: BootstrapMethods, method_parameters: MethodParameters, - // module: Module, + module: Module, module_packages: ModulePackages, module_main_class: ModuleMainClass, nest_host: NestHost, @@ -183,6 +183,12 @@ pub const AttributeInfo = union(enum) { .method_parameters = try MethodParameters.parse(limited, allocator), }, }; + } else if (std.mem.eql(u8, attribute_name.bytes, "Module")) { + return .{ + .predefined = .{ + .module = try Module.parse(limited, allocator), + }, + }; } else if (std.mem.eql(u8, attribute_name.bytes, "ModulePackages")) { return .{ .predefined = .{ @@ -245,6 +251,7 @@ pub const AttributeInfo = union(enum) { .annotation_default => |*annotation_default| annotation_default.deinit(allocator), .bootstrap_methods => |*bootstrap_methods| bootstrap_methods.deinit(allocator), .method_parameters => |*method_parameters| method_parameters.deinit(allocator), + .module => |*module| module.deinit(allocator), .module_packages => |*module_packages| module_packages.deinit(allocator), .nest_members => |*nest_members| nest_members.deinit(allocator), .record => |*record| record.deinit(allocator), @@ -1524,6 +1531,175 @@ pub const MethodParameters = struct { } }; +pub const Module = struct { + module_name_index: u16, + module_flags: ModuleFlags, + module_version_index: u16, + requires: []Requires, + exports: []Exports, + opens: []Opens, + uses_indeces: []u16, + provides: []Provides, + + const Self = @This(); + + pub const ModuleFlags = EnumFlags(enum(u16) { + open = 0x0020, + sythetic = 0x1000, + mandated = 0x8000, + }); + + pub const Requires = struct { + requires_index: u16, + requires_flags: RequiresFlags, + requires_version_index: u16, + + pub const RequiresFlags = EnumFlags(enum(u16) { + transitive = 0x0020, + static_phase = 0x0040, + synthetic = 0x1000, + mandated = 0x8000, + }); + }; + + pub const Exports = struct { + exports_index: u16, + exports_flags: ExportsFlags, + exports_to_indeces: []u16, + + pub const ExportsFlags = EnumFlags(enum(u16) { + synthetic = 0x1000, + mandated = 0x8000, + }); + }; + + pub const Opens = struct { + opens_index: u16, + opens_flags: OpensFlags, + opens_to_indeces: []u16, + + pub const OpensFlags = EnumFlags(enum(u16) { + synthetic = 0x1000, + mandated = 0x8000, + }); + }; + + pub const Provides = struct { + provides_index: u16, + provides_with_indeces: []u16, + }; + + pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self { + const module_name_index = try input.takeInt(u16, .big); + const module_flags: ModuleFlags = .{ .mask = try input.takeInt(u16, .big) }; + const module_version_index = try input.takeInt(u16, .big); + + const requires_count = try input.takeInt(u16, .big); + const requires = try allocator.alloc(Requires, requires_count); + errdefer allocator.free(requires); + for (requires) |*r| { + const requires_index = try input.takeInt(u16, .big); + const requires_flags: Requires.RequiresFlags = .{ .mask = try input.takeInt(u16, .big) }; + const requires_version_index = try input.takeInt(u16, .big); + r.* = .{ + .requires_index = requires_index, + .requires_flags = requires_flags, + .requires_version_index = requires_version_index, + }; + } + + const exports_count = try input.takeInt(u16, .big); + const exports = try allocator.alloc(Exports, exports_count); + errdefer allocator.free(exports); + for (exports) |*e| { + const exports_index = try input.takeInt(u16, .big); + const exports_flags: Exports.ExportsFlags = .{ .mask = try input.takeInt(u16, .big) }; + const exports_to_count = try input.takeInt(u16, .big); + const exports_to_indeces = try allocator.alloc(u16, exports_to_count); + errdefer allocator.free(exports_to_indeces); + for (exports_to_indeces) |*i| { + i.* = try input.takeInt(u16, .big); + } + e.* = .{ + .exports_index = exports_index, + .exports_flags = exports_flags, + .exports_to_indeces = exports_to_indeces, + }; + } + + const opens_count = try input.takeInt(u16, .big); + const opens = try allocator.alloc(Opens, opens_count); + errdefer allocator.free(opens); + for (opens) |*o| { + const opens_index = try input.takeInt(u16, .big); + const opens_flags: Opens.OpensFlags = .{ .mask = try input.takeInt(u16, .big) }; + const opens_to_count = try input.takeInt(u16, .big); + const opens_to_indeces = try allocator.alloc(u16, opens_to_count); + errdefer allocator.free(opens_to_indeces); + for (opens_to_indeces) |*i| { + i.* = try input.takeInt(u16, .big); + } + o.* = .{ + .opens_index = opens_index, + .opens_flags = opens_flags, + .opens_to_indeces = opens_to_indeces, + }; + } + + const uses_count = try input.takeInt(u16, .big); + const uses_indeces = try allocator.alloc(u16, uses_count); + errdefer allocator.free(uses_indeces); + for (uses_indeces) |*i| { + i.* = try input.takeInt(u16, .big); + } + + const provides_count = try input.takeInt(u16, .big); + const provides = try allocator.alloc(Provides, provides_count); + errdefer allocator.free(provides); + for (provides) |*p| { + const provides_index = try input.takeInt(u16, .big); + const provides_with_count = try input.takeInt(u16, .big); + const provides_with_indeces = try allocator.alloc(u16, provides_with_count); + errdefer allocator.free(provides_with_indeces); + for (provides_with_indeces) |*i| { + i.* = try input.takeInt(u16, .big); + } + p.* = .{ + .provides_index = provides_index, + .provides_with_indeces = provides_with_indeces, + }; + } + + return .{ + .module_name_index = module_name_index, + .module_flags = module_flags, + .module_version_index = module_version_index, + .requires = requires, + .exports = exports, + .opens = opens, + .uses_indeces = uses_indeces, + .provides = provides, + }; + } + + pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { + allocator.free(self.requires); + for (self.exports) |*e| { + allocator.free(e.exports_to_indeces); + } + allocator.free(self.exports); + for (self.opens) |*o| { + allocator.free(o.opens_to_indeces); + } + allocator.free(self.opens); + allocator.free(self.uses_indeces); + for (self.provides) |*p| { + allocator.free(p.provides_with_indeces); + } + allocator.free(self.provides); + } +}; + pub const ModulePackages = struct { package_indeces: []u16,