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> {
|
public class Main implements Runnable, Supplier<Integer>, Interface {
|
||||||
private static final String message = "Hello, World";
|
private static final String name = "John";
|
||||||
private static final int number = 42;
|
private static final int number = 42;
|
||||||
private static final double funnyNumber = 6.9;
|
private static final double funnyNumber = 6.9;
|
||||||
|
|
||||||
public static void main() {
|
public static void main() {
|
||||||
System.out.println(message);
|
new Main().sayHello();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Main.main();
|
Main.main();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer call() {
|
@Override
|
||||||
|
public Integer get() {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
zig
|
zig
|
||||||
zls
|
zls
|
||||||
|
javaPackages.compiler.openjdk25
|
||||||
|
jdt-language-server
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = with pkgs; [];
|
buildInputs = with pkgs; [];
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const EnumFlags = @import("EnumFlags.zig").EnumFlags;
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
magic: u32,
|
magic: u32,
|
||||||
minor_version: u16,
|
minor_version: u16,
|
||||||
major_version: u16,
|
major_version: u16,
|
||||||
constant_pool: []?CpInfo,
|
constant_pool: []?CpInfo,
|
||||||
access_flags: u16,
|
access_flags: ClassAccessFlags,
|
||||||
this_class: u16,
|
this_class: u16,
|
||||||
super_class: u16,
|
super_class: u16,
|
||||||
interfaces: []u16,
|
interfaces: []u16,
|
||||||
|
|
@ -43,7 +45,7 @@ pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Sel
|
||||||
allocator.free(constant_pool);
|
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 this_class = try input.takeInt(u16, .big);
|
||||||
const super_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("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;
|
const this_class = self.thisClass() catch return error.WriteFailed;
|
||||||
_ = try w.write("this class:\n");
|
_ = try w.write("this class:\n");
|
||||||
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = this_class });
|
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;
|
defer indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
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.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("name:\n");
|
_ = 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;
|
indent += 1;
|
||||||
defer 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.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("name:\n");
|
_ = try w.write("name:\n");
|
||||||
const method_name = method.name(self.constant_pool) catch return error.WriteFailed;
|
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 });
|
try w.print("bytes: \"{s}\"\n", .{ utf8.bytes });
|
||||||
},
|
},
|
||||||
.method_handle => |method_handle| {
|
.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.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("reference:\n");
|
_ = try w.write("reference:\n");
|
||||||
const reference = method_handle.reference(self.constant_pool) catch return error.WriteFailed;
|
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 {
|
pub const FieldInfo = struct {
|
||||||
access_flags: u16,
|
access_flags: FieldAccessFlags,
|
||||||
name_index: u16,
|
name_index: u16,
|
||||||
descriptor_index: u16,
|
descriptor_index: u16,
|
||||||
attributes: []AttributeInfo,
|
attributes: []AttributeInfo,
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !FieldInfo {
|
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 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 parseAttributes(input, allocator);
|
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 {
|
pub const MethodInfo = struct {
|
||||||
access_flags: u16,
|
access_flags: MethodAccessFlags,
|
||||||
name_index: u16,
|
name_index: u16,
|
||||||
descriptor_index: u16,
|
descriptor_index: u16,
|
||||||
attributes: []AttributeInfo,
|
attributes: []AttributeInfo,
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !MethodInfo {
|
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 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 parseAttributes(input, allocator);
|
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 {
|
pub const AttributeInfo = struct {
|
||||||
attribute_name_index: u16,
|
attribute_name_index: u16,
|
||||||
info: []u8,
|
info: []u8,
|
||||||
|
|
@ -1172,8 +1226,23 @@ pub const AttributeInfo = struct {
|
||||||
inner_class_info_index: u16,
|
inner_class_info_index: u16,
|
||||||
outer_class_info_index: u16,
|
outer_class_info_index: u16,
|
||||||
inner_name_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 {
|
pub const EnclosingMethod = struct {
|
||||||
|
|
@ -1534,7 +1603,7 @@ pub const AttributeInfo = struct {
|
||||||
.inner_class_info_index = try r.takeInt(u16, .big),
|
.inner_class_info_index = try r.takeInt(u16, .big),
|
||||||
.outer_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_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