java_signatures/
display.rs1use std::fmt::{Display, Write};
2
3use crate::{ClassType, TypeParameter};
4
5use super::{
6 BaseType, ClassSignature, FieldSignature, JavaType, MethodSignature, ReferenceType,
7 SimpleClassType, ThrowsType, TypeArgument,
8};
9
10impl<'a> Display for FieldSignature<'a> {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 render_reference_type(&self.0, f)
13 }
14}
15
16impl<'a> Display for ClassSignature<'a> {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 render_type_parameters(&self.type_params, f)?;
19 render_class_type(&self.super_class, f)?;
20 for ty in &self.super_ifaces {
21 render_class_type(ty, f)?;
22 }
23 Ok(())
24 }
25}
26
27impl<'a> Display for MethodSignature<'a> {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 render_type_parameters(&self.type_params, f)?;
30 f.write_char('(')?;
31 for ty in &self.parameters {
32 render_java_type(ty, f)?;
33 }
34 f.write_char(')')?;
35 match self.result {
36 crate::ResultType::VoidType => f.write_char('V'),
37 crate::ResultType::ValueType(ref ty) => render_java_type(ty, f),
38 }?;
39 for ty in &self.throws {
40 f.write_char('^')?;
41 match ty {
42 ThrowsType::ClassType(ref ty) => render_class_type(ty, f),
43 ThrowsType::TypeVariable(name) => render_type_variable(name, f),
44 }?;
45 }
46 Ok(())
47 }
48}
49
50fn render_type_variable(name: &str, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 write!(f, "T{};", name)
52}
53
54fn render_reference_type(
55 ty: &ReferenceType<'_>,
56 f: &mut std::fmt::Formatter<'_>,
57) -> std::fmt::Result {
58 match ty {
59 ReferenceType::Class(ty) => render_class_type(ty, f),
60 ReferenceType::Variable(name) => render_type_variable(name, f),
61 ReferenceType::Array(arr) => {
62 for _ in 0..arr.dimension {
63 f.write_char('[')?;
64 }
65 render_java_type(&arr.ty, f)
66 }
67 }
68}
69
70fn render_class_type(ty: &ClassType<'_>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 f.write_char('L')?;
72 render_simple_class_type(&ty.base, f)?;
73 for ty in &ty.nested {
74 f.write_char('.')?;
75 render_simple_class_type(ty, f)?;
76 }
77 f.write_char(';')
78}
79
80fn render_type_parameters(
81 tys: &[TypeParameter<'_>],
82 f: &mut std::fmt::Formatter<'_>,
83) -> std::fmt::Result {
84 if !tys.is_empty() {
85 f.write_char('<')?;
86 for ty in tys {
87 f.write_str(ty.name)?;
88 f.write_char(':')?;
89 if let Some(ref ty) = ty.class_bound {
90 render_reference_type(ty, f)?;
91 }
92 for ty in &ty.iface_bounds {
93 f.write_char(':')?;
94 render_reference_type(ty, f)?;
95 }
96 }
97 f.write_char('>')?;
98 }
99 Ok(())
100}
101
102fn render_java_type(ty: &JavaType<'_>, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 match ty {
104 JavaType::Base(ty) => f.write_char(match ty {
105 BaseType::Byte => 'B',
106 BaseType::Char => 'C',
107 BaseType::Double => 'D',
108 BaseType::Float => 'F',
109 BaseType::Int => 'I',
110 BaseType::Long => 'J',
111 BaseType::Short => 'S',
112 BaseType::Boolean => 'Z',
113 }),
114 JavaType::Reference(ty) => render_reference_type(ty, f),
115 }
116}
117
118fn render_simple_class_type(
119 ty: &SimpleClassType,
120 f: &mut std::fmt::Formatter<'_>,
121) -> std::fmt::Result {
122 f.write_str(ty.name)?;
123 if !ty.type_args.is_empty() {
124 f.write_char('<')?;
125 for ty in &ty.type_args {
126 match ty {
127 TypeArgument::Unbounded => {
128 f.write_char('*')?;
129 }
130 TypeArgument::Default(ty) => {
131 render_reference_type(ty, f)?;
132 }
133 TypeArgument::Extends(ty) => {
134 f.write_char('+')?;
135 render_reference_type(ty, f)?;
136 }
137 TypeArgument::Super(ty) => {
138 f.write_char('-')?;
139 render_reference_type(ty, f)?;
140 }
141 }
142 }
143 f.write_char('>')?;
144 }
145 Ok(())
146}