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