Add additional predefined attribute infos
This commit is contained in:
parent
75d023cfe1
commit
9af766e495
3 changed files with 317 additions and 12 deletions
|
|
@ -675,7 +675,13 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn indentedFormat(self: *const ConstantPoolInfo, w: *std.Io.Writer, depth: usize, indent: u8, constant_pool: []const ?ConstantPoolInfo) std.Io.Writer.Error!void {
|
||||
pub fn indentedFormat(
|
||||
self: *const ConstantPoolInfo,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
constant_pool: []const ?ConstantPoolInfo,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("constant_value_type: {s}\n", .{ @tagName(self.*) });
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,18 @@ pub const AttributeInfo = union(enum) {
|
|||
runtime_invisible_annotations: RuntimeInvisibleAnnotations,
|
||||
runtime_visible_parameter_annotations: RuntimeVisibleParameterAnnotations,
|
||||
runtime_invisible_parameter_annotations: RuntimeInvisibleParameterAnnotations,
|
||||
// runtime_visible_type_annotations: RuntimeVisibleTypeAnnotations,
|
||||
// runtime_invisible_type_annotations: RuntimeInvisibleTypeAnnotations,
|
||||
annotation_default: AnnotationDefault,
|
||||
bootstrap_methods: BootstrapMethods,
|
||||
method_parameters: MethodParameters,
|
||||
// module: Module,
|
||||
module_packages: ModulePackages,
|
||||
module_main_class: ModuleMainClass,
|
||||
nest_host: NestHost,
|
||||
nest_members: NestMembers,
|
||||
record: Record,
|
||||
permitted_subclasses: PermittedSubclasses,
|
||||
},
|
||||
|
||||
const Self = @This();
|
||||
|
|
@ -167,6 +177,48 @@ pub const AttributeInfo = union(enum) {
|
|||
.bootstrap_methods = try BootstrapMethods.parse(limited, allocator),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "MethodParameters")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.method_parameters = try MethodParameters.parse(limited, allocator),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "ModulePackages")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.module_packages = try ModulePackages.parse(limited, allocator),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "ModuleMainClass")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.module_main_class = try ModuleMainClass.parse(limited),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "NestHost")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.nest_host = try NestHost.parse(limited),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "NestMembers")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.nest_members = try NestMembers.parse(limited, allocator),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "Record")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.record = try Record.parse(limited, constant_pool, allocator),
|
||||
},
|
||||
};
|
||||
} else if (std.mem.eql(u8, attribute_name.bytes, "PermittedSubclasses")) {
|
||||
return .{
|
||||
.predefined = .{
|
||||
.permitted_subclasses = try PermittedSubclasses.parse(limited, allocator),
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return .{
|
||||
.new = try NewAttribute.parse(limited, attribute_name_index + 1, attribute_length, allocator),
|
||||
|
|
@ -192,6 +244,11 @@ pub const AttributeInfo = union(enum) {
|
|||
.runtime_invisible_parameter_annotations => |*runtime_invisible_parameter_annotations| runtime_invisible_parameter_annotations.deinit(allocator),
|
||||
.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_packages => |*module_packages| module_packages.deinit(allocator),
|
||||
.nest_members => |*nest_members| nest_members.deinit(allocator),
|
||||
.record => |*record| record.deinit(allocator),
|
||||
.permitted_subclasses => |*permitted_subclasses| permitted_subclasses.deinit(allocator),
|
||||
else => {},
|
||||
},
|
||||
}
|
||||
|
|
@ -318,10 +375,14 @@ pub const AttributeInfo = union(enum) {
|
|||
.synthetic => {},
|
||||
.signature => |attr| {
|
||||
const signature = attr.signature(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("signature:\n");
|
||||
try signature.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.source_file => |attr| {
|
||||
const source_file = attr.sourceFile(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("source_file:\n");
|
||||
try source_file.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
//.source_debug_extension,
|
||||
|
|
@ -335,6 +396,14 @@ pub const AttributeInfo = union(enum) {
|
|||
//.runtime_invisible_parameter_annotations,
|
||||
//.annotation_default,
|
||||
//.bootstrap_methods,
|
||||
//.method_parameters,
|
||||
//.module,
|
||||
//.module_packages,
|
||||
//.module_main_class,
|
||||
//.nest_host,
|
||||
//.nest_members,
|
||||
//.record,
|
||||
//.permitted_subclasses,
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
|
|
@ -970,18 +1039,18 @@ pub const Deprecated = struct { };
|
|||
|
||||
pub const ElementValue = union(enum) {
|
||||
// B, C, D, F, I, J, S, Z, s
|
||||
const_value_index: u16,
|
||||
const_value_index: u16,
|
||||
// e
|
||||
enum_const_value: struct {
|
||||
enum_const_value: struct {
|
||||
type_name_index: u16,
|
||||
const_name_index: u16,
|
||||
},
|
||||
// c
|
||||
class_info_index: u16,
|
||||
class_info_index: u16,
|
||||
// @
|
||||
annotation_value: Annotation,
|
||||
annotation_value: Annotation,
|
||||
// [
|
||||
array_value: struct {
|
||||
array_value: struct {
|
||||
values: []ElementValue,
|
||||
},
|
||||
|
||||
|
|
@ -1035,15 +1104,15 @@ pub const ElementValue = union(enum) {
|
|||
}
|
||||
};
|
||||
|
||||
pub const ElementValuePair = struct {
|
||||
element_name_index: u16,
|
||||
value: ElementValue,
|
||||
};
|
||||
|
||||
pub const Annotation = struct {
|
||||
type_index: u16,
|
||||
element_value_pairs: []ElementValuePair,
|
||||
|
||||
pub const ElementValuePair = struct {
|
||||
element_name_index: u16,
|
||||
value: ElementValue,
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Annotation {
|
||||
const type_index = try input.takeInt(u16, .big);
|
||||
|
||||
|
|
@ -1203,6 +1272,51 @@ pub const RuntimeInvisibleParameterAnnotations = struct {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: TypeAnnotation structure
|
||||
// pub const TypeAnnotation = struct {
|
||||
// target_info: union(TargetType) {
|
||||
// type_parameter_target: TypeParameterTarget,
|
||||
// supertype_target: SupertypeTarget,
|
||||
// type_parameter_bound_target: TypeParameterBoundTarget,
|
||||
// emtpy_target: EmptyTarget,
|
||||
// formal_parameter_target: FormalParameterTarget,
|
||||
// throws_target: ThrowsTarget,
|
||||
// localvar_target: LocalvarTarget,
|
||||
// catch_target: CatchTarget,
|
||||
// offset_target: OffsetTarget,
|
||||
// type_argument_target: TypeArgumentTarget,
|
||||
// },
|
||||
// target_path: TypePath,
|
||||
// type_index: u16,
|
||||
// element_value_pairs: []ElementValuePair,
|
||||
//
|
||||
// pub const TargetType = enum(u8) {
|
||||
// type_parameter_target = 0x00,
|
||||
// type
|
||||
// };
|
||||
//
|
||||
// pub const TypePath = struct {
|
||||
// path: []Path,
|
||||
//
|
||||
// pub const Path = struct {
|
||||
// type_path_kind: u8,
|
||||
// type_argument_index: u8,
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
|
||||
// pub const RuntimeVisibleTypeAnnotations = struct {
|
||||
// type_annotations: []TypeAnnotation,
|
||||
//
|
||||
// const Self = @This();
|
||||
// };
|
||||
//
|
||||
// pub const RuntimeInvisibleTypeAnnotations = struct {
|
||||
// type_annotations: []TypeAnnotation,
|
||||
//
|
||||
// const Self = @This();
|
||||
// };
|
||||
|
||||
pub const AnnotationDefault = struct {
|
||||
default_value: ElementValue,
|
||||
|
||||
|
|
@ -1261,3 +1375,189 @@ pub const BootstrapMethods = struct {
|
|||
allocator.free(self.bootstrap_methods);
|
||||
}
|
||||
};
|
||||
|
||||
pub const MethodParameters = struct {
|
||||
parameters: []Parameter,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub const Parameter = struct {
|
||||
name_index: u16,
|
||||
access_flags: ParameterAccessFlags,
|
||||
|
||||
pub const ParameterFlags = enum(u16) {
|
||||
final = 0x0010,
|
||||
synthetic = 0x1000,
|
||||
mandated = 0x8000,
|
||||
};
|
||||
|
||||
pub const ParameterAccessFlags = EnumFlags(ParameterFlags);
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
const parameter_count = try input.takeByte();
|
||||
const parameters = try allocator.alloc(Parameter, parameter_count);
|
||||
errdefer allocator.free(parameters);
|
||||
for (parameters) |*parameter| {
|
||||
parameter.* = .{
|
||||
.name_index = try input.takeInt(u16, .big),
|
||||
.access_flags = .{ .mask = try input.takeInt(u16, .big) },
|
||||
};
|
||||
}
|
||||
|
||||
return .{
|
||||
.parameters = parameters,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.parameters);
|
||||
}
|
||||
};
|
||||
|
||||
pub const ModulePackages = struct {
|
||||
package_indeces: []u16,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
const package_count = try input.takeInt(u16, .big);
|
||||
const package_indeces = try allocator.alloc(u16, package_count);
|
||||
errdefer allocator.free(package_indeces);
|
||||
for (package_indeces) |*package_index| {
|
||||
package_index.* = try input.takeInt(u16, .big);
|
||||
}
|
||||
|
||||
return .{
|
||||
.package_indeces = package_indeces,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.package_indeces);
|
||||
}
|
||||
};
|
||||
|
||||
pub const ModuleMainClass = struct {
|
||||
main_class_index: u16,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn parse(input: *std.Io.Reader) ParseError!Self {
|
||||
return .{
|
||||
.main_class_index = try input.takeInt(u16, .big),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const NestHost = struct {
|
||||
host_class_index: u16,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn parse(input: *std.Io.Reader) ParseError!Self {
|
||||
return .{
|
||||
.host_class_index = try input.takeInt(u16, .big),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const NestMembers = struct {
|
||||
classes: []u16,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
const number_of_classes = try input.takeInt(u16, .big);
|
||||
const classes = try allocator.alloc(u16, number_of_classes);
|
||||
for (classes) |*class| {
|
||||
class.* = try input.takeInt(u16, .big);
|
||||
}
|
||||
|
||||
return .{
|
||||
.classes = classes,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.classes);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Record = struct {
|
||||
components: []RecordComponentInfo,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub const RecordComponentInfo = struct {
|
||||
name_index: u16,
|
||||
descriptor_index: u16,
|
||||
attributes: []AttributeInfo,
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!RecordComponentInfo {
|
||||
const name_index = try input.takeInt(u16, .big);
|
||||
const descriptor_index = try input.takeInt(u16, .big);
|
||||
|
||||
const attribute_count = try input.takeInt(u16, .big);
|
||||
const attributes = try allocator.alloc(AttributeInfo, attribute_count);
|
||||
errdefer allocator.free(attributes);
|
||||
for (attributes) |*attribute| {
|
||||
attribute.* = try .parse(input, constant_pool, allocator);
|
||||
}
|
||||
|
||||
return .{
|
||||
.name_index = name_index,
|
||||
.descriptor_index = descriptor_index,
|
||||
.attributes = attributes,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *RecordComponentInfo, allocator: std.mem.Allocator) void {
|
||||
for (self.attributes) |*attribute| {
|
||||
attribute.deinit(allocator);
|
||||
}
|
||||
allocator.free(self.attributes);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
||||
const components_count = try input.takeInt(u16, .big);
|
||||
const components = try allocator.alloc(RecordComponentInfo, components_count);
|
||||
for (components) |*component| {
|
||||
component.* = try .parse(input, constant_pool, allocator);
|
||||
}
|
||||
|
||||
return .{
|
||||
.components = components,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||
for (self.components) |*component| {
|
||||
component.deinit(allocator);
|
||||
}
|
||||
allocator.free(self.components);
|
||||
}
|
||||
};
|
||||
|
||||
pub const PermittedSubclasses = struct {
|
||||
classes: []u16,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
const number_of_classes = try input.takeInt(u16, .big);
|
||||
const classes = try allocator.alloc(u16, number_of_classes);
|
||||
for (classes) |*class| {
|
||||
class.* = try input.takeInt(u16, .big);
|
||||
}
|
||||
|
||||
return .{
|
||||
.classes = classes,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.classes);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,4 +66,3 @@ pub fn main(init: std.process.Init) !void {
|
|||
|
||||
try stdout.flush();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue