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