Format additional predefined attribute infos
This commit is contained in:
parent
9af766e495
commit
f8b1f968e0
4 changed files with 273 additions and 19 deletions
|
|
@ -274,7 +274,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try field.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
|
||||
try field.indentedFormat(w, depth, indent + 1, self.constant_pool);
|
||||
}
|
||||
|
||||
_ = try w.write("methods:\n");
|
||||
|
|
@ -284,7 +284,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try method.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
|
||||
try method.indentedFormat(w, depth, indent + 1, self.constant_pool);
|
||||
}
|
||||
|
||||
_ = try w.write("attributes:\n");
|
||||
|
|
@ -294,7 +294,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try attribute.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
|
||||
try attribute.indentedFormat(w, depth, indent + 1, self.constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +342,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
utf8: Utf8,
|
||||
method_handle: MethodHandle,
|
||||
method_type: MethodType,
|
||||
dynamic: Dynamic,
|
||||
invoke_dynamic: InvokeDynamic,
|
||||
module: Module,
|
||||
package: Package,
|
||||
|
||||
pub const Tag = enum(u8) {
|
||||
class = 7,
|
||||
|
|
@ -358,7 +361,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
utf8 = 1,
|
||||
method_handle = 15,
|
||||
method_type = 16,
|
||||
dynamic = 17,
|
||||
invoke_dynamic = 18,
|
||||
module = 19,
|
||||
package = 20,
|
||||
};
|
||||
|
||||
pub const Class = struct {
|
||||
|
|
@ -540,6 +546,19 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
}
|
||||
};
|
||||
|
||||
pub const Dynamic = struct {
|
||||
bootstrap_method_attr_index: u16,
|
||||
name_and_type_index: u16,
|
||||
|
||||
pub fn nameAndType(self: *const Dynamic, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const name_and_type_index = self.name_and_type_index - 1;
|
||||
if (name_and_type_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[name_and_type_index];
|
||||
if (cp_info == null or @as(Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub const InvokeDynamic = struct {
|
||||
bootstrap_method_attr_index: u16,
|
||||
name_and_type_index: u16,
|
||||
|
|
@ -553,6 +572,30 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
}
|
||||
};
|
||||
|
||||
pub const Module = struct {
|
||||
name_index: u16,
|
||||
|
||||
pub fn name(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const name_index = self.name_index - 1;
|
||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[name_index];
|
||||
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Package = struct {
|
||||
name_index: u16,
|
||||
|
||||
pub fn name(self: *const Package, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const name_index = self.name_index - 1;
|
||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[name_index];
|
||||
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!ConstantPoolInfo {
|
||||
const tag_byte = try input.takeByte();
|
||||
const tag = std.enums.fromInt(Tag, tag_byte) orelse return ParseError.InvalidTag;
|
||||
|
|
@ -640,12 +683,28 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
.descriptor_index = try input.takeInt(u16, .big),
|
||||
},
|
||||
},
|
||||
.dynamic => .{
|
||||
.dynamic = .{
|
||||
.bootstrap_method_attr_index = try input.takeInt(u16, .big),
|
||||
.name_and_type_index = try input.takeInt(u16, .big),
|
||||
},
|
||||
},
|
||||
.invoke_dynamic => .{
|
||||
.invoke_dynamic = .{
|
||||
.bootstrap_method_attr_index = try input.takeInt(u16, .big),
|
||||
.name_and_type_index = try input.takeInt(u16, .big),
|
||||
},
|
||||
},
|
||||
.module => .{
|
||||
.module = .{
|
||||
.name_index = try input.takeInt(u16, .big),
|
||||
},
|
||||
},
|
||||
.package => .{
|
||||
.package = .{
|
||||
.name_index = try input.takeInt(u16, .big),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -671,7 +730,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
.utf8 => |utf8| try w.print("\"{s}\"", .{ utf8.bytes }),
|
||||
.method_handle => |method_handle| try w.print("{s} #{d}", .{ @tagName(method_handle.reference_kind), method_handle.reference_index }),
|
||||
.method_type => |method_type| try w.print("#{d}", .{ method_type.descriptor_index }),
|
||||
.dynamic => |dynamic| try w.print("#{d} #{d}", .{ dynamic.bootstrap_method_attr_index, dynamic.name_and_type_index }),
|
||||
.invoke_dynamic => |invoke_dynamic| try w.print("#{d} #{d}", .{ invoke_dynamic.bootstrap_method_attr_index, invoke_dynamic.name_and_type_index }),
|
||||
.module => |module| try w.print("#{d}", .{ module.name_index }),
|
||||
.package => |package| try w.print("#{d}", .{ package.name_index }),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -782,12 +844,30 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|||
const descriptor = method_type.descriptor(constant_pool) catch return error.WriteFailed;
|
||||
try descriptor.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.dynamic => |dynamic| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name_and_type:\n");
|
||||
const name_and_type = dynamic.nameAndType(constant_pool) catch return error.WriteFailed;
|
||||
try name_and_type.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.invoke_dynamic => |invoke_dynamic| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name_and_type:\n");
|
||||
const name_and_type = invoke_dynamic.nameAndType(constant_pool) catch return error.WriteFailed;
|
||||
try name_and_type.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.module => |module| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
const name = module.name(constant_pool) catch return error.WriteFailed;
|
||||
try name.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.package => |package| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
const name = package.name(constant_pool) catch return error.WriteFailed;
|
||||
try name.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -259,7 +259,6 @@ pub const AttributeInfo = union(enum) {
|
|||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
allocator: std.mem.Allocator,
|
||||
constant_pool: []const ?ConstantPoolInfo,
|
||||
) std.Io.Writer.Error!void {
|
||||
switch (self.*) {
|
||||
|
|
@ -325,7 +324,7 @@ pub const AttributeInfo = union(enum) {
|
|||
try w.splatByteAll(' ', depth * attr_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
|
||||
try a.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool);
|
||||
try a.indentedFormat(w, depth, attr_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
//.stack_map_table,
|
||||
|
|
@ -333,12 +332,14 @@ pub const AttributeInfo = union(enum) {
|
|||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("exceptions:\n");
|
||||
var exception_indent = indent;
|
||||
for (attr.exception_index_table, 0..) |exception, i| {
|
||||
for (attr.exception_index_table, 0..) |exception_index, i| {
|
||||
exception_indent += 1;
|
||||
defer exception_indent -= 1;
|
||||
|
||||
if (exception >= constant_pool.len) return error.WriteFailed;
|
||||
const cp_info = constant_pool[exception - 1];
|
||||
const index = exception_index - 1;
|
||||
|
||||
if (index >= constant_pool.len) return error.WriteFailed;
|
||||
const cp_info = constant_pool[index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * exception_indent);
|
||||
|
|
@ -396,14 +397,102 @@ pub const AttributeInfo = union(enum) {
|
|||
//.runtime_invisible_parameter_annotations,
|
||||
//.annotation_default,
|
||||
//.bootstrap_methods,
|
||||
//.method_parameters,
|
||||
.method_parameters => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("parameters:\n");
|
||||
var parameter_indent = indent;
|
||||
for (attr.parameters, 0..) |parameter, i| {
|
||||
parameter_indent += 1;
|
||||
defer parameter_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * parameter_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try parameter.indentedFormat(w, depth, parameter_indent, constant_pool);
|
||||
}
|
||||
},
|
||||
//.module,
|
||||
//.module_packages,
|
||||
//.module_main_class,
|
||||
//.nest_host,
|
||||
//.nest_members,
|
||||
//.record,
|
||||
//.permitted_subclasses,
|
||||
.module_packages => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("packages:\n");
|
||||
var package_indent = indent;
|
||||
for (attr.package_indeces, 0..) |package_index, i| {
|
||||
package_indent += 1;
|
||||
defer package_indent -= 1;
|
||||
|
||||
const index = package_index - 1;
|
||||
|
||||
if (index >= constant_pool.len) return error.WriteFailed;
|
||||
const cp_info = constant_pool[index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * package_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try cp_info.?.indentedFormat(w, depth, package_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
.module_main_class => |attr| {
|
||||
const main_class = attr.mainClass(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("main_class:\n");
|
||||
try main_class.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.nest_host => |attr| {
|
||||
const host_class = attr.hostClass(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("host_class:\n");
|
||||
try host_class.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.nest_members => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("classes:\n");
|
||||
var class_indent = indent;
|
||||
for (attr.classes, 0..) |class_index, i| {
|
||||
class_indent += 1;
|
||||
defer class_indent -= 1;
|
||||
|
||||
const index = class_index - 1;
|
||||
|
||||
if (index >= constant_pool.len) return error.WriteFailed;
|
||||
const cp_info = constant_pool[index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * class_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try cp_info.?.indentedFormat(w, depth, class_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
.record => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("components:\n");
|
||||
var component_indent = indent;
|
||||
for (attr.components, 0..) |component, i| {
|
||||
component_indent += 1;
|
||||
defer component_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * component_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try component.indentedFormat(w, depth, component_indent, constant_pool);
|
||||
}
|
||||
},
|
||||
.permitted_subclasses => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("classes:\n");
|
||||
var class_indent = indent;
|
||||
for (attr.classes, 0..) |class_index, i| {
|
||||
class_indent += 1;
|
||||
defer class_indent -= 1;
|
||||
|
||||
const index = class_index - 1;
|
||||
|
||||
if (index >= constant_pool.len) return error.WriteFailed;
|
||||
const cp_info = constant_pool[index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * class_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try cp_info.?.indentedFormat(w, depth, class_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
|
|
@ -1392,6 +1481,30 @@ pub const MethodParameters = struct {
|
|||
};
|
||||
|
||||
pub const ParameterAccessFlags = EnumFlags(ParameterFlags);
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const Parameter,
|
||||
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("flags: {f}\n", .{ self.access_flags });
|
||||
|
||||
const name_ = self.name(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
try name_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
}
|
||||
|
||||
pub fn name(self: *const Parameter, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const name_index = self.name_index - 1;
|
||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[name_index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
|
|
@ -1448,6 +1561,14 @@ pub const ModuleMainClass = struct {
|
|||
.main_class_index = try input.takeInt(u16, .big),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn mainClass(self: *const ModuleMainClass, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const main_class_index = self.main_class_index - 1;
|
||||
if (main_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[main_class_index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub const NestHost = struct {
|
||||
|
|
@ -1460,6 +1581,14 @@ pub const NestHost = struct {
|
|||
.host_class_index = try input.takeInt(u16, .big),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn hostClass(self: *const NestHost, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const host_class_index = self.host_class_index - 1;
|
||||
if (host_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[host_class_index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub const NestMembers = struct {
|
||||
|
|
@ -1518,6 +1647,53 @@ pub const Record = struct {
|
|||
}
|
||||
allocator.free(self.attributes);
|
||||
}
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const RecordComponentInfo,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
constant_pool: []const ?ConstantPoolInfo,
|
||||
) std.Io.Writer.Error!void {
|
||||
const name_ = self.name(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
try name_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
|
||||
const descriptor_ = self.descriptor(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("descriptor:\n");
|
||||
try descriptor_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("attributes:\n");
|
||||
var attr_indent = indent;
|
||||
for (self.attributes, 0..) |*attr, i| {
|
||||
attr_indent += 1;
|
||||
defer attr_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * attr_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
|
||||
try attr.indentedFormat(w, depth, attr_indent + 1, constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const name_index = self.name_index - 1;
|
||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[name_index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
|
||||
pub fn descriptor(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||
const descriptor_index = self.descriptor_index - 1;
|
||||
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||
const cp_info = constant_pool[descriptor_index];
|
||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||
return cp_info.?;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ pub fn indentedFormat(
|
|||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
allocator: std.mem.Allocator,
|
||||
constant_pool: []const ?ConstantPoolInfo,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
|
|
@ -79,7 +78,7 @@ pub fn indentedFormat(
|
|||
try w.splatByteAll(' ', depth * attr_indent);
|
||||
try w.print("{d}:\n", .{ j });
|
||||
|
||||
try attribute.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool);
|
||||
try attribute.indentedFormat(w, depth, attr_indent + 1, constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ pub fn indentedFormat(
|
|||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
allocator: std.mem.Allocator,
|
||||
constant_pool: []const ?ConstantPoolInfo,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
|
|
@ -82,7 +81,7 @@ pub fn indentedFormat(
|
|||
try w.splatByteAll(' ', depth * attr_indent);
|
||||
try w.print("{d}:\n", .{ j });
|
||||
|
||||
try attribute.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool);
|
||||
try attribute.indentedFormat(w, depth, attr_indent + 1, constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue