Compare commits
1 commit
master
...
feature/fo
| Author | SHA1 | Date | |
|---|---|---|---|
| ce6ce6575d |
11 changed files with 112 additions and 1345 deletions
|
|
@ -1,11 +1,9 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const EnumFlags = @import("EnumFlags.zig").EnumFlags;
|
const EnumFlags = @import("EnumFlags.zig").EnumFlags;
|
||||||
|
const Formatter = @import("Formatter.zig");
|
||||||
|
|
||||||
pub const FieldInfo = @import("Class/FieldInfo.zig");
|
allocator: std.mem.Allocator,
|
||||||
pub const MethodInfo = @import("Class/MethodInfo.zig");
|
|
||||||
pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo;
|
|
||||||
pub const ConstantPool = @import("Class/ConstantPool.zig");
|
|
||||||
|
|
||||||
magic: u32,
|
magic: u32,
|
||||||
minor_version: u16,
|
minor_version: u16,
|
||||||
|
|
@ -21,6 +19,11 @@ attributes: []AttributeInfo,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
pub const FieldInfo = @import("Class/FieldInfo.zig");
|
||||||
|
pub const MethodInfo = @import("Class/MethodInfo.zig");
|
||||||
|
pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo;
|
||||||
|
pub const ConstantPool = @import("Class/ConstantPool.zig");
|
||||||
|
|
||||||
pub const ClassAccessFlags = EnumFlags(enum(u16) {
|
pub const ClassAccessFlags = EnumFlags(enum(u16) {
|
||||||
public = 0x0001,
|
public = 0x0001,
|
||||||
final = 0x0010,
|
final = 0x0010,
|
||||||
|
|
@ -36,8 +39,6 @@ pub const ClassAccessFlags = EnumFlags(enum(u16) {
|
||||||
pub const ParseError = std.Io.Reader.Error || std.mem.Allocator.Error || error {
|
pub const ParseError = std.Io.Reader.Error || std.mem.Allocator.Error || error {
|
||||||
InvalidMagicNumber,
|
InvalidMagicNumber,
|
||||||
InvalidTag,
|
InvalidTag,
|
||||||
InvalidOp,
|
|
||||||
InvalidArrayType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ResolveError = error {
|
pub const ResolveError = error {
|
||||||
|
|
@ -57,7 +58,7 @@ pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) (ParseError ||
|
||||||
var constant_pool: ConstantPool = try .parse(input, allocator);
|
var constant_pool: ConstantPool = try .parse(input, allocator);
|
||||||
errdefer constant_pool.deinit(allocator);
|
errdefer constant_pool.deinit(allocator);
|
||||||
|
|
||||||
const access_flags: ClassAccessFlags = .from(try input.takeInt(u16, .big));
|
const access_flags: ClassAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||||
|
|
||||||
const this_class = try input.takeInt(u16, .big);
|
const this_class = try input.takeInt(u16, .big);
|
||||||
const super_class = try input.takeInt(u16, .big);
|
const super_class = try input.takeInt(u16, .big);
|
||||||
|
|
@ -90,6 +91,7 @@ pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) (ParseError ||
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
.magic = magic,
|
.magic = magic,
|
||||||
.minor_version = minor_version,
|
.minor_version = minor_version,
|
||||||
.major_version = major_version,
|
.major_version = major_version,
|
||||||
|
|
@ -152,37 +154,37 @@ pub fn parseAttributes(input: *std.Io.Reader, constant_pool: ConstantPool, alloc
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Self) void {
|
||||||
self.constant_pool.deinit(allocator);
|
self.constant_pool.deinit(self.allocator);
|
||||||
self.freeInterfaces(allocator);
|
self.freeInterfaces();
|
||||||
self.freeFields(allocator);
|
self.freeFields();
|
||||||
self.freeMethods(allocator);
|
self.freeMethods();
|
||||||
self.freeAttributes(allocator);
|
self.freeAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeInterfaces(self: *Self, allocator: std.mem.Allocator) void {
|
fn freeInterfaces(self: *Self) void {
|
||||||
allocator.free(self.interfaces);
|
self.allocator.free(self.interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeFields(self: *Self, allocator: std.mem.Allocator) void {
|
fn freeFields(self: *Self) void {
|
||||||
for (self.fields) |*field_info| {
|
for (self.fields) |*field_info| {
|
||||||
field_info.deinit(allocator);
|
field_info.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
allocator.free(self.fields);
|
self.allocator.free(self.fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeMethods(self: *Self, allocator: std.mem.Allocator) void {
|
fn freeMethods(self: *Self) void {
|
||||||
for (self.methods) |*method_info| {
|
for (self.methods) |*method_info| {
|
||||||
method_info.deinit(allocator);
|
method_info.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
allocator.free(self.methods);
|
self.allocator.free(self.methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn freeAttributes(self: *Self, allocator: std.mem.Allocator) void {
|
fn freeAttributes(self: *Self) void {
|
||||||
for (self.attributes) |*attr| {
|
for (self.attributes) |*attr| {
|
||||||
attr.deinit(allocator);
|
attr.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
allocator.free(self.attributes);
|
self.allocator.free(self.attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jsonStringify(self: *const Self, jws: *std.json.Stringify) !void {
|
pub fn jsonStringify(self: *const Self, jws: *std.json.Stringify) !void {
|
||||||
|
|
@ -197,6 +199,10 @@ pub fn jsonStringify(self: *const Self, jws: *std.json.Stringify) !void {
|
||||||
try jws.endObject();
|
try jws.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn acceptFormatter(self: *const Self, formatter: *Formatter) Formatter.Error!void {
|
||||||
|
try formatter.printField("magic", "0x{X}", .{ self.magic });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||||
const depth = 2;
|
const depth = 2;
|
||||||
var indent: u8 = 0;
|
var indent: u8 = 0;
|
||||||
|
|
|
||||||
|
|
@ -319,22 +319,20 @@ pub const AttributeInfo = union(enum) {
|
||||||
defer instr_indent -= 1;
|
defer instr_indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * instr_indent);
|
try w.splatByteAll(' ', depth * instr_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}: 0x{x}\n", .{ i, instr });
|
||||||
|
|
||||||
try instr.indentedFormat(w, depth, instr_indent + 1, constant_pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("exception_table:\n");
|
_ = try w.write("exception_table:\n");
|
||||||
var exception_indent = indent;
|
var exception_indent = indent;
|
||||||
for (attr.exception_table, 0..) |*exception, i| {
|
for (attr.exception_table, 0..) |*exception, i| {
|
||||||
exception_indent += 1;
|
exception_indent += 1;
|
||||||
defer exception_indent -= 1;
|
defer exception_indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * exception_indent);
|
try w.splatByteAll(' ', depth * exception_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
||||||
try exception.indentedFormat(w, depth, exception_indent + 1, constant_pool);
|
try exception.indentedFormat(w, depth, exception_indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -627,7 +625,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * component_indent);
|
try w.splatByteAll(' ', depth * component_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
try component.indentedFormat(w, depth, component_indent + 1, constant_pool);
|
try component.indentedFormat(w, depth, component_indent, constant_pool);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.permitted_subclasses => |attr| {
|
.permitted_subclasses => |attr| {
|
||||||
|
|
@ -692,14 +690,12 @@ pub const ConstantValue = struct {
|
||||||
pub const Code = struct {
|
pub const Code = struct {
|
||||||
max_stack: u16,
|
max_stack: u16,
|
||||||
max_locals: u16,
|
max_locals: u16,
|
||||||
code: []Instruction,
|
code: []u8,
|
||||||
exception_table: []ExceptionHandler,
|
exception_table: []ExceptionHandler,
|
||||||
attributes: []AttributeInfo,
|
attributes: []AttributeInfo,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub const Instruction = @import("Code/Instruction.zig").Instruction;
|
|
||||||
|
|
||||||
pub const ExceptionHandler = struct {
|
pub const ExceptionHandler = struct {
|
||||||
start_pc: u16,
|
start_pc: u16,
|
||||||
end_pc: u16,
|
end_pc: u16,
|
||||||
|
|
@ -740,20 +736,8 @@ pub const Code = struct {
|
||||||
const max_locals = try input.takeInt(u16, .big);
|
const max_locals = try input.takeInt(u16, .big);
|
||||||
|
|
||||||
const code_length = try input.takeInt(u32, .big);
|
const code_length = try input.takeInt(u32, .big);
|
||||||
var code_reader_buf: [1024]u8 = undefined;
|
const code = try input.readAlloc(allocator, code_length);
|
||||||
var code_reader = input.limited(.limited(code_length), &code_reader_buf);
|
errdefer allocator.free(code);
|
||||||
var code = &code_reader.interface;
|
|
||||||
var byte_index: usize = 0;
|
|
||||||
var instructions: std.ArrayList(Instruction) = .empty;
|
|
||||||
defer instructions.deinit(allocator);
|
|
||||||
loop: while (true) {
|
|
||||||
_ = code.peekByte() catch |err| switch (err) {
|
|
||||||
error.EndOfStream => break :loop,
|
|
||||||
else => return err,
|
|
||||||
};
|
|
||||||
|
|
||||||
try instructions.append(allocator, try .parse(code, allocator, &byte_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
const exception_table_length = try input.takeInt(u16, .big);
|
const exception_table_length = try input.takeInt(u16, .big);
|
||||||
const exception_table = try allocator.alloc(ExceptionHandler, exception_table_length);
|
const exception_table = try allocator.alloc(ExceptionHandler, exception_table_length);
|
||||||
|
|
@ -777,16 +761,13 @@ pub const Code = struct {
|
||||||
return .{
|
return .{
|
||||||
.max_stack = max_stack,
|
.max_stack = max_stack,
|
||||||
.max_locals = max_locals,
|
.max_locals = max_locals,
|
||||||
.code = try instructions.toOwnedSlice(allocator),
|
.code = code,
|
||||||
.exception_table = exception_table,
|
.exception_table = exception_table,
|
||||||
.attributes = attributes,
|
.attributes = attributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
for (self.code) |*instruction| {
|
|
||||||
instruction.deinit(allocator);
|
|
||||||
}
|
|
||||||
allocator.free(self.code);
|
allocator.free(self.code);
|
||||||
allocator.free(self.exception_table);
|
allocator.free(self.exception_table);
|
||||||
for (self.attributes) |*attr| {
|
for (self.attributes) |*attr| {
|
||||||
|
|
@ -1219,7 +1200,7 @@ pub const InnerClasses = struct {
|
||||||
.inner_class_info_index = try input.takeInt(u16, .big),
|
.inner_class_info_index = try input.takeInt(u16, .big),
|
||||||
.outer_class_info_index = try input.takeInt(u16, .big),
|
.outer_class_info_index = try input.takeInt(u16, .big),
|
||||||
.inner_name_index = try input.takeInt(u16, .big),
|
.inner_name_index = try input.takeInt(u16, .big),
|
||||||
.inner_class_access_flags = .from(try input.takeInt(u16, .big)),
|
.inner_class_access_flags = .{ .mask = try input.takeInt(u16, .big) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2510,7 +2491,7 @@ pub const MethodParameters = struct {
|
||||||
for (parameters) |*parameter| {
|
for (parameters) |*parameter| {
|
||||||
parameter.* = .{
|
parameter.* = .{
|
||||||
.name_index = try input.takeInt(u16, .big),
|
.name_index = try input.takeInt(u16, .big),
|
||||||
.access_flags = .from(try input.takeInt(u16, .big)),
|
.access_flags = .{ .mask = try input.takeInt(u16, .big) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2714,7 +2695,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||||
const module_name_index = try input.takeInt(u16, .big);
|
const module_name_index = try input.takeInt(u16, .big);
|
||||||
const module_flags: ModuleFlags = .from(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 module_version_index = try input.takeInt(u16, .big);
|
||||||
|
|
||||||
const requires_count = try input.takeInt(u16, .big);
|
const requires_count = try input.takeInt(u16, .big);
|
||||||
|
|
@ -2722,7 +2703,7 @@ pub const Module = struct {
|
||||||
errdefer allocator.free(requires);
|
errdefer allocator.free(requires);
|
||||||
for (requires) |*r| {
|
for (requires) |*r| {
|
||||||
const requires_index = try input.takeInt(u16, .big);
|
const requires_index = try input.takeInt(u16, .big);
|
||||||
const requires_flags: Requires.RequiresFlags = .from(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);
|
const requires_version_index = try input.takeInt(u16, .big);
|
||||||
r.* = .{
|
r.* = .{
|
||||||
.requires_index = requires_index,
|
.requires_index = requires_index,
|
||||||
|
|
@ -2736,7 +2717,7 @@ pub const Module = struct {
|
||||||
errdefer allocator.free(exports);
|
errdefer allocator.free(exports);
|
||||||
for (exports) |*e| {
|
for (exports) |*e| {
|
||||||
const exports_index = try input.takeInt(u16, .big);
|
const exports_index = try input.takeInt(u16, .big);
|
||||||
const exports_flags: Exports.ExportsFlags = .from(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_count = try input.takeInt(u16, .big);
|
||||||
const exports_to_indeces = try allocator.alloc(u16, exports_to_count);
|
const exports_to_indeces = try allocator.alloc(u16, exports_to_count);
|
||||||
errdefer allocator.free(exports_to_indeces);
|
errdefer allocator.free(exports_to_indeces);
|
||||||
|
|
@ -2755,7 +2736,7 @@ pub const Module = struct {
|
||||||
errdefer allocator.free(opens);
|
errdefer allocator.free(opens);
|
||||||
for (opens) |*o| {
|
for (opens) |*o| {
|
||||||
const opens_index = try input.takeInt(u16, .big);
|
const opens_index = try input.takeInt(u16, .big);
|
||||||
const opens_flags: Opens.OpensFlags = .from(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_count = try input.takeInt(u16, .big);
|
||||||
const opens_to_indeces = try allocator.alloc(u16, opens_to_count);
|
const opens_to_indeces = try allocator.alloc(u16, opens_to_count);
|
||||||
errdefer allocator.free(opens_to_indeces);
|
errdefer allocator.free(opens_to_indeces);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -27,7 +27,7 @@ pub const FieldAccessFlags = EnumFlags(enum(u16) {
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: ConstantPool, allocator: std.mem.Allocator) !Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: ConstantPool, allocator: std.mem.Allocator) !Self {
|
||||||
const access_flags: FieldAccessFlags = .from(try input.takeInt(u16, .big));
|
const access_flags: FieldAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||||
const name_index = try input.takeInt(u16, .big);
|
const name_index = try input.takeInt(u16, .big);
|
||||||
const descriptor_index = try input.takeInt(u16, .big);
|
const descriptor_index = try input.takeInt(u16, .big);
|
||||||
const attributes = try Class.parseAttributes(input, constant_pool, allocator);
|
const attributes = try Class.parseAttributes(input, constant_pool, allocator);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ pub const MethodAccessFlags = EnumFlags(enum(u16) {
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: ConstantPool, allocator: std.mem.Allocator) !Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: ConstantPool, allocator: std.mem.Allocator) !Self {
|
||||||
const access_flags: MethodAccessFlags = .from(try input.takeInt(u16, .big));
|
const access_flags: MethodAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||||
const name_index = try input.takeInt(u16, .big);
|
const name_index = try input.takeInt(u16, .big);
|
||||||
const descriptor_index = try input.takeInt(u16, .big);
|
const descriptor_index = try input.takeInt(u16, .big);
|
||||||
const attributes = try Class.parseAttributes(input, constant_pool, allocator);
|
const attributes = try Class.parseAttributes(input, constant_pool, allocator);
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,6 @@ pub fn EnumFlags(comptime E: type) type {
|
||||||
|
|
||||||
pub const empty: Self = .{ .data = 0 };
|
pub const empty: Self = .{ .data = 0 };
|
||||||
|
|
||||||
pub fn from(mask: BackingInt) Self {
|
|
||||||
return .{
|
|
||||||
.mask = mask,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains(self: Self, flag: E) bool {
|
pub fn contains(self: Self, flag: E) bool {
|
||||||
return (self.mask & @intFromEnum(flag)) != 0;
|
return (self.mask & @intFromEnum(flag)) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
57
src/Formatter.zig
Normal file
57
src/Formatter.zig
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const Error = error {};
|
||||||
|
|
||||||
|
vtable: *const VTable,
|
||||||
|
w: *std.Io.Writer,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub const VTable = struct {
|
||||||
|
printField: *const fn (
|
||||||
|
ptr: *Self,
|
||||||
|
comptime field: []const u8,
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
args: anytype,
|
||||||
|
) Error!void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn printField(
|
||||||
|
self: *const Self,
|
||||||
|
comptime field: []const u8,
|
||||||
|
value: anytype,
|
||||||
|
) Error!void {
|
||||||
|
self.vtable.field(self, field);
|
||||||
|
self.vtable.value(self, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const IndentedFormatter = struct {
|
||||||
|
indent: u8 = 0,
|
||||||
|
depth: usize = 0,
|
||||||
|
|
||||||
|
interface: Self,
|
||||||
|
|
||||||
|
pub fn init(w: *std.Io.Writer) IndentedFormatter {
|
||||||
|
return .{
|
||||||
|
.interface = .{
|
||||||
|
.vtable = &.{
|
||||||
|
.printField = IndentedFormatter.printField,
|
||||||
|
},
|
||||||
|
.w = w,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printField(
|
||||||
|
f: *Self,
|
||||||
|
comptime field: []const u8,
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
args: anytype,
|
||||||
|
) Error!void {
|
||||||
|
const self: *IndentedFormatter = @alignCast(@fieldParentPtr("interface", f));
|
||||||
|
|
||||||
|
_ = try self.interface.w.splatByteAll(' ', self.indent * self.depth);
|
||||||
|
try self.interface.w.print(field ++ ": " ++ fmt ++ "\n", args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -2,6 +2,8 @@ const std = @import("std");
|
||||||
|
|
||||||
const Class = @import("Class.zig");
|
const Class = @import("Class.zig");
|
||||||
|
|
||||||
|
const Formatter = @import("Formatter.zig");
|
||||||
|
|
||||||
pub fn main(init: std.process.Init) !void {
|
pub fn main(init: std.process.Init) !void {
|
||||||
const io = init.io;
|
const io = init.io;
|
||||||
const allocator = init.gpa;
|
const allocator = init.gpa;
|
||||||
|
|
@ -50,9 +52,11 @@ pub fn main(init: std.process.Init) !void {
|
||||||
},
|
},
|
||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
defer class.deinit(allocator);
|
defer class.deinit();
|
||||||
|
|
||||||
try stdout.print("{f}", .{ class });
|
var indented_formatter: Formatter.IndentedFormatter = .init(stdout);
|
||||||
|
const formatter = &indented_formatter.interface;
|
||||||
|
try class.acceptFormatter(formatter);
|
||||||
|
|
||||||
try stdout.flush();
|
try stdout.flush();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,52 +17,6 @@ public class Main implements Runnable, Supplier<Integer>, Interface {
|
||||||
} finally {
|
} finally {
|
||||||
System.err.println("Finally block");
|
System.err.println("Finally block");
|
||||||
}
|
}
|
||||||
|
|
||||||
var a = 8;
|
|
||||||
a <<= 3;
|
|
||||||
final var b = a >> 1;
|
|
||||||
switch (b) {
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
System.out.println("Good");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Number " + a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final var o = getObject();
|
|
||||||
switch (o) {
|
|
||||||
case Integer i:
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
System.out.println("One");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
System.out.println("Two");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
System.out.println("Three");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Something else");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
inc(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getObject() {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void inc(int i) {
|
|
||||||
i += 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
BIN
testsuite/classes/java/Object.class
Normal file
BIN
testsuite/classes/java/Object.class
Normal file
Binary file not shown.
|
|
@ -1,2 +0,0 @@
|
||||||
public record Record(String name, int age) {}
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue