Skip to main content

ktrs_compose/rules/
modifier_composed.rs

1//! Port of `rules/ModifierComposed.kt`.
2
3use ktrs_ast::Ast;
4use ktrs_ast::psi::{KtCallExpression, KtFunction, KtReturnExpression};
5
6use crate::core::compose_kt_config::ComposeKtConfig;
7use crate::core::compose_kt_visitor::ComposeKtVisitor;
8use crate::core::emitter::Emitter;
9use crate::core::util::kt_annotateds::is_composable;
10use crate::core::util::modifiers::is_modifier_receiver;
11use crate::core::util::psi_elements::find_direct_children_by_class;
12
13pub struct ModifierComposed;
14
15impl ComposeKtVisitor for ModifierComposed {
16    fn visit_function(&self, ast: &mut Ast, function: KtFunction, emitter: &mut dyn Emitter, config: &dyn ComposeKtConfig) {
17        if !is_modifier_receiver(ast, function.node(), config) || is_composable(ast, function.node()) {
18            return;
19        }
20        let is_composed_call = |ast: &Ast, call: KtCallExpression| {
21            call.callee_expression(ast).is_some_and(|c| ast.text(c) == "composed")
22        };
23        if function.body_expression(ast).and_then(|b| KtCallExpression::cast(ast, b)).is_some_and(|b| is_composed_call(ast, b)) {
24            emitter.report(ast, function.node(), COMPOSED_MODIFIER, false);
25        }
26        let Some(body_block_expression) = function.body_block_expression(ast) else { return };
27        let returns_composed = find_direct_children_by_class::<KtReturnExpression>(ast, body_block_expression.node())
28            .into_iter()
29            .filter_map(|it| it.returned_expression(ast))
30            .filter_map(|it| KtCallExpression::cast(ast, it))
31            .any(|it| is_composed_call(ast, it));
32        if returns_composed {
33            emitter.report(ast, function.node(), COMPOSED_MODIFIER, false);
34        }
35    }
36}
37
38pub const COMPOSED_MODIFIER: &str = "\
39Using composed for modifiers is not recommended anymore, due to the performance issues it creates.
40You should consider migrating this modifier to be based on Modifier.Node instead.
41See https://mrmans0n.github.io/compose-rules/rules/#avoid-modifier-extension-factory-functions for more information.";