1use log::info;
2
3use super::{function_parameters::TransformationType, imports::Imports, *};
4use crate::{codegen::Visibility, config::gobjects::GObject, env::Env, nameutil::*, traits::*};
5
6#[derive(Debug, Default)]
7pub struct Info {
8 pub full_name: String,
9 pub type_id: library::TypeId,
10 pub name: String,
11 pub functions: Vec<functions::Info>,
12 pub specials: special_functions::Infos,
13 pub visibility: Visibility,
14}
15
16impl Info {
17 pub fn type_<'a>(&self, library: &'a library::Library) -> &'a library::Bitfield {
18 (library
19 .type_(self.type_id)
20 .maybe_ref()
21 .unwrap_or_else(|| panic!("{} is not an flags.", self.full_name))) as _
22 }
23}
24
25pub fn new(env: &Env, obj: &GObject, imports: &mut Imports) -> Option<Info> {
26 info!("Analyzing flags {}", obj.name);
27
28 if obj.status.ignored() {
29 return None;
30 }
31
32 let flags_tid = env.library.find_type(0, &obj.name)?;
33 let type_ = env.type_(flags_tid);
34 let flags: &library::Bitfield = type_.maybe_ref()?;
35
36 let name = split_namespace_name(&obj.name).1;
37
38 if obj.status.need_generate() {
39 imports.add_defined(&format!("crate::{name}"));
41 imports.add("crate::ffi");
42
43 let imports = &mut imports.with_defaults(flags.version, &None);
44 imports.add("glib::translate::*");
45 imports.add("glib::bitflags::bitflags");
46
47 let has_get_type = flags.glib_get_type.is_some();
48 if has_get_type {
49 imports.add("glib::prelude::*");
50 }
51 }
52
53 let mut functions = functions::analyze(
54 env,
55 &flags.functions,
56 Some(flags_tid),
57 false,
58 false,
59 obj,
60 imports,
61 None,
62 None,
63 );
64
65 for f in &mut functions {
69 if f.parameters.c_parameters.is_empty() {
70 continue;
71 }
72
73 let first_param = &mut f.parameters.c_parameters[0];
74
75 if first_param.typ == flags_tid {
76 first_param.instance_parameter = true;
77
78 let t = f
79 .parameters
80 .transformations
81 .iter_mut()
82 .find(|t| t.ind_c == 0)
83 .unwrap();
84
85 if let TransformationType::ToGlibScalar { name, .. } = &mut t.transformation_type {
86 *name = "self".to_owned();
87 } else {
88 panic!(
89 "Bitfield function instance param must be passed as scalar, not {:?}",
90 t.transformation_type
91 );
92 }
93 }
94 }
95
96 let specials = special_functions::extract(&mut functions, type_, obj);
97
98 if obj.status.need_generate() {
99 special_functions::analyze_imports(&specials, imports);
100 }
101
102 let info = Info {
103 full_name: obj.name.clone(),
104 type_id: flags_tid,
105 name: name.to_owned(),
106 functions,
107 specials,
108 visibility: obj.visibility,
109 };
110
111 Some(info)
112}