luaur_ast/methods/
printer_visualize_function_body.rs1use crate::records::ast_expr_function::AstExprFunction;
2use crate::records::ast_generic_type::AstGenericType;
3use crate::records::ast_generic_type_pack::AstGenericTypePack;
4use crate::records::ast_local::AstLocal;
5use crate::records::ast_stat_block::AstStatBlock;
6use crate::records::comma_separator_inserter::CommaSeparatorInserter;
7use crate::records::cst_expr_function::CstExprFunction;
8use crate::records::cst_generic_type_pack::CstGenericTypePack;
9use crate::records::printer::Printer;
10
11pub trait IntoAstExprFunctionMut {
12 unsafe fn into_ast_expr_function_mut(self) -> *mut AstExprFunction;
13}
14
15impl IntoAstExprFunctionMut for *mut AstExprFunction {
16 unsafe fn into_ast_expr_function_mut(self) -> *mut AstExprFunction {
17 self
18 }
19}
20
21impl IntoAstExprFunctionMut for &mut AstExprFunction {
22 unsafe fn into_ast_expr_function_mut(self) -> *mut AstExprFunction {
23 self
24 }
25}
26
27impl<'a> Printer<'a> {
28 pub fn visualize_function_body<F: IntoAstExprFunctionMut>(&mut self, func: F) {
29 let func = unsafe { &mut *func.into_ast_expr_function_mut() };
30 let cst_node =
31 self.lookup_cst_node_impl::<CstExprFunction>(func as *mut AstExprFunction as *mut _);
32
33 if func.generics.size > 0 || func.generic_packs.size > 0 {
34 let comma_position = if cst_node.is_null() {
35 core::ptr::null()
36 } else {
37 unsafe { (*cst_node).generics_comma_positions.data }
38 };
39
40 let mut comma = CommaSeparatorInserter::new(self.writer, core::ptr::null());
41 comma.comma_position = comma_position;
42
43 if !cst_node.is_null() {
44 let open_pos = unsafe { &(*cst_node).open_generics_position };
45 self.maybe_advance_and_write(open_pos, "<", false);
46 } else {
47 self.writer.symbol("<");
48 }
49
50 for i in 0..func.generics.size {
51 comma.call(self.writer);
52
53 let generic_ty = unsafe { *func.generics.data.add(i) };
54 unsafe {
55 self.writer.advance(&(*generic_ty).base.location.begin);
56 let name_val = (*generic_ty).name.value;
57 let name_str = core::ffi::CStr::from_ptr(name_val).to_string_lossy();
58 self.writer.identifier(&name_str);
59 }
60 }
61
62 for i in 0..func.generic_packs.size {
63 comma.call(self.writer);
64
65 let pack = unsafe { *func.generic_packs.data.add(i) };
66 unsafe {
67 self.writer.advance(&(*pack).base.location.begin);
68 let name_val = (*pack).name.value;
69 let name_str = core::ffi::CStr::from_ptr(name_val).to_string_lossy();
70 self.writer.identifier(&name_str);
71
72 let generic_type_pack_cst_node =
73 self.lookup_cst_node_impl::<CstGenericTypePack>(pack as *mut _);
74 if !generic_type_pack_cst_node.is_null() {
75 let ellipsis_pos = &(*generic_type_pack_cst_node).ellipsis_position;
76 self.advance(ellipsis_pos);
77 }
78
79 self.writer.symbol("...");
80 }
81 }
82
83 if !cst_node.is_null() {
84 let close_pos = unsafe { &(*cst_node).close_generics_position };
85 self.maybe_advance_and_write(close_pos, ">", false);
86 } else {
87 self.writer.symbol(">");
88 }
89 }
90
91 if let Some(arg_location) = func.arg_location.as_ref() {
92 self.advance(&arg_location.begin);
93 }
94 self.writer.symbol("(");
95
96 let args_comma_pos = if cst_node.is_null() {
97 core::ptr::null()
98 } else {
99 unsafe { (*cst_node).args_comma_positions.data }
100 };
101
102 let mut comma = CommaSeparatorInserter::new(self.writer, core::ptr::null());
103 comma.comma_position = args_comma_pos;
104
105 for i in 0..func.args.size {
106 let local = unsafe { *func.args.data.add(i) };
107 comma.call(self.writer);
108
109 unsafe {
110 self.advance(&(*local).location.begin);
111 let name_val = (*local).name.value;
112 let name_str = core::ffi::CStr::from_ptr(name_val).to_string_lossy();
113 self.writer.identifier(&name_str);
114
115 if self.write_types && !(*local).annotation.is_null() {
116 if !cst_node.is_null() {
117 let colon_pos =
118 unsafe { (*cst_node).args_annotation_colon_positions.data.add(i) };
119 self.maybe_advance_and_write(&*colon_pos, ":", false);
120 } else {
121 self.writer.symbol(":");
122 }
123
124 self.visualize_type_annotation(&mut *(*local).annotation);
125 }
126 }
127 }
128
129 if func.vararg {
130 comma.call(self.writer);
131
132 self.advance(&func.vararg_location.begin);
133 self.writer.symbol("...");
134
135 if self.write_types && !func.vararg_annotation.is_null() {
136 if !cst_node.is_null() {
137 unsafe {
138 self.maybe_advance_and_write(
139 &(*cst_node).vararg_annotation_colon_position,
140 ":",
141 false,
142 );
143 }
144 } else {
145 self.writer.symbol(":");
146 }
147
148 unsafe {
149 self.visualize_type_pack_annotation(
150 &mut *func.vararg_annotation,
151 true,
152 false,
153 false,
154 );
155 }
156 }
157 }
158
159 if let Some(arg_location) = func.arg_location.as_ref() {
160 self.advance_before(arg_location.end, 1);
161 }
162 self.writer.symbol(")");
163
164 if self.write_types && !func.return_annotation.is_null() {
165 if !cst_node.is_null() {
166 unsafe {
167 self.maybe_advance_and_write(
168 &(*cst_node).return_specifier_position,
169 ":",
170 false,
171 );
172 }
173 } else {
174 self.writer.symbol(":");
175 }
176
177 if cst_node.is_null() {
178 self.writer.space();
179 }
180
181 unsafe {
182 self.visualize_type_pack_annotation(
183 &mut *func.return_annotation,
184 false,
185 false,
186 true,
187 );
188 }
189 }
190
191 unsafe {
192 self.visualize_block_ast_stat_block(&mut *func.body);
193 self.advance(&(*func.body).base.base.location.end);
194 }
195 self.writer.keyword("end");
196 }
197}