libgir/analysis/
signals.rs1use super::{imports::Imports, trampolines};
2use crate::{
3 analysis::trampolines::Trampoline,
4 config::{self, gobjects::GObject},
5 env::Env,
6 library, nameutil,
7 traits::*,
8 version::Version,
9};
10
11#[derive(Debug)]
12pub struct Info {
13 pub connect_name: String,
14 pub signal_name: String,
15 pub action_emit_name: Option<String>,
16 pub trampoline: Result<Trampoline, Vec<String>>,
17 pub version: Option<Version>,
18 pub deprecated_version: Option<Version>,
19 pub doc_hidden: bool,
20 pub is_detailed: bool,
21 pub generate_doc: bool,
22 pub cfg_condition: Option<String>,
23}
24
25pub fn analyze(
26 env: &Env,
27 signals: &[library::Signal],
28 type_tid: library::TypeId,
29 in_trait: bool,
30 is_fundamental: bool,
31 obj: &GObject,
32 imports: &mut Imports,
33) -> Vec<Info> {
34 let mut sns = Vec::new();
35
36 for signal in signals {
37 let configured_signals = obj.signals.matched(&signal.name);
38 if !configured_signals.iter().all(|f| f.status.need_generate()) {
39 continue;
40 }
41 if env.is_totally_deprecated(Some(type_tid.ns_id), signal.deprecated_version) {
42 continue;
43 }
44
45 let info = analyze_signal(
46 env,
47 signal,
48 type_tid,
49 in_trait,
50 is_fundamental,
51 &configured_signals,
52 obj,
53 imports,
54 );
55 sns.push(info);
56 }
57
58 sns
59}
60
61fn analyze_signal(
62 env: &Env,
63 signal: &library::Signal,
64 type_tid: library::TypeId,
65 in_trait: bool,
66 is_fundamental: bool,
67 configured_signals: &[&config::signals::Signal],
68 obj: &GObject,
69 imports: &mut Imports,
70) -> Info {
71 let mut used_types: Vec<String> = Vec::with_capacity(4);
72 let version = configured_signals
73 .iter()
74 .filter_map(|f| f.version)
75 .min()
76 .or(signal.version);
77 let cfg_condition = configured_signals
78 .iter()
79 .find_map(|s| s.cfg_condition.clone());
80 let deprecated_version = signal.deprecated_version;
81 let doc_hidden = configured_signals.iter().any(|f| f.doc_hidden);
82
83 let imports = &mut imports.with_defaults(version, &None);
84 imports.add("glib::translate::*");
85
86 let connect_name = format!("connect_{}", nameutil::signal_to_snake(&signal.name));
87 let trampoline = trampolines::analyze(
88 env,
89 signal,
90 type_tid,
91 in_trait,
92 is_fundamental,
93 configured_signals,
94 obj,
95 &mut used_types,
96 version,
97 );
98
99 let action_emit_name = if signal.is_action {
100 imports.add("glib::prelude::*");
101 Some(format!("emit_{}", nameutil::signal_to_snake(&signal.name)))
102 } else {
103 None
104 };
105
106 if trampoline.is_ok() {
107 imports.add_used_types(&used_types);
108 imports.add("glib::prelude::*");
109 imports.add("glib::object::ObjectType as _");
110 imports.add("glib::signal::{connect_raw, SignalHandlerId}");
111 imports.add("std::boxed::Box as Box_");
112 }
113 let generate_doc = configured_signals.iter().all(|f| f.generate_doc);
114
115 Info {
116 connect_name,
117 signal_name: signal.name.clone(),
118 trampoline,
119 action_emit_name,
120 version,
121 deprecated_version,
122 doc_hidden,
123 is_detailed: signal.is_detailed,
124 generate_doc,
125 cfg_condition,
126 }
127}