Skip to main content

mago_codex/ttype/
shared.rs

1//! A collection of shared, static, and lazily-initialized `TAtomic` types.
2//!
3//! This module provides canonical, reusable instances for common PHP types.
4//! Using these constants avoids repeated allocations for frequently used types.
5
6use std::sync::LazyLock;
7
8use mago_atom::empty_atom;
9
10use crate::ttype::atomic::TAtomic;
11use crate::ttype::atomic::array::TArray;
12use crate::ttype::atomic::array::keyed::TKeyedArray;
13use crate::ttype::atomic::callable::TCallable;
14use crate::ttype::atomic::callable::TCallableSignature;
15use crate::ttype::atomic::iterable::TIterable;
16use crate::ttype::atomic::mixed::TMixed;
17use crate::ttype::atomic::object::TObject;
18use crate::ttype::atomic::resource::TResource;
19use crate::ttype::atomic::scalar::TScalar;
20use crate::ttype::atomic::scalar::int::TInteger;
21use crate::ttype::atomic::scalar::string::TString;
22use crate::ttype::atomic::scalar::string::TStringLiteral;
23use crate::ttype::get_arraykey;
24use crate::ttype::get_mixed;
25
26/// A static `TAtomic` representing the integer literal `1`.
27pub const ONE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::literal_int(1));
28/// A static `TAtomic` representing the integer literal `0`.
29pub const ZERO_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::literal_int(0));
30/// A static `TAtomic` representing the integer literal `-1`.
31pub const MINUS_ONE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::literal_int(-1));
32/// A static `TAtomic` representing the general `int` type.
33pub const INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::int());
34/// A static `TAtomic` representing a positive integer (`positive-int` or `int<1, max>`).
35pub const POSITIVE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Integer(TInteger::positive()));
36/// A static `TAtomic` representing a non-positive integer (`non-positive-int` or `int<min, 0>`).
37pub const NON_POSITIVE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Integer(TInteger::non_positive()));
38/// A static `TAtomic` representing a negative integer (`negative-int` or `int<min, -1>`).
39pub const NEGATIVE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Integer(TInteger::negative()));
40/// A static `TAtomic` representing a non-negative integer (`non-negative-int` or `int<0, max>`).
41pub const NON_NEGATIVE_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Integer(TInteger::non_negative()));
42/// A static `TAtomic` representing a `literal-int` where the value is unknown.
43pub const UNSPECIFIED_LITERAL_INT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Integer(TInteger::UnspecifiedLiteral));
44/// A static `TAtomic` for the general `string` type.
45pub const STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::String(TString::new(None, false, false, false, false)));
46/// A static `TAtomic` for a `lowercase-string`.
47pub const LOWERCASE_STRING_ATOMIC: &TAtomic =
48    &TAtomic::Scalar(TScalar::String(TString::new(None, false, false, false, true)));
49/// A static `TAtomic` for a `non-empty-string`.
50pub const NON_EMPTY_STRING_ATOMIC: &TAtomic =
51    &TAtomic::Scalar(TScalar::String(TString::new(None, false, false, true, false)));
52/// A static `TAtomic` for a `non-empty-lowercase-string`.
53pub const NON_EMPTY_LOWERCASE_STRING_ATOMIC: &TAtomic =
54    &TAtomic::Scalar(TScalar::String(TString::new(None, false, false, true, true)));
55/// A static `TAtomic` for a `truthy-string`.
56pub const TRUTHY_STRING_ATOMIC: &TAtomic =
57    &TAtomic::Scalar(TScalar::String(TString::new(None, false, true, false, false)));
58/// A static `TAtomic` for a `truthy-lowercase-string`.
59pub const TRUTHY_LOWERCASE_STRING_ATOMIC: &TAtomic =
60    &TAtomic::Scalar(TScalar::String(TString::new(None, false, true, false, true)));
61/// A static `TAtomic` for a `numeric-string`.
62pub const NUMERIC_STRING_ATOMIC: &TAtomic =
63    &TAtomic::Scalar(TScalar::String(TString::new(None, true, false, false, false)));
64/// A static `TAtomic` for a `numeric-string` that is also `truthy`.
65pub const NUMERIC_TRUTHY_STRING_ATOMIC: &TAtomic =
66    &TAtomic::Scalar(TScalar::String(TString::new(None, true, true, false, false)));
67/// A static `TAtomic` representing the `class-string` type.
68pub const CLASS_STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::class_string());
69/// A static `TAtomic` representing the `interface-string` type.
70pub const INTERFACE_STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::interface_string());
71/// A static `TAtomic` representing the `enum-string` type.
72pub const ENUM_STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::enum_string());
73/// A static `TAtomic` representing the `trait-string` type.
74pub const TRAIT_STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::trait_string());
75/// A static `TAtomic` representing the `float` type.
76pub const FLOAT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::float());
77/// A static `TAtomic` representing the `literal-float` type (unspecified literal).
78pub const UNSPECIFIED_LITERAL_FLOAT_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::unspecified_literal_float());
79/// A static `TAtomic` representing the `mixed` type.
80pub const MIXED_ATOMIC: &TAtomic = &TAtomic::Mixed(TMixed::new());
81/// A static `TAtomic` representing a `mixed` type that originates from an `isset()` check inside a loop.
82pub const ISSET_FROM_LOOP_MIXED_ATOMIC: &TAtomic = &TAtomic::Mixed(TMixed::isset_from_loop());
83/// A static `TAtomic` representing the `never` type, which indicates an impossible state.
84pub const NEVER_ATOMIC: &TAtomic = &TAtomic::Never;
85/// A static `TAtomic` representing any value that is not `null`.
86pub const NON_NULL_ATOMIC: &TAtomic = &TAtomic::Mixed(TMixed::non_null());
87/// A static `TAtomic` representing any "falsy" value (e.g., `false`, `0`, `""`, `[]`).
88pub const FALSY_MIXED_ATOMIC: &TAtomic = &TAtomic::Mixed(TMixed::falsy());
89/// A static `TAtomic` representing any "truthy" value.
90pub const TRUTHY_MIXED_ATOMIC: &TAtomic = &TAtomic::Mixed(TMixed::truthy());
91/// A static `TAtomic` representing the `resource` type.
92pub const RESOURCE_ATOMIC: &TAtomic = &TAtomic::Resource(TResource::new(None));
93/// A static `TAtomic` representing an open `resource`.
94pub const OPEN_RESOURCE_ATOMIC: &TAtomic = &TAtomic::Resource(TResource::open());
95/// A static `TAtomic` representing a closed `resource`.
96pub const CLOSED_RESOURCE_ATOMIC: &TAtomic = &TAtomic::Resource(TResource::closed());
97/// A static `TAtomic` used as a temporary placeholder during type reconciliation.
98pub const PLACEHOLDER_ATOMIC: &TAtomic = &TAtomic::Placeholder;
99/// A static `TAtomic` representing the `void` type.
100pub const VOID_ATOMIC: &TAtomic = &TAtomic::Void;
101/// A static `TAtomic` representing the `null` type.
102pub const NULL_ATOMIC: &TAtomic = &TAtomic::Null;
103/// A static `TAtomic` representing the `array-key` type (`int|string`).
104pub const ARRAYKEY_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::ArrayKey);
105/// A static `TAtomic` representing the `bool` type.
106pub const BOOL_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::bool());
107/// A static `TAtomic` representing the literal `false` type.
108pub const FALSE_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::r#false());
109/// A static `TAtomic` representing the literal `true` type.
110pub const TRUE_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::r#true());
111/// A static `TAtomic` representing the general `object` type.
112pub const OBJECT_ATOMIC: &TAtomic = &TAtomic::Object(TObject::Any);
113/// A static `TAtomic` representing the `numeric` type (`int|float|numeric-string`).
114pub const NUMERIC_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Numeric);
115/// A static `TAtomic` representing an empty string literal (`""`).
116pub static EMPTY_STRING_ATOMIC: LazyLock<TAtomic> = LazyLock::new(|| {
117    TAtomic::Scalar(TScalar::String(TString {
118        literal: Some(TStringLiteral::Value(empty_atom())),
119        is_numeric: false,
120        is_truthy: false,
121        is_non_empty: false,
122        is_lowercase: false,
123    }))
124});
125/// A static `TAtomic` representing a `literal-string` where the value is unknown.
126pub const UNSPECIFIED_LITERAL_STRING_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::unspecified_literal_string(false));
127/// A static `TAtomic` representing a non-empty `literal-string` where the value is unknown.
128pub const NON_EMPTY_UNSPECIFIED_LITERAL_STRING_ATOMIC: &TAtomic =
129    &TAtomic::Scalar(TScalar::unspecified_literal_string(true));
130/// A static `TAtomic` representing the `scalar` type (`int|float|string|bool`).
131pub const SCALAR_ATOMIC: &TAtomic = &TAtomic::Scalar(TScalar::Generic);
132
133/// A lazily-initialized static `TAtomic` for a mixed iterable (`iterable<mixed, mixed>`).
134pub static MIXED_ITERABLE_ATOMIC: LazyLock<TAtomic> = LazyLock::new(|| {
135    TAtomic::Iterable(TIterable {
136        key_type: Box::new(get_mixed()),
137        value_type: Box::new(get_mixed()),
138        intersection_types: None,
139    })
140});
141
142/// A lazily-initialized static `TAtomic` for an empty array (`array<never, never>`).
143pub static EMPTY_KEYED_ARRAY_ATOMIC: LazyLock<TAtomic> =
144    LazyLock::new(|| TAtomic::Array(TArray::Keyed(TKeyedArray::new())));
145/// A lazily-initialized static `TAtomic` for a mixed array (`array<array-key, mixed>`).
146pub static MIXED_KEYED_ARRAY_ATOMIC: LazyLock<TAtomic> = LazyLock::new(|| {
147    TAtomic::Array(TArray::Keyed(TKeyedArray::new_with_parameters(Box::new(get_arraykey()), Box::new(get_mixed()))))
148});
149/// A lazily-initialized static `TAtomic` for a mixed callable (`callable`).
150pub static MIXED_CALLABLE_ATOMIC: LazyLock<TAtomic> =
151    LazyLock::new(|| TAtomic::Callable(TCallable::Signature(TCallableSignature::mixed(false))));
152/// A lazily-initialized static `TAtomic` for a mixed closure (`Closure`).
153pub static MIXED_CLOSURE_ATOMIC: LazyLock<TAtomic> =
154    LazyLock::new(|| TAtomic::Callable(TCallable::Signature(TCallableSignature::mixed(true))));
155
156/// A static slice of atomics representing the union type `int|float`.
157pub const INT_FLOAT_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Scalar(TScalar::int()), TAtomic::Scalar(TScalar::float())];
158/// A static slice of atomics representing the union type `int|string`.
159pub const INT_STRING_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Scalar(TScalar::int()), TAtomic::Scalar(TScalar::string())];
160/// A static slice of atomics representing the union type `null|scalar`.
161pub const NULL_SCALAR_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Null, TAtomic::Scalar(TScalar::Generic)];
162/// A static slice of atomics representing the union type `null|string`.
163pub const NULL_STRING_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Null, TAtomic::Scalar(TScalar::string())];
164/// A static slice of atomics representing the union type `null|int`.
165pub const NULL_INT_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Null, TAtomic::Scalar(TScalar::int())];
166/// A static slice of atomics representing the union type `null|float`.
167pub const NULL_FLOAT_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Null, TAtomic::Scalar(TScalar::float())];
168/// A static slice of atomics representing the union type `null|object`.
169pub const NULL_OBJECT_ATOMIC_SLICE: &[TAtomic] = &[TAtomic::Null, TAtomic::Object(TObject::Any)];
170
171/// A static slice of atomics representing the union type `-1|0|1`, commonly
172/// returned by comparison operations like the spaceship operator (`<=>`).
173pub const SIGNUM_RESULT_SLICE: &[TAtomic] = &[
174    TAtomic::Scalar(TScalar::literal_int(-1)),
175    TAtomic::Scalar(TScalar::literal_int(0)),
176    TAtomic::Scalar(TScalar::literal_int(1)),
177];