ara_parser/parser/internal/
identifier.rs1use crate::lexer::token::TokenKind;
2use crate::parser::internal::definition::template;
3use crate::parser::result::ParseResult;
4use crate::parser::state::State;
5use crate::tree::identifier::Identifier;
6use crate::tree::identifier::TemplatedIdentifier;
7
8#[inline(always)]
13pub fn namespace_identifier(state: &mut State) -> ParseResult<Identifier> {
14 let current = state.iterator.current();
15
16 match ¤t.kind {
17 TokenKind::Identifier | TokenKind::QualifiedIdentifier => {
18 let position = current.position;
19
20 state.iterator.next();
21
22 Ok(Identifier {
23 position,
24 value: current.value.clone(),
25 })
26 }
27 _ if is_reserved_identifier(¤t.kind) => {
28 let name = current.to_string().into();
29 let position = current.position;
30 state.iterator.next();
31
32 Ok(Identifier {
33 position,
34 value: name,
35 })
36 }
37 _ => {
38 crate::parser_bail!(
39 state,
40 unexpected_token(vec!["an identifier".to_owned()], current)
41 )
42 }
43 }
44}
45
46pub fn classname_identifier(state: &mut State) -> ParseResult<Identifier> {
64 let current = state.iterator.current();
65 match ¤t.kind {
66 TokenKind::Identifier => {
67 let position = current.position;
68
69 state.iterator.next();
70
71 Ok(Identifier {
72 position,
73 value: current.value.clone(),
74 })
75 }
76 TokenKind::Enum
77 | TokenKind::From
78 | TokenKind::Where
79 | TokenKind::Type
80 | TokenKind::In
81 | TokenKind::Into
82 | TokenKind::Using
83 | TokenKind::Dict
84 | TokenKind::Vec
85 | TokenKind::Async
86 | TokenKind::Await
87 | TokenKind::Concurrently => {
88 let position = current.position;
89 let name = current.to_string().into();
90
91 state.iterator.next();
92
93 Ok(Identifier {
94 position,
95 value: name,
96 })
97 }
98 t if is_reserved_identifier(t) => {
99 state.iterator.next();
100
101 let identifier = Identifier {
102 position: current.position,
103 value: current.to_string().into(),
104 };
105
106 crate::parser_report!(
107 state,
108 reserved_keyword_cannot_be_used_for_type_name(&identifier)
109 );
110
111 Ok(identifier)
112 }
113 _ => {
114 crate::parser_bail!(
115 state,
116 unexpected_token(vec!["an identifier".to_owned()], current)
117 )
118 }
119 }
120}
121
122#[inline(always)]
132pub fn constant_identifier(state: &mut State) -> ParseResult<Identifier> {
133 let current = state.iterator.current();
134 match ¤t.kind {
135 TokenKind::Identifier => {
136 let position = current.position;
137
138 state.iterator.next();
139
140 Ok(Identifier {
141 position,
142 value: current.value.clone(),
143 })
144 }
145 TokenKind::Class => {
146 let position = current.position;
147 let name = current.to_string().into();
148
149 state.iterator.next();
150
151 let identifier = Identifier {
152 position,
153 value: name,
154 };
155
156 crate::parser_report!(
157 state,
158 reserved_keyword_cannot_be_used_for_constant_name(&identifier)
159 );
160
161 Ok(identifier)
162 }
163 t if is_reserved_identifier(t) => {
164 state.iterator.next();
165
166 let identifier = Identifier {
167 position: current.position,
168 value: current.to_string().into(),
169 };
170
171 Ok(identifier)
172 }
173 _ => {
174 crate::parser_bail!(
175 state,
176 unexpected_token(vec!["an identifier".to_owned()], current)
177 )
178 }
179 }
180}
181
182#[inline(always)]
197pub fn type_identifier(state: &mut State) -> ParseResult<TemplatedIdentifier> {
198 let current = state.iterator.current();
199 let name = match ¤t.kind {
200 TokenKind::Identifier => {
201 state.iterator.next();
202
203 Identifier {
204 position: current.position,
205 value: current.value.clone(),
206 }
207 }
208 TokenKind::Enum
209 | TokenKind::From
210 | TokenKind::Where
211 | TokenKind::Type
212 | TokenKind::In
213 | TokenKind::Into
214 | TokenKind::Using => {
215 state.iterator.next();
216
217 Identifier {
218 position: current.position,
219 value: current.value.clone(),
220 }
221 }
222 t if is_reserved_identifier(t) => {
223 state.iterator.next();
224
225 let identifier = Identifier {
226 position: current.position,
227 value: current.to_string().into(),
228 };
229
230 crate::parser_report!(
231 state,
232 reserved_keyword_cannot_be_used_for_type_name(&identifier)
233 );
234
235 identifier
236 }
237 _ => {
238 crate::parser_bail!(
239 state,
240 unexpected_token(vec!["an identifier".to_owned()], current)
241 )
242 }
243 };
244
245 let templates = if state.iterator.current().kind == TokenKind::LessThan {
246 Some(template::type_template_group_definition(state)?)
247 } else {
248 None
249 };
250
251 Ok(TemplatedIdentifier { name, templates })
252}
253
254pub fn fully_qualified_templated_identifier(state: &mut State) -> ParseResult<TemplatedIdentifier> {
255 let name = fully_qualified_type_identifier(state)?;
256 let templates = if state.iterator.current().kind == TokenKind::LessThan {
257 Some(template::type_template_group_definition(state)?)
258 } else {
259 None
260 };
261
262 Ok(TemplatedIdentifier { name, templates })
263}
264
265pub fn fully_qualified_templated_identifier_including_self(
266 state: &mut State,
267) -> ParseResult<TemplatedIdentifier> {
268 let name = fully_qualified_type_identifier_including_self(state)?;
269 let templates = if state.iterator.current().kind == TokenKind::LessThan {
270 Some(template::type_template_group_definition(state)?)
271 } else {
272 None
273 };
274
275 Ok(TemplatedIdentifier { name, templates })
276}
277
278pub fn identifier(state: &mut State) -> ParseResult<Identifier> {
280 let current = state.iterator.current();
281 if let TokenKind::Identifier = ¤t.kind {
282 let position = current.position;
283
284 state.iterator.next();
285
286 Ok(Identifier {
287 position,
288 value: current.value.clone(),
289 })
290 } else {
291 crate::parser_bail!(
292 state,
293 unexpected_token(vec!["an identifier".to_owned()], current)
294 );
295 }
296}
297
298pub fn fully_qualified_type_identifier(state: &mut State) -> ParseResult<Identifier> {
300 let current = state.iterator.current();
301 match ¤t.kind {
302 TokenKind::Identifier
303 | TokenKind::QualifiedIdentifier
304 | TokenKind::FullyQualifiedIdentifier => {
305 let position = current.position;
306
307 state.iterator.next();
308
309 Ok(Identifier {
310 position,
311 value: current.value.clone(),
312 })
313 }
314 TokenKind::Enum
315 | TokenKind::From
316 | TokenKind::Where
317 | TokenKind::Type
318 | TokenKind::In
319 | TokenKind::Into
320 | TokenKind::Using
321 | TokenKind::Dict
322 | TokenKind::Vec
323 | TokenKind::Async
324 | TokenKind::Await
325 | TokenKind::Concurrently => {
326 let position = current.position;
327 let name = current.to_string().into();
328
329 state.iterator.next();
330
331 Ok(Identifier {
332 position,
333 value: name,
334 })
335 }
336 TokenKind::Self_ | TokenKind::Static | TokenKind::Parent => {
337 state.iterator.next();
338
339 let identifier = Identifier {
340 position: current.position,
341 value: current.to_string().into(),
342 };
343
344 crate::parser_report!(state, type_cannot_be_used_in_current_context(&identifier));
345
346 Ok(identifier)
347 }
348 t if is_reserved_identifier(t) => {
349 state.iterator.next();
350
351 let identifier = Identifier {
352 position: current.position,
353 value: current.to_string().into(),
354 };
355
356 crate::parser_report!(
357 state,
358 reserved_keyword_cannot_be_used_for_type_name(&identifier)
359 );
360
361 Ok(identifier)
362 }
363 _ => crate::parser_bail!(
364 state,
365 unexpected_token(vec!["an identifier".to_owned()], current)
366 ),
367 }
368}
369
370pub fn fully_qualified_type_identifier_including_self(
372 state: &mut State,
373) -> ParseResult<Identifier> {
374 let current = state.iterator.current();
375 match ¤t.kind {
376 TokenKind::Identifier
377 | TokenKind::QualifiedIdentifier
378 | TokenKind::FullyQualifiedIdentifier => {
379 let position = current.position;
380
381 state.iterator.next();
382
383 Ok(Identifier {
384 position,
385 value: current.value.clone(),
386 })
387 }
388 TokenKind::Enum
389 | TokenKind::From
390 | TokenKind::Self_
391 | TokenKind::Static
392 | TokenKind::Parent
393 | TokenKind::Type
394 | TokenKind::In
395 | TokenKind::Into
396 | TokenKind::Using
397 | TokenKind::Where
398 | TokenKind::Dict
399 | TokenKind::Vec
400 | TokenKind::Async
401 | TokenKind::Await
402 | TokenKind::Concurrently => {
403 let position = current.position;
404 let name = current.to_string().into();
405
406 state.iterator.next();
407
408 Ok(Identifier {
409 position,
410 value: name,
411 })
412 }
413 t if is_reserved_identifier(t) => {
414 state.iterator.next();
415
416 let identifier = Identifier {
417 position: current.position,
418 value: current.to_string().into(),
419 };
420
421 crate::parser_report!(
422 state,
423 reserved_keyword_cannot_be_used_for_type_name(&identifier)
424 );
425
426 Ok(identifier)
427 }
428 _ => crate::parser_bail!(
429 state,
430 unexpected_token(vec!["an identifier".to_owned()], current)
431 ),
432 }
433}
434
435pub fn identifier_maybe_reserved(state: &mut State) -> ParseResult<Identifier> {
436 let current = state.iterator.current();
437
438 if is_reserved_identifier(¤t.kind) {
439 let name = current.to_string().into();
440 let position = current.position;
441 state.iterator.next();
442
443 Ok(Identifier {
444 position,
445 value: name,
446 })
447 } else {
448 identifier(state)
449 }
450}
451
452pub fn identifier_maybe_soft_reserved(state: &mut State) -> ParseResult<Identifier> {
453 let current = state.iterator.current();
454
455 if is_soft_reserved_identifier(¤t.kind) {
456 let name = current.to_string().into();
457 let position = current.position;
458 state.iterator.next();
459
460 Ok(Identifier {
461 position,
462 value: name,
463 })
464 } else {
465 identifier(state)
466 }
467}
468
469pub fn is_identifier_maybe_reserved(kind: &TokenKind) -> bool {
470 if let TokenKind::Identifier = kind {
471 return true;
472 }
473
474 is_reserved_identifier(kind)
475}
476
477pub fn is_soft_reserved_identifier(kind: &TokenKind) -> bool {
478 matches!(kind, |TokenKind::Parent| TokenKind::Self_
479 | TokenKind::True
480 | TokenKind::False
481 | TokenKind::Type
482 | TokenKind::In
483 | TokenKind::Into
484 | TokenKind::Using
485 | TokenKind::Is
486 | TokenKind::List
487 | TokenKind::Null
488 | TokenKind::Concurrently
489 | TokenKind::Async
490 | TokenKind::Await
491 | TokenKind::Where
492 | TokenKind::Enum
493 | TokenKind::From
494 | TokenKind::Readonly)
495}
496
497pub fn is_reserved_identifier(kind: &TokenKind) -> bool {
498 if is_soft_reserved_identifier(kind) {
499 return true;
500 }
501
502 matches!(
503 kind,
504 TokenKind::Static
505 | TokenKind::Abstract
506 | TokenKind::Final
507 | TokenKind::For
508 | TokenKind::Private
509 | TokenKind::Protected
510 | TokenKind::Public
511 | TokenKind::Dict
512 | TokenKind::Vec
513 | TokenKind::LogicalOr
514 | TokenKind::LogicalXor
515 | TokenKind::LogicalAnd
516 | TokenKind::Instanceof
517 | TokenKind::New
518 | TokenKind::Clone
519 | TokenKind::Exit
520 | TokenKind::If
521 | TokenKind::ElseIf
522 | TokenKind::Else
523 | TokenKind::EndIf
524 | TokenKind::Echo
525 | TokenKind::Do
526 | TokenKind::While
527 | TokenKind::EndWhile
528 | TokenKind::EndFor
529 | TokenKind::Foreach
530 | TokenKind::EndForeach
531 | TokenKind::Declare
532 | TokenKind::EndDeclare
533 | TokenKind::As
534 | TokenKind::Try
535 | TokenKind::Catch
536 | TokenKind::Finally
537 | TokenKind::Throw
538 | TokenKind::Use
539 | TokenKind::Insteadof
540 | TokenKind::Global
541 | TokenKind::Var
542 | TokenKind::Unset
543 | TokenKind::Isset
544 | TokenKind::Empty
545 | TokenKind::Continue
546 | TokenKind::Goto
547 | TokenKind::Function
548 | TokenKind::Const
549 | TokenKind::Return
550 | TokenKind::Print
551 | TokenKind::Yield
552 | TokenKind::List
553 | TokenKind::Switch
554 | TokenKind::EndSwitch
555 | TokenKind::Case
556 | TokenKind::Default
557 | TokenKind::Break
558 | TokenKind::Array
559 | TokenKind::Callable
560 | TokenKind::Extends
561 | TokenKind::Implements
562 | TokenKind::Namespace
563 | TokenKind::Trait
564 | TokenKind::Interface
565 | TokenKind::Class
566 | TokenKind::ClassConstant
567 | TokenKind::TraitConstant
568 | TokenKind::FunctionConstant
569 | TokenKind::MethodConstant
570 | TokenKind::LineConstant
571 | TokenKind::FileConstant
572 | TokenKind::DirConstant
573 | TokenKind::NamespaceConstant
574 | TokenKind::HaltCompiler
575 | TokenKind::Fn
576 | TokenKind::Match
577 | TokenKind::Include
578 | TokenKind::IncludeOnce
579 | TokenKind::Eval
580 | TokenKind::Require
581 | TokenKind::RequireOnce
582 | TokenKind::Die
583 )
584}