Skip to main content

mago_analyzer/plugin/hook/
call.rs

1//! Call hooks for function and method call events.
2
3use mago_syntax::ast::FunctionCall;
4use mago_syntax::ast::MethodCall;
5use mago_syntax::ast::NullSafeMethodCall;
6use mago_syntax::ast::StaticMethodCall;
7
8use crate::plugin::context::HookContext;
9use crate::plugin::hook::ExpressionHookResult;
10use crate::plugin::hook::HookResult;
11use crate::plugin::provider::Provider;
12
13/// Hook trait for intercepting function call analysis.
14///
15/// This hook receives the real AST function call node and full mutable context,
16/// allowing hooks to inspect calls, report issues, modify analysis state,
17/// and optionally skip analysis with a custom return type.
18pub trait FunctionCallHook: Provider {
19    /// Called before a function call is analyzed.
20    ///
21    /// Return `ExpressionHookResult::Continue` to proceed with normal analysis,
22    /// `ExpressionHookResult::Skip` to skip analysis (type will be `mixed`), or
23    /// `ExpressionHookResult::SkipWithType(ty)` to skip with a custom return type.
24    fn before_function_call(
25        &self,
26        _call: &FunctionCall<'_>,
27        _context: &mut HookContext<'_, '_>,
28    ) -> HookResult<ExpressionHookResult> {
29        Ok(ExpressionHookResult::Continue)
30    }
31
32    /// Called after a function call has been analyzed.
33    fn after_function_call(&self, _call: &FunctionCall<'_>, _context: &mut HookContext<'_, '_>) -> HookResult<()> {
34        Ok(())
35    }
36}
37
38/// Hook trait for intercepting method call analysis.
39///
40/// This hook receives the real AST method call node and full mutable context,
41/// allowing hooks to inspect calls, report issues, modify analysis state,
42/// and optionally skip analysis with a custom return type.
43pub trait MethodCallHook: Provider {
44    /// Called before a method call is analyzed.
45    ///
46    /// Return `ExpressionHookResult::Continue` to proceed with normal analysis,
47    /// `ExpressionHookResult::Skip` to skip analysis (type will be `mixed`), or
48    /// `ExpressionHookResult::SkipWithType(ty)` to skip with a custom return type.
49    fn before_method_call(
50        &self,
51        _call: &MethodCall<'_>,
52        _context: &mut HookContext<'_, '_>,
53    ) -> HookResult<ExpressionHookResult> {
54        Ok(ExpressionHookResult::Continue)
55    }
56
57    /// Called after a method call has been analyzed.
58    fn after_method_call(&self, _call: &MethodCall<'_>, _context: &mut HookContext<'_, '_>) -> HookResult<()> {
59        Ok(())
60    }
61}
62
63/// Hook trait for intercepting static method call analysis.
64pub trait StaticMethodCallHook: Provider {
65    /// Called before a static method call is analyzed.
66    fn before_static_method_call(
67        &self,
68        _call: &StaticMethodCall<'_>,
69        _context: &mut HookContext<'_, '_>,
70    ) -> HookResult<ExpressionHookResult> {
71        Ok(ExpressionHookResult::Continue)
72    }
73
74    /// Called after a static method call has been analyzed.
75    fn after_static_method_call(
76        &self,
77        _call: &StaticMethodCall<'_>,
78        _context: &mut HookContext<'_, '_>,
79    ) -> HookResult<()> {
80        Ok(())
81    }
82}
83
84/// Hook trait for intercepting nullsafe method call analysis.
85pub trait NullSafeMethodCallHook: Provider {
86    /// Called before a nullsafe method call is analyzed.
87    fn before_nullsafe_method_call(
88        &self,
89        _call: &NullSafeMethodCall<'_>,
90        _context: &mut HookContext<'_, '_>,
91    ) -> HookResult<ExpressionHookResult> {
92        Ok(ExpressionHookResult::Continue)
93    }
94
95    /// Called after a nullsafe method call has been analyzed.
96    fn after_nullsafe_method_call(
97        &self,
98        _call: &NullSafeMethodCall<'_>,
99        _context: &mut HookContext<'_, '_>,
100    ) -> HookResult<()> {
101        Ok(())
102    }
103}