Skip to main content

mago_analyzer/plugin/libraries/stdlib/reflection/
method_get_name.rs

1//! `ReflectionMethod<T>::getName()` return type provider.
2
3use mago_codex::ttype::union::TUnion;
4
5use crate::plugin::context::InvocationInfo;
6use crate::plugin::context::ProviderContext;
7use crate::plugin::provider::Provider;
8use crate::plugin::provider::ProviderMeta;
9use crate::plugin::provider::method::MethodReturnTypeProvider;
10use crate::plugin::provider::method::MethodTarget;
11
12static META: ProviderMeta = ProviderMeta::new(
13    "reflection::method::get_name",
14    "ReflectionMethod::getName",
15    "Returns the union of method names of the reflected class",
16);
17
18static TARGETS: [MethodTarget; 1] = [MethodTarget::any_class(b"getName")];
19
20/// Provider for `ReflectionMethod<T>::getName()`.
21///
22/// A `ReflectionMethod<T>` obtained from `getMethods()`/`getMethod()` does not
23/// track *which* method it is, so `getName()` returns the union of every method
24/// name on `T` (e.g. `'greet'|'count'`) instead of a plain `string`. This lets
25/// dynamic dispatch like `$object->{$method->getName()}()` resolve.
26#[derive(Default)]
27pub struct ReflectionMethodGetNameProvider;
28
29impl Provider for ReflectionMethodGetNameProvider {
30    fn meta() -> &'static ProviderMeta {
31        &META
32    }
33}
34
35impl MethodReturnTypeProvider for ReflectionMethodGetNameProvider {
36    fn targets() -> &'static [MethodTarget] {
37        &TARGETS
38    }
39
40    fn get_return_type(
41        &self,
42        context: &ProviderContext<'_, '_, '_>,
43        _class_name: &[u8],
44        _method_name: &[u8],
45        invocation: &InvocationInfo<'_, '_, '_>,
46    ) -> Option<TUnion> {
47        let reflected_class = super::reflected_class_name(context, invocation, b"ReflectionMethod")?;
48
49        super::method_name_union(context.codebase(), reflected_class)
50    }
51}