1use serde::Deserialize;
2use serde::Serialize;
3use strum::Display;
4
5use mago_database::file::FileId;
6use mago_span::Position;
7use mago_span::Span;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
18pub enum TypePrecedence {
19 Lowest,
21 Conditional,
23 Union,
25 Intersection,
27 Postfix,
29 Callable,
31}
32
33#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
34pub enum TypeTokenKind {
35 Int,
36 Integer,
37 String,
38 Float,
39 Real,
40 Double,
41 Bool,
42 Boolean,
43 False,
44 True,
45 Object,
46 Callable,
47 Array,
48 NonEmptyArray,
49 CallableString,
50 LowercaseCallableString,
51 UppercaseCallableString,
52 NonEmptyString,
53 NonEmptyLowercaseString,
54 NonEmptyUppercaseString,
55 NonFalsyString,
56 LowercaseString,
57 UppercaseString,
58 TruthyString,
59 Iterable,
60 Null,
61 Mixed,
62 NonEmptyMixed,
63 NumericString,
64 ClassString,
65 InterfaceString,
66 TraitString,
67 EnumString,
68 StringableObject,
69 PureCallable,
70 PureClosure,
71 UnspecifiedLiteralString,
72 UnspecifiedLiteralInt,
73 UnspecifiedLiteralFloat,
74 NonEmptyUnspecifiedLiteralString,
75 Resource,
76 Void,
77 Scalar,
78 Numeric,
79 NoReturn,
80 NeverReturn,
81 NeverReturns,
82 Never,
83 Nothing,
84 ArrayKey,
85 List,
86 NonEmptyList,
87 OpenResource,
88 ClosedResource,
89 AssociativeArray,
90 KeyOf,
91 ValueOf,
92 IntMask,
93 IntMaskOf,
94 New,
95 TemplateType,
96 Min,
97 Max,
98 PropertiesOf,
99 PublicPropertiesOf,
100 PrivatePropertiesOf,
101 ProtectedPropertiesOf,
102 PositiveInt,
103 NegativeInt,
104 NonPositiveInt,
105 NonNegativeInt,
106 NonZeroInt,
107 As,
108 Is,
109 Not,
110 Identifier,
111 QualifiedIdentifier,
112 FullyQualifiedIdentifier,
113 Plus,
114 Minus,
115 LessThan,
116 GreaterThan,
117 Pipe,
118 Ampersand,
119 Question,
120 Exclamation,
121 Comma,
122 Colon,
123 ColonColon,
124 LeftBrace,
125 RightBrace,
126 LeftBracket,
127 RightBracket,
128 LeftParenthesis,
129 RightParenthesis,
130 Equals,
131 Ellipsis,
132 PartialLiteralString,
133 LiteralString,
134 LiteralInteger,
135 LiteralFloat,
136 Variable,
137 Whitespace,
138 SingleLineComment,
139 Asterisk,
140}
141
142#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
143pub struct TypeToken<'input> {
144 pub kind: TypeTokenKind,
145 pub start: Position,
146 pub value: &'input str,
147}
148
149impl<'input> TypeToken<'input> {
150 #[inline]
152 #[must_use]
153 pub const fn new(kind: TypeTokenKind, value: &'input str, start: Position) -> Self {
154 Self { kind, start, value }
155 }
156
157 #[inline]
159 #[must_use]
160 pub const fn end(&self) -> Position {
161 Position::new(self.start.offset + self.value.len() as u32)
162 }
163
164 #[inline]
166 #[must_use]
167 pub const fn span_for(&self, file_id: FileId) -> Span {
168 Span::new(file_id, self.start, self.end())
169 }
170}
171
172impl TypeTokenKind {
173 #[inline]
174 #[must_use]
175 pub const fn is_trivia(&self) -> bool {
176 matches!(self, Self::SingleLineComment | Self::Whitespace)
177 }
178
179 #[inline]
180 #[must_use]
181 pub const fn is_simple_identifier(&self) -> bool {
182 matches!(self, Self::Identifier)
183 }
184
185 #[inline]
186 #[must_use]
187 pub const fn is_identifier(&self) -> bool {
188 matches!(self, Self::Identifier | Self::QualifiedIdentifier | Self::FullyQualifiedIdentifier)
189 }
190
191 #[inline]
192 #[must_use]
193 pub const fn is_keyword(&self) -> bool {
194 matches!(
195 self,
196 Self::Int
197 | Self::Integer
198 | Self::Double
199 | Self::String
200 | Self::Float
201 | Self::Real
202 | Self::Bool
203 | Self::Boolean
204 | Self::False
205 | Self::True
206 | Self::Object
207 | Self::Callable
208 | Self::Array
209 | Self::NonEmptyArray
210 | Self::CallableString
211 | Self::LowercaseCallableString
212 | Self::UppercaseCallableString
213 | Self::NonEmptyString
214 | Self::NonEmptyLowercaseString
215 | Self::LowercaseString
216 | Self::NonEmptyUppercaseString
217 | Self::UppercaseString
218 | Self::TruthyString
219 | Self::NonFalsyString
220 | Self::Iterable
221 | Self::Null
222 | Self::Mixed
223 | Self::NonEmptyMixed
224 | Self::NumericString
225 | Self::ClassString
226 | Self::InterfaceString
227 | Self::TraitString
228 | Self::EnumString
229 | Self::StringableObject
230 | Self::PureCallable
231 | Self::PureClosure
232 | Self::UnspecifiedLiteralString
233 | Self::UnspecifiedLiteralFloat
234 | Self::NonEmptyUnspecifiedLiteralString
235 | Self::Resource
236 | Self::Void
237 | Self::Scalar
238 | Self::Numeric
239 | Self::NoReturn
240 | Self::NeverReturn
241 | Self::NeverReturns
242 | Self::Never
243 | Self::Nothing
244 | Self::ArrayKey
245 | Self::List
246 | Self::NonEmptyList
247 | Self::OpenResource
248 | Self::ClosedResource
249 | Self::AssociativeArray
250 | Self::Is
251 | Self::As
252 | Self::Not
253 | Self::KeyOf
254 | Self::ValueOf
255 | Self::IntMask
256 | Self::IntMaskOf
257 | Self::New
258 | Self::TemplateType
259 | Self::Min
260 | Self::Max
261 | Self::UnspecifiedLiteralInt
262 | Self::PropertiesOf
263 | Self::PublicPropertiesOf
264 | Self::PrivatePropertiesOf
265 | Self::ProtectedPropertiesOf
266 | Self::PositiveInt
267 | Self::NegativeInt
268 | Self::NonPositiveInt
269 | Self::NonNegativeInt
270 | Self::NonZeroInt
271 )
272 }
273
274 #[inline]
275 #[must_use]
276 pub const fn is_array_like(&self) -> bool {
277 matches!(self, Self::Array | Self::NonEmptyArray | Self::AssociativeArray | Self::List | Self::NonEmptyList)
278 }
279}