Parse access flags
This commit is contained in:
parent
1e6be5588a
commit
7d7df22df3
5 changed files with 147 additions and 14 deletions
10
Interface.java
Normal file
10
Interface.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
public interface Interface {
|
||||
|
||||
String getName();
|
||||
|
||||
default void sayHello() {
|
||||
System.out.println("Hello " + getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
18
Main.java
18
Main.java
|
|
@ -1,19 +1,27 @@
|
|||
import java.util.concurrent.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Main implements Runnable, Callable<Integer> {
|
||||
private static final String message = "Hello, World";
|
||||
public class Main implements Runnable, Supplier<Integer>, Interface {
|
||||
private static final String name = "John";
|
||||
private static final int number = 42;
|
||||
private static final double funnyNumber = 6.9;
|
||||
|
||||
public static void main() {
|
||||
System.out.println(message);
|
||||
new Main().sayHello();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Main.main();
|
||||
}
|
||||
|
||||
public Integer call() {
|
||||
@Override
|
||||
public Integer get() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
nativeBuildInputs = with pkgs; [
|
||||
zig
|
||||
zls
|
||||
javaPackages.compiler.openjdk25
|
||||
jdt-language-server
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [];
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
const std = @import("std");
|
||||
|
||||
const EnumFlags = @import("EnumFlags.zig").EnumFlags;
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
magic: u32,
|
||||
minor_version: u16,
|
||||
major_version: u16,
|
||||
constant_pool: []?CpInfo,
|
||||
access_flags: u16,
|
||||
access_flags: ClassAccessFlags,
|
||||
this_class: u16,
|
||||
super_class: u16,
|
||||
interfaces: []u16,
|
||||
|
|
@ -43,7 +45,7 @@ pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Sel
|
|||
allocator.free(constant_pool);
|
||||
}
|
||||
|
||||
const access_flags = try input.takeInt(u16, .big);
|
||||
const access_flags: ClassAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||
|
||||
const this_class = try input.takeInt(u16, .big);
|
||||
const super_class = try input.takeInt(u16, .big);
|
||||
|
|
@ -223,6 +225,8 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
|
||||
try w.print("version: {d}.{d}\n", .{ self.major_version, self.minor_version });
|
||||
|
||||
try w.print("flags: {f}\n", .{ self.access_flags });
|
||||
|
||||
const this_class = self.thisClass() catch return error.WriteFailed;
|
||||
_ = try w.write("this class:\n");
|
||||
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = this_class });
|
||||
|
|
@ -258,7 +262,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
defer indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("flags: {d}\n", .{ field.access_flags });
|
||||
try w.print("flags: {f}\n", .{ field.access_flags });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
|
|
@ -294,6 +298,9 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
|||
indent += 1;
|
||||
defer indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("flags: {f}\n", .{ method.access_flags });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("name:\n");
|
||||
const method_name = method.name(self.constant_pool) catch return error.WriteFailed;
|
||||
|
|
@ -478,6 +485,9 @@ fn formatCpInfo(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u8,
|
|||
try w.print("bytes: \"{s}\"\n", .{ utf8.bytes });
|
||||
},
|
||||
.method_handle => |method_handle| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("kind: {t}\n", .{ method_handle.reference_kind });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("reference:\n");
|
||||
const reference = method_handle.reference(self.constant_pool) catch return error.WriteFailed;
|
||||
|
|
@ -854,14 +864,27 @@ pub const CpInfo = union(CpInfo.Tag) {
|
|||
}
|
||||
};
|
||||
|
||||
pub const ClassFlags = enum(u16) {
|
||||
public = 0x0001,
|
||||
final = 0x0010,
|
||||
super = 0x0020,
|
||||
interface = 0x0200,
|
||||
abstract = 0x0400,
|
||||
synthetic = 0x1000,
|
||||
annotation = 0x2000,
|
||||
@"enum" = 0x4000,
|
||||
};
|
||||
|
||||
pub const ClassAccessFlags = EnumFlags(ClassFlags);
|
||||
|
||||
pub const FieldInfo = struct {
|
||||
access_flags: u16,
|
||||
access_flags: FieldAccessFlags,
|
||||
name_index: u16,
|
||||
descriptor_index: u16,
|
||||
attributes: []AttributeInfo,
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !FieldInfo {
|
||||
const access_flags = try input.takeInt(u16, .big);
|
||||
const access_flags: FieldAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||
const name_index = try input.takeInt(u16, .big);
|
||||
const descriptor_index = try input.takeInt(u16, .big);
|
||||
const attributes = try parseAttributes(input, allocator);
|
||||
|
|
@ -897,14 +920,28 @@ pub const FieldInfo = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const FieldFlags = enum(u16) {
|
||||
public = 0x0001,
|
||||
private = 0x0002,
|
||||
protected = 0x0004,
|
||||
static = 0x0008,
|
||||
final = 0x0010,
|
||||
@"volatile" = 0x0040,
|
||||
transient = 0x0080,
|
||||
synthetic = 0x1000,
|
||||
@"enum" = 0x4000,
|
||||
};
|
||||
|
||||
pub const FieldAccessFlags = EnumFlags(FieldFlags);
|
||||
|
||||
pub const MethodInfo = struct {
|
||||
access_flags: u16,
|
||||
access_flags: MethodAccessFlags,
|
||||
name_index: u16,
|
||||
descriptor_index: u16,
|
||||
attributes: []AttributeInfo,
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !MethodInfo {
|
||||
const access_flags = try input.takeInt(u16, .big);
|
||||
const access_flags: MethodAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||
const name_index = try input.takeInt(u16, .big);
|
||||
const descriptor_index = try input.takeInt(u16, .big);
|
||||
const attributes = try parseAttributes(input, allocator);
|
||||
|
|
@ -940,6 +977,23 @@ pub const MethodInfo = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const MethodFlags = enum(u16) {
|
||||
public = 0x0001,
|
||||
private = 0x0002,
|
||||
protected = 0x0004,
|
||||
static = 0x0008,
|
||||
final = 0x0010,
|
||||
synchronized = 0x0020,
|
||||
bridge = 0x0040,
|
||||
varargs = 0x0080,
|
||||
native = 0x0100,
|
||||
abstract = 0x0400,
|
||||
strict = 0x0800,
|
||||
synthetic = 0x1000,
|
||||
};
|
||||
|
||||
pub const MethodAccessFlags = EnumFlags(MethodFlags);
|
||||
|
||||
pub const AttributeInfo = struct {
|
||||
attribute_name_index: u16,
|
||||
info: []u8,
|
||||
|
|
@ -1172,8 +1226,23 @@ pub const AttributeInfo = struct {
|
|||
inner_class_info_index: u16,
|
||||
outer_class_info_index: u16,
|
||||
inner_name_index: u16,
|
||||
inner_class_access_flags: u16,
|
||||
inner_class_access_flags: InnerClassAccessFlags,
|
||||
};
|
||||
|
||||
pub const InnerClassFlags = enum(u16) {
|
||||
public = 0x0001,
|
||||
private = 0x0002,
|
||||
protected = 0x0004,
|
||||
static = 0x0008,
|
||||
final = 0x0010,
|
||||
interface = 0x0200,
|
||||
abstract = 0x0400,
|
||||
synthetic = 0x1000,
|
||||
annotation = 0x2000,
|
||||
@"enum" = 0x4000,
|
||||
};
|
||||
|
||||
pub const InnerClassAccessFlags = EnumFlags(InnerClassFlags);
|
||||
};
|
||||
|
||||
pub const EnclosingMethod = struct {
|
||||
|
|
@ -1534,7 +1603,7 @@ pub const AttributeInfo = struct {
|
|||
.inner_class_info_index = try r.takeInt(u16, .big),
|
||||
.outer_class_info_index = try r.takeInt(u16, .big),
|
||||
.inner_name_index = try r.takeInt(u16, .big),
|
||||
.inner_class_access_flags = try r.takeInt(u16, .big),
|
||||
.inner_class_access_flags = .{ .mask = try r.takeInt(u16, .big) },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
44
src/EnumFlags.zig
Normal file
44
src/EnumFlags.zig
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn EnumFlags(comptime E: type) type {
|
||||
return packed struct {
|
||||
const Self = @This();
|
||||
|
||||
const BackingInt = @typeInfo(E).@"enum".tag_type;
|
||||
|
||||
mask: BackingInt,
|
||||
|
||||
pub const empty: Self = .{ .data = 0 };
|
||||
|
||||
pub fn contains(self: Self, flag: E) bool {
|
||||
return (self.mask & @intFromEnum(flag)) != 0;
|
||||
}
|
||||
|
||||
pub fn insert(self: *Self, flag: E) void {
|
||||
self.mask |= @intFromEnum(flag);
|
||||
}
|
||||
|
||||
pub fn remove(self: *Self, flag: E) void {
|
||||
self.mask &= ~@intFromEnum(flag);
|
||||
}
|
||||
|
||||
pub fn toggle(self: *Self, flag: E) void {
|
||||
self.mask ^= @intFromEnum(flag);
|
||||
}
|
||||
|
||||
pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
var index: usize = 0;
|
||||
inline for (std.meta.fields(E)) |field| {
|
||||
const key = @field(E, field.name);
|
||||
if (self.contains(key)) {
|
||||
if (index > 0) {
|
||||
_ = try w.write(" | ");
|
||||
}
|
||||
try w.print("{s}", .{ field.name });
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue