Add module attribute

This commit is contained in:
ktkk 2026-07-05 13:58:11 +02:00
parent 7cc907dc19
commit 21644ef7f0

View file

@ -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,