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 As,
107 Is,
108 Not,
109 Identifier,
110 QualifiedIdentifier,
111 FullyQualifiedIdentifier,
112 Plus,
113 Minus,
114 LessThan,
115 GreaterThan,
116 Pipe,
117 Ampersand,
118 Question,
119 Exclamation,
120 Comma,
121 Colon,
122 ColonColon,
123 LeftBrace,
124 RightBrace,
125 LeftBracket,
126 RightBracket,
127 LeftParenthesis,
128 RightParenthesis,
129 Equals,
130 Ellipsis,
131 PartialLiteralString,
132 LiteralString,
133 LiteralInteger,
134 LiteralFloat,
135 Variable,
136 Whitespace,
137 SingleLineComment,
138 Asterisk,
139}
140
141#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
142pub struct TypeToken<'input> {
143 pub kind: TypeTokenKind,
144 pub start: Position,
145 pub value: &'input str,
146}
147
148impl<'input> TypeToken<'input> {
149 #[inline]
151 #[must_use]
152 pub const fn new(kind: TypeTokenKind, value: &'input str, start: Position) -> Self {
153 Self { kind, start, value }
154 }
155
156 #[inline]
158 #[must_use]
159 pub const fn end(&self) -> Position {
160 Position::new(self.start.offset + self.value.len() as u32)
161 }
162
163 #[inline]
165 #[must_use]
166 pub const fn span_for(&self, file_id: FileId) -> Span {
167 Span::new(file_id, self.start, self.end())
168 }
169}
170
171impl TypeTokenKind {
172 #[inline]
173 #[must_use]
174 pub const fn is_trivia(&self) -> bool {
175 matches!(self, Self::SingleLineComment | Self::Whitespace)
176 }
177
178 #[inline]
179 #[must_use]
180 pub const fn is_simple_identifier(&self) -> bool {
181 matches!(self, Self::Identifier)
182 }
183
184 #[inline]
185 #[must_use]
186 pub const fn is_identifier(&self) -> bool {
187 matches!(self, Self::Identifier | Self::QualifiedIdentifier | Self::FullyQualifiedIdentifier)
188 }
189
190 #[inline]
191 #[must_use]
192 pub const fn is_keyword(&self) -> bool {
193 matches!(
194 self,
195 Self::Int
196 | Self::Integer
197 | Self::Double
198 | Self::String
199 | Self::Float
200 | Self::Real
201 | Self::Bool
202 | Self::Boolean
203 | Self::False
204 | Self::True
205 | Self::Object
206 | Self::Callable
207 | Self::Array
208 | Self::NonEmptyArray
209 | Self::CallableString
210 | Self::LowercaseCallableString
211 | Self::UppercaseCallableString
212 | Self::NonEmptyString
213 | Self::NonEmptyLowercaseString
214 | Self::LowercaseString
215 | Self::NonEmptyUppercaseString
216 | Self::UppercaseString
217 | Self::TruthyString
218 | Self::NonFalsyString
219 | Self::Iterable
220 | Self::Null
221 | Self::Mixed
222 | Self::NonEmptyMixed
223 | Self::NumericString
224 | Self::ClassString
225 | Self::InterfaceString
226 | Self::TraitString
227 | Self::EnumString
228 | Self::StringableObject
229 | Self::PureCallable
230 | Self::PureClosure
231 | Self::UnspecifiedLiteralString
232 | Self::UnspecifiedLiteralFloat
233 | Self::NonEmptyUnspecifiedLiteralString
234 | Self::Resource
235 | Self::Void
236 | Self::Scalar
237 | Self::Numeric
238 | Self::NoReturn
239 | Self::NeverReturn
240 | Self::NeverReturns
241 | Self::Never
242 | Self::Nothing
243 | Self::ArrayKey
244 | Self::List
245 | Self::NonEmptyList
246 | Self::OpenResource
247 | Self::ClosedResource
248 | Self::AssociativeArray
249 | Self::Is
250 | Self::As
251 | Self::Not
252 | Self::KeyOf
253 | Self::ValueOf
254 | Self::IntMask
255 | Self::IntMaskOf
256 | Self::New
257 | Self::TemplateType
258 | Self::Min
259 | Self::Max
260 | Self::UnspecifiedLiteralInt
261 | Self::PropertiesOf
262 | Self::PublicPropertiesOf
263 | Self::PrivatePropertiesOf
264 | Self::ProtectedPropertiesOf
265 | Self::PositiveInt
266 | Self::NegativeInt
267 | Self::NonPositiveInt
268 | Self::NonNegativeInt
269 )
270 }
271
272 #[inline]
273 #[must_use]
274 pub const fn is_array_like(&self) -> bool {
275 matches!(self, Self::Array | Self::NonEmptyArray | Self::AssociativeArray | Self::List | Self::NonEmptyList)
276 }
277}