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