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