1use super::{ParsedImpl, ParsedMethod};
53use crate::r_class_formatter::class_ref_or_verbatim;
54
55fn active_setter_precondition_checks(
79 setter: &ParsedMethod,
80 impl_preconditions: Option<bool>,
81) -> Vec<String> {
82 let Some(mut value_arg) = setter.sig.inputs.iter().find_map(|arg| match arg {
83 syn::FnArg::Typed(pat_type) => Some(pat_type.clone()),
84 syn::FnArg::Receiver(_) => None,
85 }) else {
86 return Vec::new();
87 };
88
89 let mut per_param = setter.method_attrs.per_param.clone();
90 if let syn::Pat::Ident(pat_ident) = value_arg.pat.as_mut() {
91 let rust_name = crate::naming::ident_name(&pat_ident.ident);
92 if let Some(mut attrs) = per_param.remove(&rust_name) {
95 attrs.formal = None;
96 per_param.insert("value".to_string(), attrs);
97 }
98 pat_ident.ident = syn::Ident::new("value", pat_ident.ident.span());
99 }
100
101 let mut inputs: syn::punctuated::Punctuated<syn::FnArg, ::syn::token::Commasyn::Token![,]> =
102 syn::punctuated::Punctuated::new();
103 inputs.push(syn::FnArg::Typed(value_arg));
104
105 crate::r_class_formatter::build_method_precondition_checks(
106 &inputs,
107 &per_param,
108 setter.method_attrs.coerce,
109 setter.method_attrs.preconditions,
110 impl_preconditions,
111 None,
112 )
113}
114
115fn field_tag_documents(tag: &str, field_name: &str) -> bool {
123 let Some(rest) = tag.trim_start().strip_prefix("@field ") else {
124 return false;
125 };
126 let Some(names) = rest.split_whitespace().next() else {
127 return false;
128 };
129 names.split(',').any(|name| name.trim() == field_name)
130}
131
132fn active_binding_field_lines(method: &ParsedMethod, class_doc_tags: &[String]) -> Vec<String> {
133 let prop_name = method
134 .method_attrs
135 .r6
136 .prop
137 .clone()
138 .unwrap_or_else(|| method.r_method_name());
139
140 if class_doc_tags
141 .iter()
142 .any(|tag| field_tag_documents(tag, &prop_name))
143 {
144 return Vec::new();
145 }
146
147 if method.method_attrs.noexport || method.method_attrs.internal {
148 return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[super::class_default(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' @field {0} (internal)",
prop_name))
}))]))vec![super::class_default(format!(
149 "#' @field {prop_name} (internal)"
150 ))];
151 }
152
153 let description = method.doc_tags.iter().find_map(|tag| {
154 tag.strip_prefix("@field ")
155 .and_then(|rest| rest.split_once(char::is_whitespace).map(|(_, desc)| desc))
156 .or_else(|| tag.strip_prefix("@description "))
157 .or_else(|| tag.strip_prefix("@title "))
158 });
159 let Some(description) = description else {
160 return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[super::class_default(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' @field {0} Active binding.",
prop_name))
}))]))vec![super::class_default(format!(
161 "#' @field {prop_name} Active binding."
162 ))];
163 };
164
165 let mut description_lines = description.lines();
166 let first = description_lines.next().unwrap_or("Active binding.");
167 let mut lines = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[super::class_default(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' @field {0} {1}",
prop_name, first))
}))]))vec![super::class_default(format!(
168 "#' @field {prop_name} {first}"
169 ))];
170 lines.extend(description_lines.map(crate::roxygen::roxygen_line));
171 lines
172}
173
174pub(crate) const MX_INHERITED_PARAM_PREFIX: &str = ".__MX_INHERITED_PARAM__(";
179
180pub fn generate_r6_class(parsed_impl: &ParsedImpl) -> super::ClassWrapper {
210 use crate::r_class_formatter::{ClassDocBuilder, MethodDocBuilder, ParsedImplExt};
211
212 let class_name = parsed_impl.class_name();
213 let type_ident = &parsed_impl.type_ident;
214 let class_doc_tags = &parsed_impl.doc_tags;
215
216 let mut w = super::ClassWrapper::default();
217 let mut lines = Vec::new();
218
219 let class_docs = ClassDocBuilder::new(&class_name, type_ident, class_doc_tags, "R6")
221 .with_imports("@importFrom R6 R6Class")
222 .with_export_control(parsed_impl.internal, parsed_impl.noexport);
223 lines.extend(class_docs.build());
224 w.class_docs = class_docs.docs();
225 if !crate::roxygen::has_roxygen_tag(class_doc_tags, "param .ptr") {
228 let insert_pos = lines.len().saturating_sub(1);
230 lines.insert(
231 insert_pos,
232 super::class_default(
233 "#' @param .ptr Internal pointer (used by static methods, not for direct use).",
234 ),
235 );
236 }
237 w.mark_class_doc_lines(&mut lines, parsed_impl);
238
239 let active_method_contexts: Vec<_> = parsed_impl.active_instance_method_contexts().collect();
245 w.class_doc_lines.extend(
246 active_method_contexts
247 .iter()
248 .flat_map(|ctx| active_binding_field_lines(ctx.method, class_doc_tags)),
249 );
250
251 if let Some(ref parent) = parsed_impl.r6_inherit {
255 let parent_ref = class_ref_or_verbatim(parent);
256 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} <- R6::R6Class(\"{1}\", inherit = {2},",
class_name, class_name, parent_ref))
})format!(
257 "{} <- R6::R6Class(\"{}\", inherit = {},",
258 class_name, class_name, parent_ref
259 ));
260 } else {
261 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} <- R6::R6Class(\"{1}\",",
class_name, class_name))
})format!("{} <- R6::R6Class(\"{}\",", class_name, class_name));
262 }
263
264 if parsed_impl.r6_portable == Some(false) {
266 lines.push(" portable = FALSE,".to_string());
267 }
268
269 lines.push(" public = list(".to_string());
271
272 let class_param_names = &parsed_impl.class_param_names;
276
277 if let Some(ctx) = parsed_impl.constructor_context() {
281 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}",
ctx.source_comment(type_ident)))
})format!(" {}", ctx.source_comment(type_ident)));
282 let has_description = ctx
285 .method
286 .doc_tags
287 .iter()
288 .any(|t| t.starts_with("@description ") || t.starts_with("@title "));
289 if !has_description {
290 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" #\' @description Create a new `{0}`.",
class_name))
})format!(
291 " #' @description Create a new `{}`.",
292 class_name
293 ));
294 }
295 for tag in &ctx.method.doc_tags {
296 for line in tag.lines() {
297 let line = if line.starts_with("@title ") {
298 line.replacen("@title ", "@description ", 1)
299 } else {
300 line.to_string()
301 };
302 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}",
crate::roxygen::roxygen_line(&line)))
})format!(" {}", crate::roxygen::roxygen_line(&line)));
303 }
304 }
305 let ctor_mx_doc = ctx.choice_param_docs();
309 for param in ctx.params.split(", ").filter(|p| !p.is_empty()) {
310 let param_name = param.split('=').next().unwrap_or(param).trim();
311 if param_name == ".ptr" {
312 continue;
313 }
314 let already_documented =
315 crate::roxygen::param_documented(&ctx.method.doc_tags, param_name);
316 if !already_documented {
317 if class_param_names.contains(param_name) {
319 continue;
320 }
321 let body = ctor_mx_doc
325 .get(param_name)
326 .map(String::as_str)
327 .unwrap_or("(no documentation available)");
328 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" #\' @param {0} {1}",
param_name, body))
})format!(" #' @param {} {}", param_name, body));
329 }
330 }
331
332 let ctor_preconditions = ctx.precondition_checks();
334
335 let ctor_match_arg = ctx.match_arg_prelude();
338
339 let full_params = if ctx.params.is_empty() {
340 ".ptr = NULL".to_string()
341 } else {
342 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}, .ptr = NULL", ctx.params))
})format!("{}, .ptr = NULL", ctx.params)
343 };
344 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" initialize = function({0}) {{",
full_params))
})format!(" initialize = function({}) {{", full_params));
345 if !ctor_preconditions.is_empty() || !ctor_match_arg.is_empty() {
347 lines.push(" if (is.null(.ptr)) {".to_string());
348 for check in &ctor_preconditions {
349 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}", check))
})format!(" {}", check));
350 }
351 for line in &ctor_match_arg {
352 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}", line))
})format!(" {}", line));
353 }
354 lines.push(" }".to_string());
355 }
356 lines.push(" if (!is.null(.ptr)) {".to_string());
357 lines.push(" private$.ptr <- .ptr".to_string());
358 lines.push(" } else {".to_string());
359 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" .val <- {0}",
ctx.static_call()))
})format!(" .val <- {}", ctx.static_call()));
360 for check_line in crate::method_return_builder::condition_check_lines(" ") {
362 lines.push(check_line);
363 }
364 lines.push(" private$.ptr <- .val".to_string());
365 lines.push(" }".to_string());
366 lines.push(" }".to_string());
369 } else {
370 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" #\' @description `{0}` has no constructor: `$new()` only wraps the `.ptr` its factory functions pass.",
class_name))
})format!(
374 " #' @description `{class_name}` has no constructor: `$new()` only wraps \
375 the `.ptr` its factory functions pass."
376 ));
377 lines.push(" initialize = function(.ptr = NULL) {".to_string());
378 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}",
super::no_constructor_guard(&class_name)))
})format!(
379 " {}",
380 super::no_constructor_guard(&class_name)
381 ));
382 lines.push(" private$.ptr <- .ptr".to_string());
383 lines.push(" }".to_string());
384 }
385
386 lines.push(" ),".to_string());
387
388 lines.push(" private = list(".to_string());
391 lines.push(" .ptr = NULL".to_string());
392 lines.push(" ),".to_string());
393
394 let lock_objects = parsed_impl.r6_lock_objects.unwrap_or(true);
396 let lock_class = parsed_impl.r6_lock_class.unwrap_or(false);
397 let cloneable = parsed_impl.r6_cloneable.unwrap_or(false);
398 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" lock_objects = {0},",
if lock_objects { "TRUE" } else { "FALSE" }))
})format!(
399 " lock_objects = {},",
400 if lock_objects { "TRUE" } else { "FALSE" }
401 ));
402 lines.push(" lock_class = FALSE,".to_string());
411 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" cloneable = {0}",
if cloneable { "TRUE" } else { "FALSE" }))
})format!(
412 " cloneable = {}",
413 if cloneable { "TRUE" } else { "FALSE" }
414 ));
415 lines.push(")".to_string());
416 w.head = std::mem::take(&mut lines);
417
418 for ctx in parsed_impl.private_instance_method_contexts() {
423 let r_name = ctx.method.r_method_name();
424 w.member_names.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the R6 member `{0}`", r_name))
})format!("the R6 member `{r_name}`"));
425 lines.push(String::new());
426 lines.push(ctx.source_comment(type_ident));
427 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"private\", \"{1}\", function({2}) {{",
class_name, r_name, ctx.params))
})format!(
428 "{}$set(\"private\", \"{}\", function({}) {{",
429 class_name, r_name, ctx.params
430 ));
431
432 let what = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}${1}", class_name, r_name))
})format!("{}${}", class_name, r_name);
435 ctx.emit_method_prelude(&mut lines, " ", &what, &ctx.params);
436
437 let call = ctx.instance_call("private$.ptr");
438 let strategy = crate::ReturnStrategy::for_method(ctx.method);
439 let return_builder = crate::MethodReturnBuilder::new(call)
440 .with_strategy(strategy)
441 .with_invisible(ctx.method.is_invisible())
442 .with_class_name(class_name.clone())
443 .with_return_class_from_method(ctx.method, &type_ident.to_string())
444 .with_indent(2); lines.extend(return_builder.build_r6_body());
446
447 lines.push("})".to_string());
448 }
449
450 if let Some(finalizer) = parsed_impl.finalizer() {
452 w.member_names.push("the R6 member `finalize`".to_string());
453 let c_ident = finalizer.c_wrapper_ident(type_ident).to_string();
454 let finalize_call = crate::r_wrapper_builder::DotCallBuilder::new(&c_ident)
455 .null_call_attribution()
456 .with_self("private$.ptr")
457 .build();
458 lines.push(String::new());
459 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"private\", \"finalize\", function() {1})",
class_name, finalize_call))
})format!(
460 "{class_name}$set(\"private\", \"finalize\", function() {finalize_call})"
461 ));
462 }
463
464 if let Some(dc_method) = parsed_impl
466 .methods
467 .iter()
468 .find(|m| m.method_attrs.r6.deep_clone && m.should_include())
469 {
470 w.member_names
471 .push("the R6 member `deep_clone`".to_string());
472 let c_ident = dc_method.c_wrapper_ident(type_ident).to_string();
473 let deep_clone_call = crate::r_wrapper_builder::DotCallBuilder::new(&c_ident)
474 .null_call_attribution()
475 .with_self("private$.ptr")
476 .with_args(&["name", "value"])
477 .build();
478 lines.push(String::new());
479 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"private\", \"deep_clone\", function(name, value) {1})",
class_name, deep_clone_call))
})format!(
480 "{class_name}$set(\"private\", \"deep_clone\", function(name, value) {deep_clone_call})"
481 ));
482 }
483
484 let public_method_contexts: Vec<_> = parsed_impl.public_instance_method_contexts().collect();
489 for ctx in &public_method_contexts {
490 lines.push(String::new());
491 lines.push(ctx.source_comment(type_ident));
492 let r_name = ctx.method.r_method_name();
495 w.member_names.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the R6 member `{0}`", r_name))
})format!("the R6 member `{r_name}`"));
496 let has_description = ctx
497 .method
498 .doc_tags
499 .iter()
500 .any(|t| t.starts_with("@description ") || t.starts_with("@title "));
501 if !has_description {
502 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' @description Method `{0}`.",
r_name))
})format!("#' @description Method `{}`.", r_name));
503 }
504 for tag in &ctx.method.doc_tags {
509 if crate::roxygen::roxygen_tag_name(tag).is_some_and(|n| n == "rdname" || n == "name") {
510 continue;
511 }
512 for line in tag.lines() {
513 let line = if line.starts_with("@title ") {
514 line.replacen("@title ", "@description ", 1)
515 } else {
516 line.to_string()
517 };
518 lines.push(crate::roxygen::roxygen_line(&line));
519 }
520 }
521 let method_mx_doc = ctx.choice_param_docs();
527 let r_method_name = ctx.method.r_method_name();
528 for param in ctx.params.split(", ").filter(|p| !p.is_empty()) {
529 let param_name = param.split('=').next().unwrap_or(param).trim();
530 let already_documented =
531 crate::roxygen::param_documented(&ctx.method.doc_tags, param_name);
532 if !already_documented {
533 if class_param_names.contains(param_name) {
535 continue;
536 }
537 let body = method_mx_doc
538 .get(param_name)
539 .map(String::as_str)
540 .unwrap_or("(no documentation available)");
541 if let Some(ref parent) = parsed_impl.r6_inherit
545 && body == "(no documentation available)"
546 {
547 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' {0}class=\"{1}\", parent=\"{2}\", method=\"{3}\", param=\"{4}\")",
MX_INHERITED_PARAM_PREFIX, class_name, parent, r_method_name,
param_name))
})format!(
548 "#' {}class=\"{}\", parent=\"{}\", method=\"{}\", param=\"{}\")",
549 MX_INHERITED_PARAM_PREFIX, class_name, parent, r_method_name, param_name,
550 ));
551 } else {
552 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#\' @param {0} {1}", param_name,
body))
})format!("#' @param {} {}", param_name, body));
553 }
554 }
555 }
556 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"public\", \"{1}\", function({2}) {{",
class_name, r_name, ctx.params))
})format!(
557 "{}$set(\"public\", \"{}\", function({}) {{",
558 class_name, r_name, ctx.params
559 ));
560
561 let what = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}${1}", class_name, r_name))
})format!("{}${}", class_name, r_name);
562 ctx.emit_method_prelude(&mut lines, " ", &what, &ctx.params);
563
564 let call = ctx.instance_call("private$.ptr");
565 let strategy = crate::ReturnStrategy::for_method(ctx.method);
566 let return_builder = crate::MethodReturnBuilder::new(call)
567 .with_strategy(strategy)
568 .with_invisible(ctx.method.is_invisible())
569 .with_class_name(class_name.clone())
570 .with_return_class_from_method(ctx.method, &type_ident.to_string())
571 .with_indent(2); lines.extend(return_builder.build_r6_body());
573
574 lines.push("})".to_string());
575 }
576
577 for ctx in &active_method_contexts {
581 lines.push(String::new());
582
583 let prop_name = ctx
585 .method
586 .method_attrs
587 .r6
588 .prop
589 .clone()
590 .unwrap_or_else(|| ctx.method.r_method_name());
591 w.member_names.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the R6 member `{0}`", prop_name))
})format!("the R6 member `{prop_name}`"));
592
593 let setter = parsed_impl.find_setter_for_prop(&prop_name);
595
596 if let Some(setter_method) = setter {
597 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"active\", \"{1}\", function(value) {{",
class_name, prop_name))
})format!(
600 "{}$set(\"active\", \"{}\", function(value) {{",
601 class_name, prop_name
602 ));
603 lines.push(" if (missing(value)) {".to_string());
604
605 let getter_call = ctx.instance_call("private$.ptr");
608 let getter_strategy = crate::ReturnStrategy::for_method(ctx.method);
609 let getter_builder = crate::MethodReturnBuilder::new(getter_call)
610 .with_strategy(getter_strategy)
611 .with_invisible(ctx.method.is_invisible())
612 .with_class_name(class_name.clone())
613 .with_return_class_from_method(ctx.method, &type_ident.to_string())
614 .with_indent(4);
615 lines.extend(getter_builder.build_r6_body());
616
617 lines.push(" } else {".to_string());
618
619 for check in active_setter_precondition_checks(setter_method, parsed_impl.preconditions)
623 {
624 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" {0}", check))
})format!(" {}", check));
625 }
626
627 let setter_c_ident = setter_method.c_wrapper_ident(type_ident).to_string();
632 let setter_call = crate::r_wrapper_builder::DotCallBuilder::new(&setter_c_ident)
633 .with_self("private$.ptr")
634 .with_args(&["value"])
635 .build();
636 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" .val <- {0}", setter_call))
})format!(" .val <- {}", setter_call));
637 lines.extend(crate::method_return_builder::condition_check_lines(" "));
638 let invisible = setter_method
641 .visibility_marker
642 .or(setter_method.method_attrs.force_invisible)
643 .unwrap_or(true);
644 lines.push(
645 if invisible {
646 " invisible(self)"
647 } else {
648 " self"
649 }
650 .to_string(),
651 );
652
653 lines.push(" }".to_string());
654 lines.push("})".to_string());
655 } else {
656 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$set(\"active\", \"{1}\", function() {{",
class_name, prop_name))
})format!(
659 "{}$set(\"active\", \"{}\", function() {{",
660 class_name, prop_name
661 ));
662
663 let call = ctx.instance_call("private$.ptr");
664 let strategy = crate::ReturnStrategy::for_method(ctx.method);
665 let return_builder = crate::MethodReturnBuilder::new(call)
666 .with_strategy(strategy)
667 .with_invisible(ctx.method.is_invisible())
668 .with_class_name(class_name.clone())
669 .with_return_class_from_method(ctx.method, &type_ident.to_string())
670 .with_indent(2); lines.extend(return_builder.build_r6_body());
672
673 lines.push("})".to_string());
674 }
675 }
676
677 let class_has_no_rd = crate::roxygen::has_roxygen_tag(class_doc_tags, "noRd")
681 || (parsed_impl.noexport && !parsed_impl.internal);
682
683 for ctx in parsed_impl.static_method_contexts() {
685 let method_name = ctx.method.r_method_name();
686 w.member_names.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}${1}`", class_name,
method_name))
})format!("`{class_name}${method_name}`"));
687 let static_method_name =
689 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}${1}", class_name,
crate::naming::r_def_name(&method_name)))
})format!("{}${}", class_name, crate::naming::r_def_name(&method_name));
690 lines.push(String::new());
691
692 lines.push(ctx.source_comment(type_ident));
693 let doc_tags = parsed_impl.static_doc_tags(
694 ctx.method,
695 &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}${1}()", class_name,
method_name))
})format!("{class_name}${method_name}()"),
696 &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$new()", class_name))
})format!("{class_name}$new()"),
697 true,
698 );
699 let method_doc = MethodDocBuilder::new(&class_name, &method_name, type_ident, &doc_tags)
700 .with_source_method(&ctx.method.ident)
701 .with_name_prefix("$")
702 .with_class_no_rd(class_has_no_rd);
703 lines.extend(method_doc.build());
704
705 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} <- function({1}) {{",
static_method_name, ctx.params))
})format!(
706 "{} <- function({}) {{",
707 static_method_name, ctx.params
708 ));
709
710 let what = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}${1}", class_name, method_name))
})format!("{}${}", class_name, method_name);
711 ctx.emit_method_prelude(&mut lines, " ", &what, &ctx.params);
712
713 let strategy = crate::ReturnStrategy::for_method(ctx.method);
714 let return_builder = crate::MethodReturnBuilder::new(ctx.static_call())
715 .with_strategy(strategy)
716 .with_invisible(ctx.method.is_invisible())
717 .with_class_name(class_name.clone())
718 .with_return_class_from_method(ctx.method, &type_ident.to_string());
719 lines.extend(return_builder.build_r6_body());
720
721 lines.push("}".to_string());
722 }
723 w.members = std::mem::take(&mut lines);
724
725 if parsed_impl.r_data_accessors.enabled() {
727 let type_name = type_ident.to_string();
728 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!(".rdata_active_bindings_{0}({1})",
type_name, class_name))
})format!(
729 ".rdata_active_bindings_{}({})",
730 type_name, class_name
731 ));
732 }
733
734 if lock_class {
741 lines.push(String::new());
742 lines.push(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}$lock()", class_name))
})format!("{}$lock()", class_name));
743 }
744
745 w.tail = lines;
746 w
747}
748
749#[cfg(test)]
751pub fn generate_r6_r_wrapper(parsed_impl: &ParsedImpl) -> String {
752 generate_r6_class(parsed_impl).render()
753}