Skip to main content

mago_analyzer/plugin/hook/
call.rs

1//! Call hooks for function and method call events.
2
3use mago_syntax::cst::FunctionCall;
4use mago_syntax::cst::MethodCall;
5use mago_syntax::cst::NullSafeMethodCall;
6use mago_syntax::cst::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    ///
25    /// # Errors
26    ///
27    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
28    fn before_function_call(
29        &self,
30        _call: &FunctionCall<'_>,
31        _context: &mut HookContext<'_, '_>,
32    ) -> HookResult<ExpressionHookResult> {
33        Ok(ExpressionHookResult::Continue)
34    }
35
36    /// Called after a function call has been analyzed.
37    ///
38    /// # Errors
39    ///
40    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
41    fn after_function_call(&self, _call: &FunctionCall<'_>, _context: &mut HookContext<'_, '_>) -> HookResult<()> {
42        Ok(())
43    }
44}
45
46/// Hook trait for intercepting method call analysis.
47///
48/// This hook receives the real AST method call node and full mutable context,
49/// allowing hooks to inspect calls, report issues, modify analysis state,
50/// and optionally skip analysis with a custom return type.
51pub trait MethodCallHook: Provider {
52    /// Called before a method call is analyzed.
53    ///
54    /// Return `ExpressionHookResult::Continue` to proceed with normal analysis,
55    /// `ExpressionHookResult::Skip` to skip analysis (type will be `mixed`), or
56    /// `ExpressionHookResult::SkipWithType(ty)` to skip with a custom return type.
57    ///
58    /// # Errors
59    ///
60    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
61    fn before_method_call(
62        &self,
63        _call: &MethodCall<'_>,
64        _context: &mut HookContext<'_, '_>,
65    ) -> HookResult<ExpressionHookResult> {
66        Ok(ExpressionHookResult::Continue)
67    }
68
69    /// Called after a method call has been analyzed.
70    ///
71    /// # Errors
72    ///
73    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
74    fn after_method_call(&self, _call: &MethodCall<'_>, _context: &mut HookContext<'_, '_>) -> HookResult<()> {
75        Ok(())
76    }
77}
78
79/// Hook trait for intercepting static method call analysis.
80pub trait StaticMethodCallHook: Provider {
81    /// Called before a static method call is analyzed.
82    ///
83    /// # Errors
84    ///
85    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
86    fn before_static_method_call(
87        &self,
88        _call: &StaticMethodCall<'_>,
89        _context: &mut HookContext<'_, '_>,
90    ) -> HookResult<ExpressionHookResult> {
91        Ok(ExpressionHookResult::Continue)
92    }
93
94    /// Called after a static method call has been analyzed.
95    ///
96    /// # Errors
97    ///
98    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
99    fn after_static_method_call(
100        &self,
101        _call: &StaticMethodCall<'_>,
102        _context: &mut HookContext<'_, '_>,
103    ) -> HookResult<()> {
104        Ok(())
105    }
106}
107
108/// Hook trait for intercepting nullsafe method call analysis.
109pub trait NullSafeMethodCallHook: Provider {
110    /// Called before a nullsafe method call is analyzed.
111    ///
112    /// # Errors
113    ///
114    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
115    fn before_nullsafe_method_call(
116        &self,
117        _call: &NullSafeMethodCall<'_>,
118        _context: &mut HookContext<'_, '_>,
119    ) -> HookResult<ExpressionHookResult> {
120        Ok(ExpressionHookResult::Continue)
121    }
122
123    /// Called after a nullsafe method call has been analyzed.
124    ///
125    /// # Errors
126    ///
127    /// Returns [`HookError`] if the underlying plugin implementation propagates one.
128    fn after_nullsafe_method_call(
129        &self,
130        _call: &NullSafeMethodCall<'_>,
131        _context: &mut HookContext<'_, '_>,
132    ) -> HookResult<()> {
133        Ok(())
134    }
135}