diff --git a/gtk/src/subclass/scrolled_window.rs b/gtk/src/subclass/scrolled_window.rs index 1e94a362a778..385e542a4cfa 100644 --- a/gtk/src/subclass/scrolled_window.rs +++ b/gtk/src/subclass/scrolled_window.rs @@ -71,6 +71,10 @@ unsafe impl IsSubclassable for ScrolledWindow { fn class_init(class: &mut ::glib::Class) { Self::parent_class_init::(class); + if !crate::rt::is_initialized() { + panic!("GTK has to be initialized first"); + } + let klass = class.as_mut(); klass.move_focus_out = Some(window_move_focus_out::); klass.scroll_child = Some(window_scroll_child::); diff --git a/gtk/tests/check_subclass_panic.rs b/gtk/tests/check_subclass_panic.rs new file mode 100644 index 000000000000..f9e0220e8ac0 --- /dev/null +++ b/gtk/tests/check_subclass_panic.rs @@ -0,0 +1,69 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +// We want to ensure that all subclasses have: +// +// ``` +// if !crate::rt::is_initialized() { +// panic!("GTK has to be initialized first"); +// } +// ``` + +use std::fs::{read_dir, read_to_string}; +use std::path::Path; + +fn check_file(f: &Path) -> usize { + let s = read_to_string(f).expect("cannot read file"); + let mut checking_type: Option = None; + let mut found_is_initialized_check = false; + + for line in s.lines() { + if checking_type.is_none() { + if !line.starts_with("unsafe impl") || !line.contains(" IsSubclassable<") { + continue; + } + if let Some(for_) = line.split(" for ").nth(1).and_then(|s| s.split(' ').next()) { + checking_type = Some(for_.to_owned()); + } + continue; + } + if line == "}" { + // Analysis complete! + break; + } + let trimmed = line.trim(); + if trimmed.contains("is_initialized()") { + found_is_initialized_check = true; + } + } + if !found_is_initialized_check { + if let Some(for_) = checking_type { + if for_ == "Application" { + return 0; + } + eprintln!( + "[{}] Missing `is_initialized()` check in subclass implementation (`{}`)", + f.display(), + for_ + ); + 1 + } else { + 0 + } + } else { + 0 + } +} + +#[test] +fn check_subclass_panic() { + let mut errors = 0; + + for entry in read_dir("src/subclass").unwrap() { + let entry = entry.expect("invalid entry"); + let path = entry.path(); + if path.is_file() { + errors += check_file(&path); + } + } + assert!(errors == 0); +}