mago_analyzer/plugin/libraries/stdlib/string/
strlen.rs1use mago_codex::ttype::get_literal_int;
4use mago_codex::ttype::get_non_negative_int;
5use mago_codex::ttype::union::TUnion;
6
7use crate::plugin::context::InvocationInfo;
8use crate::plugin::context::ProviderContext;
9use crate::plugin::provider::Provider;
10use crate::plugin::provider::ProviderMeta;
11use crate::plugin::provider::function::FunctionReturnTypeProvider;
12use crate::plugin::provider::function::FunctionTarget;
13
14static META: ProviderMeta = ProviderMeta::new(
15 "php::string::strlen",
16 "strlen",
17 "Returns a non-negative integer, or a literal length for literal strings",
18);
19
20#[derive(Default)]
21pub struct StrlenProvider;
22
23impl Provider for StrlenProvider {
24 fn meta() -> &'static ProviderMeta {
25 &META
26 }
27}
28
29impl FunctionReturnTypeProvider for StrlenProvider {
30 fn targets() -> FunctionTarget {
31 FunctionTarget::Exact(b"strlen")
32 }
33
34 fn get_return_type(
35 &self,
36 context: &ProviderContext<'_, '_, '_>,
37 invocation: &InvocationInfo<'_, '_, '_>,
38 ) -> Option<TUnion> {
39 let string_argument = invocation.get_argument(0, &[b"string"])?;
40 let string_argument_type = context.get_expression_type(string_argument)?;
41 match string_argument_type.get_single_literal_string_value() {
42 Some(string_literal) => Some(get_literal_int(string_literal.len() as i64)),
43 None => Some(get_non_negative_int()),
44 }
45 }
46}