Skip to main content

ktrs_compose/rules/
composition_local_allowlist.rs

1//! Port of `rules/CompositionLocalAllowlist.kt`.
2
3use ktrs_ast::Ast;
4use ktrs_ast::psi::{KtFile, KtProperty};
5
6use crate::core::compose_kt_config::ComposeKtConfig;
7use crate::core::compose_kt_visitor::ComposeKtVisitor;
8use crate::core::emitter::Emitter;
9use crate::core::util::composables::declares_composition_local;
10use crate::core::util::psi_elements::find_all_children;
11
12pub struct CompositionLocalAllowlist;
13
14impl ComposeKtVisitor for CompositionLocalAllowlist {
15    fn visit_file(&self, ast: &mut Ast, file: KtFile, emitter: &mut dyn Emitter, config: &dyn ComposeKtConfig) {
16        let composition_locals: Vec<KtProperty> = find_all_children::<KtProperty>(ast, file.node())
17            .into_iter()
18            .filter(|it| declares_composition_local(ast, *it))
19            .collect();
20        if composition_locals.is_empty() {
21            return;
22        }
23        let allowed = config.get_set("allowedCompositionLocals", &[]);
24        let not_allowed: Vec<KtProperty> = composition_locals
25            .into_iter()
26            .filter(|it| !it.name_identifier(ast).is_some_and(|n| allowed.contains(&ast.text(n))))
27            .collect();
28        for composition_local in not_allowed {
29            emitter.report(ast, composition_local.node(), COMPOSITION_LOCAL_NOT_IN_ALLOWLIST, false);
30        }
31    }
32}
33
34pub const COMPOSITION_LOCAL_NOT_IN_ALLOWLIST: &str = "\
35CompositionLocals are implicit dependencies and creating new ones should be avoided.
36See https://mrmans0n.github.io/compose-rules/rules/#compositionlocals for more information.";