Skip to main content

gobject_linter/rules/
signal_enum_coverage.rs

1use gobject_ast::model::{EnumInfo, FileModel};
2
3use crate::{
4    ast_context::AstContext,
5    config::Config,
6    rules::{Rule, Violation},
7};
8
9pub struct SignalEnumCoverage;
10
11impl Rule for SignalEnumCoverage {
12    fn name(&self) -> &'static str {
13        "signal_enum_coverage"
14    }
15
16    fn description(&self) -> &'static str {
17        "Ensure all signal enum values have corresponding g_signal_new calls"
18    }
19
20    fn category(&self) -> crate::rules::Category {
21        crate::rules::Category::Correctness
22    }
23
24    fn check_enum(
25        &self,
26        _ast_context: &AstContext,
27        _config: &Config,
28        enum_info: &EnumInfo,
29        file: &FileModel,
30        violations: &mut Vec<Violation>,
31    ) {
32        if !enum_info.is_signal_enum() {
33            return;
34        }
35
36        let signal_values: Vec<&str> = enum_info
37            .values
38            .iter()
39            .filter(|v| !v.is_signal_last())
40            .map(|v| v.name.as_str())
41            .collect();
42
43        if signal_values.is_empty() {
44            return;
45        }
46
47        let Some(gobject_type) = file.find_gobject_type_for_signal_enum(enum_info) else {
48            return;
49        };
50
51        let installed: std::collections::HashSet<&str> = gobject_type
52            .signals
53            .iter()
54            .filter_map(|s| s.enum_value.as_deref())
55            .collect();
56
57        for signal_name in &signal_values {
58            if !installed.contains(signal_name) {
59                violations.push(self.violation(
60                    &file.path,
61                    enum_info.location.line,
62                    1,
63                    format!(
64                        "Signal enum value '{}' is declared but never installed in {}",
65                        signal_name,
66                        gobject_type.class_init_function_name()
67                    ),
68                ));
69            }
70        }
71    }
72}