Format runtime visible/invisible type annotations attributes
This commit is contained in:
parent
76c436714f
commit
5ff7a358f9
3 changed files with 211 additions and 5 deletions
|
|
@ -295,11 +295,13 @@ pub const AttributeInfo = union(enum) {
|
|||
_ = try w.write("predefined: yes\n");
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type: {s}\n", .{ @tagName(predefined) });
|
||||
try w.print("type: {t}\n", .{ predefined });
|
||||
|
||||
switch (predefined) {
|
||||
.constant_value => |attr| {
|
||||
const constant_value = attr.constantValue(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("constant_value:\n");
|
||||
try constant_value.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.code => |attr| {
|
||||
|
|
@ -513,9 +515,37 @@ pub const AttributeInfo = union(enum) {
|
|||
try parameter_annotation.indentedFormat(w, depth, parameter_annotation_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
//.runtime_visible_type_annotations,
|
||||
//.runtime_invisible_type_annotations,
|
||||
//.annotation_default,
|
||||
.runtime_visible_type_annotations => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type_annotations:\n");
|
||||
var type_annotation_indent = indent;
|
||||
for (attr.type_annotations, 0..) |type_annotation, i| {
|
||||
type_annotation_indent += 1;
|
||||
defer type_annotation_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * type_annotation_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try type_annotation.indentedFormat(w, depth, type_annotation_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
.runtime_invisible_type_annotations => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type_annotations:\n");
|
||||
var type_annotation_indent = indent;
|
||||
for (attr.type_annotations, 0..) |type_annotation, i| {
|
||||
type_annotation_indent += 1;
|
||||
defer type_annotation_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * type_annotation_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try type_annotation.indentedFormat(w, depth, type_annotation_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
.annotation_default => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("default_value:\n");
|
||||
try attr.default_value.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.bootstrap_methods => |attr| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("bootstrap_methods:\n");
|
||||
|
|
@ -613,7 +643,6 @@ pub const AttributeInfo = union(enum) {
|
|||
try info.indentedFormat(w, depth, class_indent + 1, constant_pool);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -1971,6 +2000,22 @@ pub const TypeAnnotation = struct {
|
|||
start_pc: u16,
|
||||
length: u16,
|
||||
index: u16,
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const Entry,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("length: {d}\n", .{ self.length });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("start_pc: {d}\n", .{ self.index });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -1986,6 +2031,72 @@ pub const TypeAnnotation = struct {
|
|||
offset: u16,
|
||||
type_argument_index: u8,
|
||||
};
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const TargetInfo,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("target_info_type: {t}\n", .{ self.* });
|
||||
|
||||
switch (self.*) {
|
||||
.type_parameter => |*type_parameter| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type_parameter_index: {d}\n", .{ type_parameter.type_parameter_index });
|
||||
},
|
||||
.supertype => |*supertype| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("supertype_index: {d}\n", .{ supertype.supertype_index });
|
||||
},
|
||||
.type_parameter_bound => |*type_parameter_bound| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type_parameter_index: {d}\n", .{ type_parameter_bound.type_parameter_index });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("bound_index: {d}\n", .{ type_parameter_bound.bound_index });
|
||||
},
|
||||
.formal_parameter => |*formal_parameter| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("formal_parameter_index: {d}\n", .{ formal_parameter.formal_parameter_index });
|
||||
},
|
||||
.throws => |*throws| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("throws_type_index: {d}\n", .{ throws.throws_type_index });
|
||||
},
|
||||
.localvar => |*localvar| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("table:\n");
|
||||
var entry_indent = indent;
|
||||
for (localvar.table, 0..) |*entry, i| {
|
||||
entry_indent += 1;
|
||||
defer entry_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * entry_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
|
||||
try entry.indentedFormat(w, depth, indent);
|
||||
}
|
||||
},
|
||||
.@"catch" => |*@"catch"| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("exception_table_index: {d}\n", .{ @"catch".exception_table_index });
|
||||
},
|
||||
.offset => |*offset| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("offset: {d}\n", .{ offset.offset });
|
||||
},
|
||||
.type_argument => |*type_argument| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("offset: {d}\n", .{ type_argument.offset });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type_argument_index: {d}\n", .{ type_argument.type_argument_index });
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const TypePath = struct {
|
||||
|
|
@ -1994,6 +2105,19 @@ pub const TypeAnnotation = struct {
|
|||
pub const Path = struct {
|
||||
type_path_kind: u8,
|
||||
type_argument_index: u8,
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const Path,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type_path_kind: {d}\n", .{ self.type_path_kind });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type_argument_index: {d}\n", .{ self.type_argument_index });
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!TypePath {
|
||||
|
|
@ -2015,6 +2139,25 @@ pub const TypeAnnotation = struct {
|
|||
pub fn deinit(self: *TypePath, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.paths);
|
||||
}
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const TypePath,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("paths:\n");
|
||||
var path_indent = indent;
|
||||
for (self.paths, 0..) |path, i| {
|
||||
path_indent += 1;
|
||||
defer path_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * path_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try path.indentedFormat(w, depth, path_indent + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||
|
|
@ -2119,6 +2262,46 @@ pub const TypeAnnotation = struct {
|
|||
}
|
||||
allocator.free(self.element_value_pairs);
|
||||
}
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const Self,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
constant_pool: ConstantPool,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("target_type: {t}\n", .{ self.target_type });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("target_info:\n");
|
||||
try self.target_info.indentedFormat(w, depth + 1, indent);
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("target_path:\n");
|
||||
try self.target_path.indentedFormat(w, depth + 1, indent);
|
||||
|
||||
const type_ = self.@"type"(constant_pool) catch return error.WriteFailed;
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type:\n");
|
||||
try type_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("element_value_pairs:\n");
|
||||
var element_value_pair_indent = indent;
|
||||
for (self.element_value_pairs, 0..) |element_value_pair, i| {
|
||||
element_value_pair_indent += 1;
|
||||
defer element_value_pair_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * element_value_pair_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try element_value_pair.indentedFormat(w, depth, element_value_pair_indent + 1, constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn @"type"(self: *const Self, constant_pool: ConstantPool) ResolveError!ConstantPool.Info {
|
||||
return constant_pool.getTag(self.type_index, .utf8);
|
||||
}
|
||||
};
|
||||
|
||||
pub const RuntimeVisibleTypeAnnotations = struct {
|
||||
|
|
|
|||
9
testsuite/classes/java/CustomTypeAnnotation.java
Normal file
9
testsuite/classes/java/CustomTypeAnnotation.java
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
public @interface CustomTypeAnnotation {
|
||||
}
|
||||
14
testsuite/classes/java/GenericClass.java
Normal file
14
testsuite/classes/java/GenericClass.java
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import java.util.function.Supplier;
|
||||
|
||||
public class GenericClass<@CustomTypeAnnotation T> {
|
||||
|
||||
public <T> Supplier<T> getSupplier(T value) {
|
||||
return new Supplier<T>() {
|
||||
@Override
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue