1use std::mem;
2
3use cairo_lang_diagnostics::DiagnosticsBuilder;
4use cairo_lang_filesystem::ids::FileId;
5use cairo_lang_filesystem::span::{TextOffset, TextSpan, TextWidth};
6use cairo_lang_primitive_token::{PrimitiveToken, ToPrimitiveTokenStream};
7use cairo_lang_syntax as syntax;
8use cairo_lang_syntax::node::ast::*;
9use cairo_lang_syntax::node::db::SyntaxGroup;
10use cairo_lang_syntax::node::kind::SyntaxKind;
11use cairo_lang_syntax::node::{SyntaxNode, Token, TypedSyntaxNode};
12use cairo_lang_utils::{LookupIntern, extract_matches, require};
13use syntax::node::green::{GreenNode, GreenNodeDetails};
14use syntax::node::ids::GreenId;
15
16use crate::ParserDiagnostic;
17use crate::diagnostic::ParserDiagnosticKind;
18use crate::lexer::{Lexer, LexerTerminal};
19use crate::operators::{get_post_operator_precedence, get_unary_operator_precedence};
20use crate::recovery::is_of_kind;
21use crate::utils::primitive_token_stream_content_and_offset;
22use crate::validation::{validate_literal_number, validate_short_string, validate_string};
23
24#[cfg(test)]
25#[path = "parser_test.rs"]
26mod test;
27
28pub struct Parser<'a> {
29 db: &'a dyn SyntaxGroup,
30 file_id: FileId,
31 lexer: Lexer<'a>,
32 next_terminal: LexerTerminal,
34 pending_trivia: Vec<TriviumGreen>,
36 offset: TextOffset,
38 current_width: TextWidth,
41 last_trivia_length: TextWidth,
43 diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
44 pending_skipped_token_diagnostics: Vec<PendingParserDiagnostic>,
46}
47
48#[derive(PartialEq)]
50pub enum TryParseFailure {
51 SkipToken,
54 DoNothing,
59}
60pub type TryParseResult<GreenElement> = Result<GreenElement, TryParseFailure>;
62
63const MAX_PRECEDENCE: usize = 1000;
92const MODULE_ITEM_DESCRIPTION: &str = "Const/Enum/ExternFunction/ExternType/Function/Impl/\
93 InlineMacro/Module/Struct/Trait/TypeAlias/Use";
94const TRAIT_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
95const IMPL_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
96
97macro_rules! or_an_attribute {
99 ($string:expr) => {
100 format!("{} or an attribute", $string)
101 };
102}
103
104impl<'a> Parser<'a> {
105 fn new(
107 db: &'a dyn SyntaxGroup,
108 file_id: FileId,
109 text: &'a str,
110 diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
111 ) -> Self {
112 let mut lexer = Lexer::from_text(db, text);
113 let next_terminal = lexer.next().unwrap();
114 Parser {
115 db,
116 file_id,
117 lexer,
118 next_terminal,
119 pending_trivia: Vec::new(),
120 offset: Default::default(),
121 current_width: Default::default(),
122 last_trivia_length: Default::default(),
123 diagnostics,
124 pending_skipped_token_diagnostics: Vec::new(),
125 }
126 }
127
128 fn add_diagnostic(&mut self, kind: ParserDiagnosticKind, span: TextSpan) {
130 self.diagnostics.add(ParserDiagnostic { file_id: self.file_id, kind, span });
131 }
132
133 pub fn parse_file(
135 db: &'a dyn SyntaxGroup,
136 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
137 file_id: FileId,
138 text: &'a str,
139 ) -> SyntaxFile {
140 let parser = Parser::new(db, file_id, text, diagnostics);
141 let green = parser.parse_syntax_file();
142 SyntaxFile::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
143 }
144
145 pub fn parse_file_expr(
147 db: &'a dyn SyntaxGroup,
148 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
149 file_id: FileId,
150 text: &'a str,
151 ) -> Expr {
152 let mut parser = Parser::new(db, file_id, text, diagnostics);
153 let green = parser.parse_expr();
154 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
155 parser.add_diagnostic(
156 ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
157 span,
158 );
159 }
160 Expr::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
161 }
162
163 pub fn parse_token_stream(
165 db: &'a dyn SyntaxGroup,
166 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
167 file_id: FileId,
168 token_stream: &'a dyn ToPrimitiveTokenStream<Iter = impl Iterator<Item = PrimitiveToken>>,
169 ) -> SyntaxFile {
170 let (content, offset) = primitive_token_stream_content_and_offset(token_stream);
171 let parser = Parser::new(db, file_id, &content, diagnostics);
172 let green = parser.parse_syntax_file();
173 SyntaxFile::from_syntax_node(
174 db,
175 SyntaxNode::new_root_with_offset(db, file_id, green.0, offset),
176 )
177 }
178
179 pub fn parse_token_stream_expr(
181 db: &'a dyn SyntaxGroup,
182 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
183 file_id: FileId,
184 token_stream: &'a dyn ToPrimitiveTokenStream<Iter = impl Iterator<Item = PrimitiveToken>>,
185 ) -> Expr {
186 let (content, offset) = primitive_token_stream_content_and_offset(token_stream);
187 let mut parser = Parser::new(db, file_id, &content, diagnostics);
188 let green = parser.parse_expr();
189 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
190 parser.diagnostics.add(ParserDiagnostic {
191 file_id: parser.file_id,
192 kind: ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
193 span,
194 });
195 }
196 Expr::from_syntax_node(db, SyntaxNode::new_root_with_offset(db, file_id, green.0, offset))
197 }
198
199 fn create_and_report_missing<T: TypedSyntaxNode>(
201 &mut self,
202 missing_kind: ParserDiagnosticKind,
203 ) -> T::Green {
204 let next_offset = self.offset.add_width(self.current_width - self.last_trivia_length);
205 self.add_diagnostic(missing_kind, TextSpan { start: next_offset, end: next_offset });
206 T::missing(self.db)
207 }
208
209 fn create_and_report_missing_terminal<Terminal: syntax::node::Terminal>(
212 &mut self,
213 ) -> Terminal::Green {
214 self.create_and_report_missing::<Terminal>(ParserDiagnosticKind::MissingToken(
215 Terminal::KIND,
216 ))
217 }
218
219 pub fn parse_syntax_file(mut self) -> SyntaxFileGreen {
220 let mut module_items = vec![];
221 if let Some(doc_item) = self.take_doc() {
222 module_items.push(doc_item.into());
223 }
224 module_items.extend(self.parse_attributed_list(
225 Self::try_parse_module_item,
226 is_of_kind!(),
227 MODULE_ITEM_DESCRIPTION,
228 ));
229 let items = ModuleItemList::new_green(self.db, module_items);
231 assert_eq!(self.peek().kind, SyntaxKind::TerminalEndOfFile);
233
234 self.offset = self.offset.add_width(self.current_width);
238
239 let eof = self.add_trivia_to_terminal::<TerminalEndOfFile>(self.next_terminal.clone());
240 SyntaxFile::new_green(self.db, items, eof)
241 }
242
243 pub fn try_parse_module_item(&mut self) -> TryParseResult<ModuleItemGreen> {
250 let maybe_attributes = self.try_parse_attribute_list(MODULE_ITEM_DESCRIPTION);
251 let (has_attrs, attributes) = match maybe_attributes {
252 Ok(attributes) => (true, attributes),
253 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
254 };
255 let post_attributes_offset = self.offset.add_width(self.current_width);
256
257 let visibility_pub = self.try_parse_visibility_pub();
258 let visibility = match visibility_pub {
259 Some(visibility) => visibility.into(),
260 None => VisibilityDefault::new_green(self.db).into(),
261 };
262 let post_visibility_offset = self.offset.add_width(self.current_width);
263
264 match self.peek().kind {
265 SyntaxKind::TerminalConst => {
266 let const_kw = self.take::<TerminalConst>();
267 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
268 self.expect_item_function_with_body(attributes, visibility, const_kw.into())
269 .into()
270 } else {
271 self.expect_item_const(attributes, visibility, const_kw).into()
272 })
273 }
274 SyntaxKind::TerminalModule => {
275 Ok(self.expect_item_module(attributes, visibility).into())
276 }
277 SyntaxKind::TerminalStruct => {
278 Ok(self.expect_item_struct(attributes, visibility).into())
279 }
280 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
281 SyntaxKind::TerminalType => {
282 Ok(self.expect_item_type_alias(attributes, visibility).into())
283 }
284 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
285 SyntaxKind::TerminalFunction => Ok(self
286 .expect_item_function_with_body(
287 attributes,
288 visibility,
289 OptionTerminalConstEmpty::new_green(self.db).into(),
290 )
291 .into()),
292 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
293 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
294 SyntaxKind::TerminalImpl => Ok(self.expect_module_item_impl(attributes, visibility)),
295 SyntaxKind::TerminalIdentifier => {
296 let ident = self.take_raw();
303 match self.peek().kind {
304 SyntaxKind::TerminalNot => {
305 let macro_name = self.add_trivia_to_terminal::<TerminalIdentifier>(ident);
307 Ok(self.expect_item_inline_macro(attributes, macro_name).into())
308 }
309 SyntaxKind::TerminalLParen
310 | SyntaxKind::TerminalLBrace
311 | SyntaxKind::TerminalLBrack => {
312 self.add_diagnostic(
314 ParserDiagnosticKind::ItemInlineMacroWithoutBang {
315 identifier: ident.clone().text,
316 bracket_type: self.peek().kind,
317 },
318 TextSpan {
319 start: self.offset,
320 end: self.offset.add_width(self.current_width),
321 },
322 );
323 let macro_name = self.add_trivia_to_terminal::<TerminalIdentifier>(ident);
324 Ok(self
325 .parse_item_inline_macro_given_bang(
326 attributes,
327 macro_name,
328 TerminalNot::missing(self.db),
329 )
330 .into())
331 }
332 _ => {
333 if has_attrs {
334 self.skip_taken_node_with_offset(
335 attributes,
336 ParserDiagnosticKind::SkippedElement {
337 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
338 },
339 post_attributes_offset,
340 );
341 }
342 if let Some(visibility_pub) = visibility_pub {
343 self.skip_taken_node_with_offset(
344 visibility_pub,
345 ParserDiagnosticKind::SkippedElement {
346 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
347 },
348 post_visibility_offset,
349 );
350 }
351 self.append_skipped_token_to_pending_trivia(
353 ident,
354 ParserDiagnosticKind::SkippedElement {
355 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
356 },
357 );
358 Err(TryParseFailure::DoNothing)
360 }
361 }
362 }
363 _ => {
364 let mut result = Err(TryParseFailure::SkipToken);
365 if has_attrs {
366 self.skip_taken_node_with_offset(
367 attributes,
368 ParserDiagnosticKind::AttributesWithoutItem,
369 post_attributes_offset,
370 );
371 result = Ok(ModuleItem::missing(self.db));
372 }
373 if let Some(visibility_pub) = visibility_pub {
374 self.skip_taken_node_with_offset(
375 visibility_pub,
376 ParserDiagnosticKind::VisibilityWithoutItem,
377 post_visibility_offset,
378 );
379 result = Ok(ModuleItem::missing(self.db));
380 }
381 result
382 }
383 }
384 }
385
386 fn expect_item_module(
389 &mut self,
390 attributes: AttributeListGreen,
391 visibility: VisibilityGreen,
392 ) -> ItemModuleGreen {
393 let module_kw = self.take::<TerminalModule>();
394 let name = self.parse_identifier();
395
396 let body = match self.peek().kind {
397 SyntaxKind::TerminalLBrace => {
398 let lbrace = self.take::<TerminalLBrace>();
399 let mut module_items = vec![];
400 if let Some(doc_item) = self.take_doc() {
401 module_items.push(doc_item.into());
402 }
403 module_items.extend(self.parse_attributed_list(
404 Self::try_parse_module_item,
405 is_of_kind!(rbrace),
406 MODULE_ITEM_DESCRIPTION,
407 ));
408 let items = ModuleItemList::new_green(self.db, module_items);
409 let rbrace = self.parse_token::<TerminalRBrace>();
410 ModuleBody::new_green(self.db, lbrace, items, rbrace).into()
411 }
412 _ => self.parse_token::<TerminalSemicolon>().into(),
414 };
415
416 ItemModule::new_green(self.db, attributes, visibility, module_kw, name, body)
417 }
418
419 fn expect_item_struct(
422 &mut self,
423 attributes: AttributeListGreen,
424 visibility: VisibilityGreen,
425 ) -> ItemStructGreen {
426 let struct_kw = self.take::<TerminalStruct>();
427 let name = self.parse_identifier();
428 let generic_params = self.parse_optional_generic_params();
429 let lbrace = self.parse_token::<TerminalLBrace>();
430 let members = self.parse_member_list();
431 let rbrace = self.parse_token::<TerminalRBrace>();
432 ItemStruct::new_green(
433 self.db,
434 attributes,
435 visibility,
436 struct_kw,
437 name,
438 generic_params,
439 lbrace,
440 members,
441 rbrace,
442 )
443 }
444
445 fn expect_item_enum(
448 &mut self,
449 attributes: AttributeListGreen,
450 visibility: VisibilityGreen,
451 ) -> ItemEnumGreen {
452 let enum_kw = self.take::<TerminalEnum>();
453 let name = self.parse_identifier();
454 let generic_params = self.parse_optional_generic_params();
455 let lbrace = self.parse_token::<TerminalLBrace>();
456 let variants = self.parse_variant_list();
457 let rbrace = self.parse_token::<TerminalRBrace>();
458 ItemEnum::new_green(
459 self.db,
460 attributes,
461 visibility,
462 enum_kw,
463 name,
464 generic_params,
465 lbrace,
466 variants,
467 rbrace,
468 )
469 }
470
471 fn expect_item_type_alias(
474 &mut self,
475 attributes: AttributeListGreen,
476 visibility: VisibilityGreen,
477 ) -> ItemTypeAliasGreen {
478 let type_kw = self.take::<TerminalType>();
479 let name = self.parse_identifier();
480 let generic_params = self.parse_optional_generic_params();
481 let eq = self.parse_token::<TerminalEq>();
482 let ty = self.parse_type_expr();
483 let semicolon = self.parse_token::<TerminalSemicolon>();
484 ItemTypeAlias::new_green(
485 self.db,
486 attributes,
487 visibility,
488 type_kw,
489 name,
490 generic_params,
491 eq,
492 ty,
493 semicolon,
494 )
495 }
496
497 fn expect_function_signature(&mut self) -> FunctionSignatureGreen {
499 let lparen = self.parse_token::<TerminalLParen>();
500 let params = self.parse_param_list();
501 let rparen = self.parse_token::<TerminalRParen>();
502 let return_type_clause = self.parse_option_return_type_clause();
503 let implicits_clause = self.parse_option_implicits_clause();
504 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
505 self.take::<TerminalNoPanic>().into()
506 } else {
507 OptionTerminalNoPanicEmpty::new_green(self.db).into()
508 };
509
510 FunctionSignature::new_green(
511 self.db,
512 lparen,
513 params,
514 rparen,
515 return_type_clause,
516 implicits_clause,
517 optional_no_panic,
518 )
519 }
520
521 fn expect_item_const(
524 &mut self,
525 attributes: AttributeListGreen,
526 visibility: VisibilityGreen,
527 const_kw: TerminalConstGreen,
528 ) -> ItemConstantGreen {
529 let name = self.parse_identifier();
530 let type_clause = self.parse_type_clause(ErrorRecovery {
531 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
532 });
533 let eq = self.parse_token::<TerminalEq>();
534 let expr = self.parse_expr();
535 let semicolon = self.parse_token::<TerminalSemicolon>();
536
537 ItemConstant::new_green(
538 self.db,
539 attributes,
540 visibility,
541 const_kw,
542 name,
543 type_clause,
544 eq,
545 expr,
546 semicolon,
547 )
548 }
549
550 fn expect_item_extern<T: From<ItemExternFunctionGreen> + From<ItemExternTypeGreen>>(
553 &mut self,
554 attributes: AttributeListGreen,
555 visibility: VisibilityGreen,
556 ) -> T {
557 match self.expect_item_extern_inner(attributes, visibility) {
558 ExternItem::Function(x) => x.into(),
559 ExternItem::Type(x) => x.into(),
560 }
561 }
562
563 fn expect_item_extern_inner(
566 &mut self,
567 attributes: AttributeListGreen,
568 visibility: VisibilityGreen,
569 ) -> ExternItem {
570 let extern_kw = self.take::<TerminalExtern>();
571 match self.peek().kind {
572 SyntaxKind::TerminalFunction | SyntaxKind::TerminalConst => {
573 let (optional_const, function_kw) = if self.peek().kind == SyntaxKind::TerminalConst
574 {
575 (self.take::<TerminalConst>().into(), self.parse_token::<TerminalFunction>())
576 } else {
577 (
578 OptionTerminalConstEmpty::new_green(self.db).into(),
579 self.take::<TerminalFunction>(),
580 )
581 };
582 let declaration = self.expect_function_declaration_ex(optional_const, function_kw);
583 let semicolon = self.parse_token::<TerminalSemicolon>();
584 ExternItem::Function(ItemExternFunction::new_green(
585 self.db,
586 attributes,
587 visibility,
588 extern_kw,
589 declaration,
590 semicolon,
591 ))
592 }
593 _ => {
594 let type_kw = self.parse_token::<TerminalType>();
596
597 let name = self.parse_identifier();
598 let generic_params = self.parse_optional_generic_params();
599 let semicolon = self.parse_token::<TerminalSemicolon>();
600 ExternItem::Type(ItemExternType::new_green(
602 self.db,
603 attributes,
604 visibility,
605 extern_kw,
606 type_kw,
607 name,
608 generic_params,
609 semicolon,
610 ))
611 }
612 }
613 }
614
615 fn expect_item_use(
618 &mut self,
619 attributes: AttributeListGreen,
620 visibility: VisibilityGreen,
621 ) -> ItemUseGreen {
622 let use_kw = self.take::<TerminalUse>();
623 let use_path = self.parse_use_path();
624 let semicolon = self.parse_token::<TerminalSemicolon>();
625 ItemUse::new_green(self.db, attributes, visibility, use_kw, use_path, semicolon)
626 }
627
628 fn try_parse_use_path(&mut self) -> TryParseResult<UsePathGreen> {
630 if !matches!(
631 self.peek().kind,
632 SyntaxKind::TerminalLBrace | SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalMul
633 ) {
634 return Err(TryParseFailure::SkipToken);
635 }
636 Ok(self.parse_use_path())
637 }
638
639 fn parse_use_path(&mut self) -> UsePathGreen {
641 match self.peek().kind {
642 SyntaxKind::TerminalLBrace => {
643 let lbrace = self.parse_token::<TerminalLBrace>();
644 let items = UsePathList::new_green(self.db,
645 self.parse_separated_list::<
646 UsePath, TerminalComma, UsePathListElementOrSeparatorGreen
647 >(
648 Self::try_parse_use_path,
649 is_of_kind!(rbrace, module_item_kw),
650 "path segment",
651 ));
652 let rbrace = self.parse_token::<TerminalRBrace>();
653 UsePathMulti::new_green(self.db, lbrace, items, rbrace).into()
654 }
655 SyntaxKind::TerminalMul => {
656 let star = self.parse_token::<TerminalMul>();
657 UsePathStar::new_green(self.db, star).into()
658 }
659 _ => {
660 if let Ok(ident) = self.try_parse_identifier() {
661 let ident = PathSegmentSimple::new_green(self.db, ident).into();
662 match self.peek().kind {
663 SyntaxKind::TerminalColonColon => {
664 let colon_colon = self.parse_token::<TerminalColonColon>();
665 let use_path = self.parse_use_path();
666 UsePathSingle::new_green(self.db, ident, colon_colon, use_path).into()
667 }
668 SyntaxKind::TerminalAs => {
669 let as_kw = self.take::<TerminalAs>();
670 let alias = self.parse_identifier();
671 let alias_clause = AliasClause::new_green(self.db, as_kw, alias).into();
672 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
673 }
674 _ => {
675 let alias_clause = OptionAliasClauseEmpty::new_green(self.db).into();
676 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
677 }
678 }
679 } else {
680 let missing = self.create_and_report_missing::<TerminalIdentifier>(
681 ParserDiagnosticKind::MissingPathSegment,
682 );
683 let ident = PathSegmentSimple::new_green(self.db, missing).into();
684 UsePathLeaf::new_green(
685 self.db,
686 ident,
687 OptionAliasClauseEmpty::new_green(self.db).into(),
688 )
689 .into()
690 }
691 }
692 }
693 }
694
695 fn try_parse_identifier(&mut self) -> TryParseResult<TerminalIdentifierGreen> {
700 if self.peek().kind.is_keyword_terminal() {
701 Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
703 ParserDiagnosticKind::ReservedIdentifier { identifier: self.peek().text.clone() },
704 ))
705 } else if self.peek().kind == SyntaxKind::TerminalUnderscore {
706 Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
707 ParserDiagnosticKind::UnderscoreNotAllowedAsIdentifier,
708 ))
709 } else {
710 self.try_parse_token::<TerminalIdentifier>()
711 }
712 }
713 fn is_peek_identifier_like(&self) -> bool {
719 let kind = self.peek().kind;
720 kind.is_keyword_terminal()
721 || matches!(kind, SyntaxKind::TerminalUnderscore | SyntaxKind::TerminalIdentifier)
722 }
723
724 fn parse_identifier(&mut self) -> TerminalIdentifierGreen {
726 match self.try_parse_identifier() {
727 Ok(identifier) => identifier,
728 Err(_) => self.create_and_report_missing_terminal::<TerminalIdentifier>(),
729 }
730 }
731
732 fn parse_visibility(&mut self) -> VisibilityGreen {
734 match self.try_parse_visibility_pub() {
735 Some(visibility) => visibility.into(),
736 None => VisibilityDefault::new_green(self.db).into(),
737 }
738 }
739
740 fn try_parse_visibility_pub(&mut self) -> Option<VisibilityPubGreen> {
742 require(self.peek().kind == SyntaxKind::TerminalPub)?;
743 let pub_kw = self.take::<TerminalPub>();
744 let argument_clause = if self.peek().kind != SyntaxKind::TerminalLParen {
745 OptionVisibilityPubArgumentClauseEmpty::new_green(self.db).into()
746 } else {
747 let lparen = self.parse_token::<TerminalLParen>();
748 let argument = self.parse_token::<TerminalIdentifier>();
749 let rparen = self.parse_token::<TerminalRParen>();
750 VisibilityPubArgumentClause::new_green(self.db, lparen, argument, rparen).into()
751 };
752 Some(VisibilityPub::new_green(self.db, pub_kw, argument_clause))
753 }
754
755 fn try_parse_attribute_list(
760 &mut self,
761 expected_elements_str: &str,
762 ) -> TryParseResult<AttributeListGreen> {
763 if self.peek().kind == SyntaxKind::TerminalHash {
764 Ok(self.parse_attribute_list(expected_elements_str))
765 } else {
766 Err(TryParseFailure::SkipToken)
767 }
768 }
769
770 fn parse_attribute_list(&mut self, expected_elements_str: &str) -> AttributeListGreen {
774 AttributeList::new_green(
775 self.db,
776 self.parse_list(
777 Self::try_parse_attribute,
778 |x| x != SyntaxKind::TerminalHash,
779 &or_an_attribute!(expected_elements_str),
780 ),
781 )
782 }
783
784 fn try_parse_attribute(&mut self) -> TryParseResult<AttributeGreen> {
787 match self.peek().kind {
788 SyntaxKind::TerminalHash => {
789 let hash = self.take::<TerminalHash>();
790 let lbrack = self.parse_token::<TerminalLBrack>();
791 let attr = self.parse_path();
792 let arguments = self.try_parse_parenthesized_argument_list();
793 let rbrack = self.parse_token::<TerminalRBrack>();
794
795 Ok(Attribute::new_green(self.db, hash, lbrack, attr, arguments, rbrack))
796 }
797 _ => Err(TryParseFailure::SkipToken),
798 }
799 }
800
801 fn expect_function_declaration(
804 &mut self,
805 optional_const: OptionTerminalConstGreen,
806 ) -> FunctionDeclarationGreen {
807 let function_kw = self.take::<TerminalFunction>();
808 self.expect_function_declaration_ex(optional_const, function_kw)
809 }
810
811 fn expect_function_declaration_ex(
814 &mut self,
815 optional_const: OptionTerminalConstGreen,
816 function_kw: TerminalFunctionGreen,
817 ) -> FunctionDeclarationGreen {
818 let name = self.parse_identifier();
819 let generic_params = self.parse_optional_generic_params();
820 let signature = self.expect_function_signature();
821
822 FunctionDeclaration::new_green(
823 self.db,
824 optional_const,
825 function_kw,
826 name,
827 generic_params,
828 signature,
829 )
830 }
831
832 fn expect_item_function_with_body(
835 &mut self,
836 attributes: AttributeListGreen,
837 visibility: VisibilityGreen,
838 optional_const: OptionTerminalConstGreen,
839 ) -> FunctionWithBodyGreen {
840 let declaration = self.expect_function_declaration(optional_const);
841 let function_body = self.parse_block();
842 FunctionWithBody::new_green(self.db, attributes, visibility, declaration, function_body)
843 }
844
845 fn expect_item_trait(
847 &mut self,
848 attributes: AttributeListGreen,
849 visibility: VisibilityGreen,
850 ) -> ItemTraitGreen {
851 let trait_kw = self.take::<TerminalTrait>();
852 let name = self.parse_identifier();
853 let generic_params = self.parse_optional_generic_params();
854 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
855 let lbrace = self.take::<TerminalLBrace>();
856 let items = TraitItemList::new_green(
857 self.db,
858 self.parse_attributed_list(
859 Self::try_parse_trait_item,
860 is_of_kind!(rbrace, module_item_kw),
861 TRAIT_ITEM_DESCRIPTION,
862 ),
863 );
864 let rbrace = self.parse_token::<TerminalRBrace>();
865 TraitBody::new_green(self.db, lbrace, items, rbrace).into()
866 } else {
867 self.parse_token::<TerminalSemicolon>().into()
868 };
869
870 ItemTrait::new_green(self.db, attributes, visibility, trait_kw, name, generic_params, body)
871 }
872
873 pub fn try_parse_trait_item(&mut self) -> TryParseResult<TraitItemGreen> {
876 let maybe_attributes = self.try_parse_attribute_list(TRAIT_ITEM_DESCRIPTION);
877
878 let (has_attrs, attributes) = match maybe_attributes {
879 Ok(attributes) => (true, attributes),
880 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
881 };
882
883 match self.peek().kind {
884 SyntaxKind::TerminalFunction => Ok(self
885 .expect_trait_item_function(
886 attributes,
887 OptionTerminalConstEmpty::new_green(self.db).into(),
888 )
889 .into()),
890 SyntaxKind::TerminalType => Ok(self.expect_trait_item_type(attributes).into()),
891 SyntaxKind::TerminalConst => {
892 let const_kw = self.take::<TerminalConst>();
893 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
894 self.expect_trait_item_function(attributes, const_kw.into()).into()
895 } else {
896 self.expect_trait_item_const(attributes, const_kw).into()
897 })
898 }
899 SyntaxKind::TerminalImpl => Ok(self.expect_trait_item_impl(attributes).into()),
900 _ => {
901 if has_attrs {
902 Ok(self.skip_taken_node_and_return_missing::<TraitItem>(
903 attributes,
904 ParserDiagnosticKind::AttributesWithoutTraitItem,
905 ))
906 } else {
907 Err(TryParseFailure::SkipToken)
908 }
909 }
910 }
911 }
912
913 fn expect_trait_item_function(
916 &mut self,
917 attributes: AttributeListGreen,
918 optional_const: OptionTerminalConstGreen,
919 ) -> TraitItemFunctionGreen {
920 let declaration = self.expect_function_declaration(optional_const);
921 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
922 self.parse_block().into()
923 } else {
924 self.parse_token::<TerminalSemicolon>().into()
925 };
926 TraitItemFunction::new_green(self.db, attributes, declaration, body)
927 }
928
929 fn expect_trait_item_type(&mut self, attributes: AttributeListGreen) -> TraitItemTypeGreen {
932 let type_kw = self.take::<TerminalType>();
933 let name = self.parse_identifier();
934 let generic_params = self.parse_optional_generic_params();
935 let semicolon = self.parse_token::<TerminalSemicolon>();
936 TraitItemType::new_green(self.db, attributes, type_kw, name, generic_params, semicolon)
937 }
938
939 fn expect_trait_item_const(
942 &mut self,
943 attributes: AttributeListGreen,
944 const_kw: TerminalConstGreen,
945 ) -> TraitItemConstantGreen {
946 let name = self.parse_identifier();
947 let type_clause = self.parse_type_clause(ErrorRecovery {
948 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
949 });
950 let semicolon = self.parse_token::<TerminalSemicolon>();
951
952 TraitItemConstant::new_green(self.db, attributes, const_kw, name, type_clause, semicolon)
953 }
954
955 fn expect_trait_item_impl(&mut self, attributes: AttributeListGreen) -> TraitItemImplGreen {
958 let impl_kw = self.take::<TerminalImpl>();
959 let name = self.parse_identifier();
960 let colon = self.parse_token::<TerminalColon>();
961 let trait_path = self.parse_type_path();
962 let semicolon = self.parse_token::<TerminalSemicolon>();
963 TraitItemImpl::new_green(self.db, attributes, impl_kw, name, colon, trait_path, semicolon)
964 }
965
966 fn expect_module_item_impl(
968 &mut self,
969 attributes: AttributeListGreen,
970 visibility: VisibilityGreen,
971 ) -> ModuleItemGreen {
972 match self.expect_item_impl_inner(attributes, visibility, false) {
973 ImplItemOrAlias::Item(green) => green.into(),
974 ImplItemOrAlias::Alias(green) => green.into(),
975 }
976 }
977
978 fn expect_impl_item_impl(
981 &mut self,
982 attributes: AttributeListGreen,
983 visibility: VisibilityGreen,
984 ) -> ItemImplAliasGreen {
985 extract_matches!(
986 self.expect_item_impl_inner(attributes, visibility, true),
987 ImplItemOrAlias::Alias
988 )
989 }
990
991 fn expect_item_impl_inner(
996 &mut self,
997 attributes: AttributeListGreen,
998 visibility: VisibilityGreen,
999 only_allow_alias: bool,
1000 ) -> ImplItemOrAlias {
1001 let impl_kw = self.take::<TerminalImpl>();
1002 let name = self.parse_identifier();
1003 let generic_params = self.parse_optional_generic_params();
1004
1005 if self.peek().kind == SyntaxKind::TerminalEq || only_allow_alias {
1006 let eq = self.parse_token::<TerminalEq>();
1007 let impl_path = self.parse_type_path();
1008 let semicolon = self.parse_token::<TerminalSemicolon>();
1009
1010 return ImplItemOrAlias::Alias(ItemImplAlias::new_green(
1011 self.db,
1012 attributes,
1013 visibility,
1014 impl_kw,
1015 name,
1016 generic_params,
1017 eq,
1018 impl_path,
1019 semicolon,
1020 ));
1021 }
1022
1023 let of_kw = self.parse_token::<TerminalOf>();
1024 let trait_path = self.parse_type_path();
1025 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1026 let lbrace = self.take::<TerminalLBrace>();
1027 let items = ImplItemList::new_green(
1028 self.db,
1029 self.parse_attributed_list(
1030 Self::try_parse_impl_item,
1031 is_of_kind!(rbrace),
1032 IMPL_ITEM_DESCRIPTION,
1033 ),
1034 );
1035 let rbrace = self.parse_token::<TerminalRBrace>();
1036 ImplBody::new_green(self.db, lbrace, items, rbrace).into()
1037 } else {
1038 self.parse_token::<TerminalSemicolon>().into()
1039 };
1040
1041 ImplItemOrAlias::Item(ItemImpl::new_green(
1042 self.db,
1043 attributes,
1044 visibility,
1045 impl_kw,
1046 name,
1047 generic_params,
1048 of_kw,
1049 trait_path,
1050 body,
1051 ))
1052 }
1053
1054 pub fn try_parse_impl_item(&mut self) -> TryParseResult<ImplItemGreen> {
1057 let maybe_attributes = self.try_parse_attribute_list(IMPL_ITEM_DESCRIPTION);
1058
1059 let (has_attrs, attributes) = match maybe_attributes {
1060 Ok(attributes) => (true, attributes),
1061 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
1062 };
1063
1064 let visibility = VisibilityDefault::new_green(self.db).into();
1067
1068 match self.peek().kind {
1069 SyntaxKind::TerminalFunction => Ok(self
1070 .expect_item_function_with_body(
1071 attributes,
1072 visibility,
1073 OptionTerminalConstEmpty::new_green(self.db).into(),
1074 )
1075 .into()),
1076 SyntaxKind::TerminalType => {
1077 Ok(self.expect_item_type_alias(attributes, visibility).into())
1078 }
1079 SyntaxKind::TerminalConst => {
1080 let const_kw = self.take::<TerminalConst>();
1081 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
1082 self.expect_item_function_with_body(attributes, visibility, const_kw.into())
1083 .into()
1084 } else {
1085 self.expect_item_const(attributes, visibility, const_kw).into()
1086 })
1087 }
1088 SyntaxKind::TerminalImpl => {
1089 Ok(self.expect_impl_item_impl(attributes, visibility).into())
1090 }
1091 SyntaxKind::TerminalModule => {
1093 Ok(self.expect_item_module(attributes, visibility).into())
1094 }
1095 SyntaxKind::TerminalStruct => {
1096 Ok(self.expect_item_struct(attributes, visibility).into())
1097 }
1098 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
1099 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
1100 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
1101 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
1102 _ => {
1103 if has_attrs {
1104 Ok(self.skip_taken_node_and_return_missing::<ImplItem>(
1105 attributes,
1106 ParserDiagnosticKind::AttributesWithoutImplItem,
1107 ))
1108 } else {
1109 Err(TryParseFailure::SkipToken)
1110 }
1111 }
1112 }
1113 }
1114
1115 fn expect_item_inline_macro(
1117 &mut self,
1118 attributes: AttributeListGreen,
1119 name: TerminalIdentifierGreen,
1120 ) -> ItemInlineMacroGreen {
1121 let bang = self.parse_token::<TerminalNot>();
1122 self.parse_item_inline_macro_given_bang(attributes, name, bang)
1123 }
1124
1125 fn parse_item_inline_macro_given_bang(
1127 &mut self,
1128 attributes: AttributeListGreen,
1129 name: TerminalIdentifierGreen,
1130 bang: TerminalNotGreen,
1131 ) -> ItemInlineMacroGreen {
1132 let arguments = self.parse_wrapped_arg_list();
1133 let semicolon = self.parse_token::<TerminalSemicolon>();
1134 ItemInlineMacro::new_green(self.db, attributes, name, bang, arguments, semicolon)
1135 }
1136
1137 fn try_parse_expr(&mut self) -> TryParseResult<ExprGreen> {
1142 self.try_parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Allow)
1143 }
1144 pub fn parse_expr(&mut self) -> ExprGreen {
1147 match self.try_parse_expr() {
1148 Ok(green) => green,
1149 Err(_) => {
1150 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1151 }
1152 }
1153 }
1154
1155 fn parse_binary_operator(&mut self) -> BinaryOperatorGreen {
1159 match self.peek().kind {
1162 SyntaxKind::TerminalDot => self.take::<TerminalDot>().into(),
1163 SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1164 SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq>().into(),
1165 SyntaxKind::TerminalDiv => self.take::<TerminalDiv>().into(),
1166 SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq>().into(),
1167 SyntaxKind::TerminalMod => self.take::<TerminalMod>().into(),
1168 SyntaxKind::TerminalModEq => self.take::<TerminalModEq>().into(),
1169 SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
1170 SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq>().into(),
1171 SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1172 SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq>().into(),
1173 SyntaxKind::TerminalEq => self.take::<TerminalEq>().into(),
1174 SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq>().into(),
1175 SyntaxKind::TerminalNeq => self.take::<TerminalNeq>().into(),
1176 SyntaxKind::TerminalLT => self.take::<TerminalLT>().into(),
1177 SyntaxKind::TerminalGT => self.take::<TerminalGT>().into(),
1178 SyntaxKind::TerminalLE => self.take::<TerminalLE>().into(),
1179 SyntaxKind::TerminalGE => self.take::<TerminalGE>().into(),
1180 SyntaxKind::TerminalAnd => self.take::<TerminalAnd>().into(),
1181 SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd>().into(),
1182 SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr>().into(),
1183 SyntaxKind::TerminalOr => self.take::<TerminalOr>().into(),
1184 SyntaxKind::TerminalXor => self.take::<TerminalXor>().into(),
1185 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
1186 SyntaxKind::TerminalDotDotEq => self.take::<TerminalDotDotEq>().into(),
1187 _ => unreachable!(),
1188 }
1189 }
1190
1191 fn expect_unary_operator(&mut self) -> UnaryOperatorGreen {
1193 match self.peek().kind {
1194 SyntaxKind::TerminalAt => self.take::<TerminalAt>().into(),
1195 SyntaxKind::TerminalNot => self.take::<TerminalNot>().into(),
1196 SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot>().into(),
1197 SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1198 SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1199 _ => unreachable!(),
1200 }
1201 }
1202
1203 fn is_comparison_operator(&self, kind: SyntaxKind) -> bool {
1215 matches!(
1216 kind,
1217 SyntaxKind::TerminalLT
1218 | SyntaxKind::TerminalGT
1219 | SyntaxKind::TerminalLE
1220 | SyntaxKind::TerminalGE
1221 | SyntaxKind::TerminalEqEq
1222 | SyntaxKind::TerminalNeq
1223 )
1224 }
1225
1226 fn try_parse_expr_limited(
1233 &mut self,
1234 parent_precedence: usize,
1235 lbrace_allowed: LbraceAllowed,
1236 ) -> TryParseResult<ExprGreen> {
1237 let mut expr = self.try_parse_atom_or_unary(lbrace_allowed)?;
1238 let mut child_op: Option<SyntaxKind> = None;
1239 while let Some(precedence) = get_post_operator_precedence(self.peek().kind) {
1240 if precedence >= parent_precedence {
1241 return Ok(expr);
1242 }
1243 expr = if self.peek().kind == SyntaxKind::TerminalQuestionMark {
1244 ExprErrorPropagate::new_green(self.db, expr, self.take::<TerminalQuestionMark>())
1245 .into()
1246 } else if self.peek().kind == SyntaxKind::TerminalLBrack {
1247 let lbrack = self.take::<TerminalLBrack>();
1248 let index_expr = self.parse_expr();
1249 let rbrack = self.parse_token::<TerminalRBrack>();
1250 ExprIndexed::new_green(self.db, expr, lbrack, index_expr, rbrack).into()
1251 } else {
1252 let current_op = self.peek().kind;
1253 if let Some(child_op_kind) = child_op {
1254 if self.is_comparison_operator(child_op_kind)
1255 && self.is_comparison_operator(current_op)
1256 {
1257 self.add_diagnostic(
1258 ParserDiagnosticKind::ConsecutiveMathOperators {
1259 first_op: child_op_kind,
1260 second_op: current_op,
1261 },
1262 TextSpan { start: self.offset, end: self.offset },
1263 );
1264 }
1265 }
1266 child_op = Some(current_op);
1267 let op = self.parse_binary_operator();
1268 let rhs = self.parse_expr_limited(precedence, lbrace_allowed);
1269 ExprBinary::new_green(self.db, expr, op, rhs).into()
1270 };
1271 }
1272 Ok(expr)
1273 }
1274
1275 fn try_parse_atom_or_unary(
1281 &mut self,
1282 lbrace_allowed: LbraceAllowed,
1283 ) -> TryParseResult<ExprGreen> {
1284 let Some(precedence) = get_unary_operator_precedence(self.peek().kind) else {
1285 return self.try_parse_atom(lbrace_allowed);
1286 };
1287 let op = self.expect_unary_operator();
1288 let expr = self.parse_expr_limited(precedence, lbrace_allowed);
1289 Ok(ExprUnary::new_green(self.db, op, expr).into())
1290 }
1291
1292 fn parse_expr_limited(
1297 &mut self,
1298 parent_precedence: usize,
1299 lbrace_allowed: LbraceAllowed,
1300 ) -> ExprGreen {
1301 match self.try_parse_expr_limited(parent_precedence, lbrace_allowed) {
1302 Ok(green) => green,
1303 Err(_) => {
1304 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1305 }
1306 }
1307 }
1308
1309 fn try_parse_atom(&mut self, lbrace_allowed: LbraceAllowed) -> TryParseResult<ExprGreen> {
1315 match self.peek().kind {
1317 SyntaxKind::TerminalIdentifier => {
1318 let path = self.parse_path();
1320 match self.peek().kind {
1321 SyntaxKind::TerminalLParen => Ok(self.expect_function_call(path).into()),
1322 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1323 Ok(self.expect_constructor_call(path).into())
1324 }
1325 SyntaxKind::TerminalNot => Ok(self.expect_macro_call(path).into()),
1326 _ => Ok(path.into()),
1327 }
1328 }
1329 SyntaxKind::TerminalFalse => Ok(self.take::<TerminalFalse>().into()),
1330 SyntaxKind::TerminalTrue => Ok(self.take::<TerminalTrue>().into()),
1331 SyntaxKind::TerminalLiteralNumber => Ok(self.take_terminal_literal_number().into()),
1332 SyntaxKind::TerminalShortString => Ok(self.take_terminal_short_string().into()),
1333 SyntaxKind::TerminalString => Ok(self.take_terminal_string().into()),
1334 SyntaxKind::TerminalLParen => {
1335 Ok(self.expect_parenthesized_expr())
1338 }
1339 SyntaxKind::TerminalLBrack => Ok(self.expect_fixed_size_array_expr().into()),
1340 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1341 Ok(self.parse_block().into())
1342 }
1343 SyntaxKind::TerminalMatch if lbrace_allowed == LbraceAllowed::Allow => {
1344 Ok(self.expect_match_expr().into())
1345 }
1346 SyntaxKind::TerminalIf if lbrace_allowed == LbraceAllowed::Allow => {
1347 Ok(self.expect_if_expr().into())
1348 }
1349 SyntaxKind::TerminalLoop if lbrace_allowed == LbraceAllowed::Allow => {
1350 Ok(self.expect_loop_expr().into())
1351 }
1352 SyntaxKind::TerminalWhile if lbrace_allowed == LbraceAllowed::Allow => {
1353 Ok(self.expect_while_expr().into())
1354 }
1355 SyntaxKind::TerminalFor if lbrace_allowed == LbraceAllowed::Allow => {
1356 Ok(self.expect_for_expr().into())
1357 }
1358 SyntaxKind::TerminalOr if lbrace_allowed == LbraceAllowed::Allow => {
1359 Ok(self.expect_closure_expr_nary().into())
1360 }
1361 SyntaxKind::TerminalOrOr if lbrace_allowed == LbraceAllowed::Allow => {
1362 Ok(self.expect_closure_expr_nullary().into())
1363 }
1364
1365 _ => {
1366 Err(TryParseFailure::SkipToken)
1368 }
1369 }
1370 }
1371
1372 fn try_parse_type_expr(&mut self) -> TryParseResult<ExprGreen> {
1375 match self.peek().kind {
1377 SyntaxKind::TerminalAt => {
1378 let op = self.take::<TerminalAt>().into();
1379 let expr = self.parse_type_expr();
1380 Ok(ExprUnary::new_green(self.db, op, expr).into())
1381 }
1382 SyntaxKind::TerminalIdentifier => Ok(self.parse_type_path().into()),
1383 SyntaxKind::TerminalLParen => Ok(self.expect_type_tuple_expr()),
1384 SyntaxKind::TerminalLBrack => Ok(self.expect_type_fixed_size_array_expr()),
1385 _ => {
1386 Err(TryParseFailure::SkipToken)
1388 }
1389 }
1390 }
1391
1392 fn parse_type_expr(&mut self) -> ExprGreen {
1395 match self.try_parse_type_expr() {
1396 Ok(expr) => expr,
1397 Err(_) => {
1398 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingTypeExpression)
1399 }
1400 }
1401 }
1402
1403 fn expect_struct_ctor_argument_list_braced(&mut self) -> StructArgListBracedGreen {
1406 let lbrace = self.take::<TerminalLBrace>();
1407 let arg_list = StructArgList::new_green(
1408 self.db,
1409 self.parse_separated_list::<StructArg, TerminalComma, StructArgListElementOrSeparatorGreen>(
1410 Self::try_parse_struct_ctor_argument,
1411 is_of_kind!(rparen, block, rbrace, module_item_kw),
1412 "struct constructor argument",
1413 ),
1414 );
1415 let rbrace = self.parse_token::<TerminalRBrace>();
1416
1417 StructArgListBraced::new_green(self.db, lbrace, arg_list, rbrace)
1418 }
1419
1420 fn expect_function_call(&mut self, path: ExprPathGreen) -> ExprFunctionCallGreen {
1423 let func_name = path;
1424 let parenthesized_args = self.expect_parenthesized_argument_list();
1425 ExprFunctionCall::new_green(self.db, func_name, parenthesized_args)
1426 }
1427
1428 fn expect_macro_call(&mut self, path: ExprPathGreen) -> ExprInlineMacroGreen {
1431 let bang = self.take::<TerminalNot>();
1432 let macro_name = path;
1433 let wrapped_expr_list = self.parse_wrapped_arg_list();
1434 ExprInlineMacro::new_green(self.db, macro_name, bang, wrapped_expr_list)
1435 }
1436
1437 fn parse_wrapped_arg_list(&mut self) -> WrappedArgListGreen {
1440 let current_token = self.peek().kind;
1441 match current_token {
1442 SyntaxKind::TerminalLParen => self
1443 .expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1444 ArgListParenthesized::new_green,
1445 )
1446 .into(),
1447 SyntaxKind::TerminalLBrack => self
1448 .expect_wrapped_argument_list::<TerminalLBrack, TerminalRBrack, _, _>(
1449 ArgListBracketed::new_green,
1450 )
1451 .into(),
1452 SyntaxKind::TerminalLBrace => self
1453 .expect_wrapped_argument_list::<TerminalLBrace, TerminalRBrace, _, _>(
1454 ArgListBraced::new_green,
1455 )
1456 .into(),
1457 _ => self.create_and_report_missing::<WrappedArgList>(
1458 ParserDiagnosticKind::MissingWrappedArgList,
1459 ),
1460 }
1461 }
1462
1463 fn expect_wrapped_argument_list<
1468 LTerminal: syntax::node::Terminal,
1469 RTerminal: syntax::node::Terminal,
1470 ListGreen,
1471 NewGreen: Fn(&dyn SyntaxGroup, LTerminal::Green, ArgListGreen, RTerminal::Green) -> ListGreen,
1472 >(
1473 &mut self,
1474 new_green: NewGreen,
1475 ) -> ListGreen {
1476 let l_term = self.take::<LTerminal>();
1477 let exprs: Vec<ArgListElementOrSeparatorGreen> = self
1478 .parse_separated_list::<Arg, TerminalComma, ArgListElementOrSeparatorGreen>(
1479 Self::try_parse_function_argument,
1480 is_of_kind!(rparen, rbrace, rbrack, block, module_item_kw),
1481 "argument",
1482 );
1483 let r_term: <RTerminal as TypedSyntaxNode>::Green = self.parse_token::<RTerminal>();
1484 new_green(self.db, l_term, ArgList::new_green(self.db, exprs), r_term)
1485 }
1486
1487 fn expect_parenthesized_argument_list(&mut self) -> ArgListParenthesizedGreen {
1490 self.expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1491 ArgListParenthesized::new_green,
1492 )
1493 }
1494
1495 fn try_parse_parenthesized_argument_list(&mut self) -> OptionArgListParenthesizedGreen {
1498 if self.peek().kind == SyntaxKind::TerminalLParen {
1499 self.expect_parenthesized_argument_list().into()
1500 } else {
1501 OptionArgListParenthesizedEmpty::new_green(self.db).into()
1502 }
1503 }
1504
1505 fn try_parse_function_argument(&mut self) -> TryParseResult<ArgGreen> {
1507 let modifiers_list = self.parse_modifier_list();
1508 let arg_clause = self.try_parse_argument_clause();
1509 match arg_clause {
1510 Ok(arg_clause) => {
1511 let modifiers = ModifierList::new_green(self.db, modifiers_list);
1512 Ok(Arg::new_green(self.db, modifiers, arg_clause))
1513 }
1514 Err(_) if !modifiers_list.is_empty() => {
1515 let modifiers = ModifierList::new_green(self.db, modifiers_list);
1516 let arg_clause = ArgClauseUnnamed::new_green(self.db, self.parse_expr()).into();
1517 Ok(Arg::new_green(self.db, modifiers, arg_clause))
1518 }
1519 Err(err) => Err(err),
1520 }
1521 }
1522
1523 fn try_parse_argument_clause(&mut self) -> TryParseResult<ArgClauseGreen> {
1531 if self.peek().kind == SyntaxKind::TerminalColon {
1532 let colon = self.take::<TerminalColon>();
1533 let name = self.parse_identifier();
1534 return Ok(ArgClauseFieldInitShorthand::new_green(
1535 self.db,
1536 colon,
1537 ExprFieldInitShorthand::new_green(self.db, name),
1538 )
1539 .into());
1540 }
1541
1542 let value = self.try_parse_expr()?;
1544
1545 if self.peek().kind == SyntaxKind::TerminalColon {
1548 if let Some(argname) = self.try_extract_identifier(value) {
1549 let colon = self.take::<TerminalColon>();
1550 let expr = self.parse_expr();
1551 return Ok(ArgClauseNamed::new_green(self.db, argname, colon, expr).into());
1552 }
1553 }
1554
1555 Ok(ArgClauseUnnamed::new_green(self.db, value).into())
1556 }
1557
1558 fn try_extract_identifier(&self, expr: ExprGreen) -> Option<TerminalIdentifierGreen> {
1561 let GreenNode {
1563 kind: SyntaxKind::ExprPath,
1564 details: GreenNodeDetails::Node { children: children0, .. },
1565 } = &*expr.0.lookup_intern(self.db)
1566 else {
1567 return None;
1568 };
1569
1570 let [path_segment] = children0[..] else {
1572 return None;
1573 };
1574
1575 let GreenNode {
1577 kind: SyntaxKind::PathSegmentSimple,
1578 details: GreenNodeDetails::Node { children: children1, .. },
1579 } = &*path_segment.lookup_intern(self.db)
1580 else {
1581 return None;
1582 };
1583
1584 let [ident] = children1[..] else {
1586 return None;
1587 };
1588
1589 let GreenNode { kind: SyntaxKind::TerminalIdentifier, .. } =
1591 ident.lookup_intern(self.db).as_ref()
1592 else {
1593 return None;
1594 };
1595
1596 Some(TerminalIdentifierGreen(ident))
1597 }
1598
1599 fn expect_constructor_call(&mut self, path: ExprPathGreen) -> ExprStructCtorCallGreen {
1602 let ctor_name = path;
1603 let args = self.expect_struct_ctor_argument_list_braced();
1604 ExprStructCtorCall::new_green(self.db, ctor_name, args)
1605 }
1606
1607 fn expect_parenthesized_expr(&mut self) -> ExprGreen {
1611 let lparen = self.take::<TerminalLParen>();
1612 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1613 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1614 Self::try_parse_expr,
1615 is_of_kind!(rparen, block, rbrace, module_item_kw),
1616 "expression",
1617 );
1618 let rparen = self.parse_token::<TerminalRParen>();
1619
1620 if let [ExprListElementOrSeparatorGreen::Element(expr)] = &exprs[..] {
1621 ExprParenthesized::new_green(self.db, lparen, *expr, rparen).into()
1623 } else {
1624 ExprListParenthesized::new_green(
1625 self.db,
1626 lparen,
1627 ExprList::new_green(self.db, exprs),
1628 rparen,
1629 )
1630 .into()
1631 }
1632 }
1633
1634 fn expect_type_tuple_expr(&mut self) -> ExprGreen {
1638 let lparen = self.take::<TerminalLParen>();
1639 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1640 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1641 Self::try_parse_type_expr,
1642 is_of_kind!(rparen, block, rbrace, module_item_kw),
1643 "type expression",
1644 );
1645 let rparen = self.parse_token::<TerminalRParen>();
1646 if let [ExprListElementOrSeparatorGreen::Element(_)] = &exprs[..] {
1647 self.add_diagnostic(
1648 ParserDiagnosticKind::MissingToken(SyntaxKind::TokenComma),
1649 TextSpan { start: self.offset, end: self.offset },
1650 );
1651 }
1652 ExprListParenthesized::new_green(
1653 self.db,
1654 lparen,
1655 ExprList::new_green(self.db, exprs),
1656 rparen,
1657 )
1658 .into()
1659 }
1660
1661 fn expect_type_fixed_size_array_expr(&mut self) -> ExprGreen {
1665 let lbrack = self.take::<TerminalLBrack>();
1666 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1667 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1668 Self::try_parse_type_expr,
1669 is_of_kind!(rbrack, semicolon),
1670 "type expression",
1671 );
1672 let semicolon = self.parse_token::<TerminalSemicolon>();
1673 let size_expr = self.parse_expr();
1674 let fixed_size_array_size =
1675 FixedSizeArraySize::new_green(self.db, semicolon, size_expr).into();
1676 let rbrack = self.parse_token::<TerminalRBrack>();
1677 ExprFixedSizeArray::new_green(
1678 self.db,
1679 lbrack,
1680 ExprList::new_green(self.db, exprs),
1681 fixed_size_array_size,
1682 rbrack,
1683 )
1684 .into()
1685 }
1686
1687 fn expect_struct_argument_tail(&mut self) -> StructArgTailGreen {
1690 let dotdot = self.take::<TerminalDotDot>(); let expr = self.parse_expr();
1693 StructArgTail::new_green(self.db, dotdot, expr)
1694 }
1695
1696 fn try_parse_struct_ctor_argument(&mut self) -> TryParseResult<StructArgGreen> {
1701 match self.peek().kind {
1702 SyntaxKind::TerminalDotDot => Ok(self.expect_struct_argument_tail().into()),
1703 _ => self.try_parse_argument_single().map(|arg| arg.into()),
1704 }
1705 }
1706
1707 fn parse_option_struct_arg_expression(&mut self) -> OptionStructArgExprGreen {
1710 if self.peek().kind == SyntaxKind::TerminalColon {
1711 let colon = self.take::<TerminalColon>();
1712 let value = self.parse_expr();
1713 StructArgExpr::new_green(self.db, colon, value).into()
1714 } else {
1715 OptionStructArgExprEmpty::new_green(self.db).into()
1716 }
1717 }
1718
1719 fn parse_option_expression_clause(&mut self) -> OptionExprClauseGreen {
1722 if self.peek().kind == SyntaxKind::TerminalSemicolon {
1723 OptionExprClauseEmpty::new_green(self.db).into()
1724 } else {
1725 let value = self.parse_expr();
1726 ExprClause::new_green(self.db, value).into()
1727 }
1728 }
1729
1730 fn try_parse_argument_single(&mut self) -> TryParseResult<StructArgSingleGreen> {
1732 let identifier = self.try_parse_identifier()?;
1733 let struct_arg_expr = self.parse_option_struct_arg_expression(); Ok(StructArgSingle::new_green(self.db, identifier, struct_arg_expr))
1735 }
1736
1737 fn parse_block(&mut self) -> ExprBlockGreen {
1739 let skipped_tokens = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
1740
1741 if let Err(SkippedError(span)) = skipped_tokens {
1742 self.add_diagnostic(
1743 ParserDiagnosticKind::SkippedElement { element_name: "'{'".into() },
1744 span,
1745 );
1746 }
1747
1748 let is_rbrace_or_top_level = is_of_kind!(rbrace, module_item_kw);
1749 if is_rbrace_or_top_level(self.peek().kind) {
1750 return ExprBlock::new_green(
1751 self.db,
1752 self.create_and_report_missing_terminal::<TerminalLBrace>(),
1753 StatementList::new_green(self.db, vec![]),
1754 TerminalRBrace::missing(self.db),
1755 );
1756 }
1757 let lbrace = self.parse_token_ex::<TerminalLBrace>(skipped_tokens.is_ok());
1759 let statements = StatementList::new_green(
1760 self.db,
1761 self.parse_list(
1762 Self::try_parse_statement,
1763 is_of_kind!(rbrace, module_item_kw),
1764 "statement",
1765 ),
1766 );
1767 let rbrace = self.parse_token::<TerminalRBrace>();
1768 ExprBlock::new_green(self.db, lbrace, statements, rbrace)
1769 }
1770
1771 fn expect_match_expr(&mut self) -> ExprMatchGreen {
1774 let match_kw = self.take::<TerminalMatch>();
1775 let expr = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1776 let lbrace = self.parse_token::<TerminalLBrace>();
1777 let arms = MatchArms::new_green(
1778 self.db,
1779 self.parse_separated_list::<MatchArm, TerminalComma, MatchArmsElementOrSeparatorGreen>(
1780 Self::try_parse_match_arm,
1781 is_of_kind!(block, rbrace, module_item_kw),
1782 "match arm",
1783 ),
1784 );
1785 let rbrace = self.parse_token::<TerminalRBrace>();
1786 ExprMatch::new_green(self.db, match_kw, expr, lbrace, arms, rbrace)
1787 }
1788
1789 fn expect_if_expr(&mut self) -> ExprIfGreen {
1791 let if_kw = self.take::<TerminalIf>();
1792
1793 let condition = self.parse_condition_expr();
1794 let if_block = self.parse_block();
1795 let else_clause = if self.peek().kind == SyntaxKind::TerminalElse {
1796 let else_kw = self.take::<TerminalElse>();
1797 let else_block_or_if = if self.peek().kind == SyntaxKind::TerminalIf {
1798 self.expect_if_expr().into()
1799 } else {
1800 self.parse_block().into()
1801 };
1802 ElseClause::new_green(self.db, else_kw, else_block_or_if).into()
1803 } else {
1804 OptionElseClauseEmpty::new_green(self.db).into()
1805 };
1806 ExprIf::new_green(self.db, if_kw, condition, if_block, else_clause)
1807 }
1808
1809 fn parse_condition_expr(&mut self) -> ConditionGreen {
1811 if self.peek().kind == SyntaxKind::TerminalLet {
1812 let let_kw = self.take::<TerminalLet>();
1813 let pattern_list = self
1814 .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
1815 Self::try_parse_pattern,
1816 is_of_kind!(eq),
1817 "pattern",
1818 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
1819 );
1820
1821 let pattern_list_green = if pattern_list.is_empty() {
1822 self.create_and_report_missing::<PatternListOr>(
1823 ParserDiagnosticKind::MissingPattern,
1824 )
1825 } else {
1826 PatternListOr::new_green(self.db, pattern_list)
1827 };
1828 let eq = self.parse_token::<TerminalEq>();
1829 let expr: ExprGreen = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1830 ConditionLet::new_green(self.db, let_kw, pattern_list_green, eq, expr).into()
1831 } else {
1832 let condition = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1833 ConditionExpr::new_green(self.db, condition).into()
1834 }
1835 }
1836
1837 fn expect_loop_expr(&mut self) -> ExprLoopGreen {
1840 let loop_kw = self.take::<TerminalLoop>();
1841 let body = self.parse_block();
1842
1843 ExprLoop::new_green(self.db, loop_kw, body)
1844 }
1845
1846 fn expect_while_expr(&mut self) -> ExprWhileGreen {
1849 let while_kw = self.take::<TerminalWhile>();
1850 let condition = self.parse_condition_expr();
1851 let body = self.parse_block();
1852
1853 ExprWhile::new_green(self.db, while_kw, condition, body)
1854 }
1855
1856 fn expect_for_expr(&mut self) -> ExprForGreen {
1860 let for_kw = self.take::<TerminalFor>();
1861 let pattern = self.parse_pattern();
1862 let ident = self.take_raw();
1863 let in_identifier: TerminalIdentifierGreen = match ident.text.as_str() {
1864 "in" => self.add_trivia_to_terminal::<TerminalIdentifier>(ident),
1865 _ => {
1866 self.append_skipped_token_to_pending_trivia(
1867 ident,
1868 ParserDiagnosticKind::SkippedElement { element_name: "'in'".into() },
1869 );
1870 TerminalIdentifier::missing(self.db)
1871 }
1872 };
1873 let expression = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1874 let body = self.parse_block();
1875 ExprFor::new_green(self.db, for_kw, pattern, in_identifier, expression, body)
1876 }
1877
1878 fn expect_closure_expr_nary(&mut self) -> ExprClosureGreen {
1881 let leftor = self.take::<TerminalOr>();
1882 let params = self.parse_closure_param_list();
1883 let rightor = self.parse_token::<TerminalOr>();
1884
1885 self.parse_closure_expr_body(
1886 ClosureParamWrapperNAry::new_green(self.db, leftor, params, rightor).into(),
1887 )
1888 }
1889 fn expect_closure_expr_nullary(&mut self) -> ExprClosureGreen {
1892 let wrapper = self.take::<TerminalOrOr>().into();
1893 self.parse_closure_expr_body(wrapper)
1894 }
1895 fn parse_closure_expr_body(&mut self, wrapper: ClosureParamWrapperGreen) -> ExprClosureGreen {
1896 let mut block_required = self.peek().kind == SyntaxKind::TerminalArrow;
1897
1898 let return_type_clause = self.parse_option_return_type_clause();
1899 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
1900 block_required = true;
1901 self.take::<TerminalNoPanic>().into()
1902 } else {
1903 OptionTerminalNoPanicEmpty::new_green(self.db).into()
1904 };
1905 let expr = if block_required { self.parse_block().into() } else { self.parse_expr() };
1906
1907 ExprClosure::new_green(self.db, wrapper, return_type_clause, optional_no_panic, expr)
1908 }
1909
1910 fn expect_fixed_size_array_expr(&mut self) -> ExprFixedSizeArrayGreen {
1913 let lbrack = self.take::<TerminalLBrack>();
1914 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1915 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1916 Self::try_parse_expr,
1917 is_of_kind!(rbrack, semicolon),
1918 "expression",
1919 );
1920 let size_green = if self.peek().kind == SyntaxKind::TerminalSemicolon {
1921 let semicolon = self.take::<TerminalSemicolon>();
1922 let size = self.parse_expr();
1923 FixedSizeArraySize::new_green(self.db, semicolon, size).into()
1924 } else {
1925 OptionFixedSizeArraySizeEmpty::new_green(self.db).into()
1926 };
1927 let rbrack = self.parse_token::<TerminalRBrack>();
1928 ExprFixedSizeArray::new_green(
1929 self.db,
1930 lbrack,
1931 ExprList::new_green(self.db, exprs),
1932 size_green,
1933 rbrack,
1934 )
1935 }
1936
1937 pub fn try_parse_match_arm(&mut self) -> TryParseResult<MatchArmGreen> {
1940 let pattern_list = self
1941 .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
1942 Self::try_parse_pattern,
1943 is_of_kind!(match_arrow, rparen, block, rbrace, module_item_kw),
1944 "pattern",
1945 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
1946 );
1947 if pattern_list.is_empty() {
1948 return Err(TryParseFailure::SkipToken);
1949 }
1950
1951 let pattern_list_green = PatternListOr::new_green(self.db, pattern_list);
1952
1953 let arrow = self.parse_token::<TerminalMatchArrow>();
1954 let expr = self.parse_expr();
1955 Ok(MatchArm::new_green(self.db, pattern_list_green, arrow, expr))
1956 }
1957
1958 fn try_parse_pattern(&mut self) -> TryParseResult<PatternGreen> {
1961 let modifier_list = self.parse_modifier_list();
1962 if !modifier_list.is_empty() {
1963 let modifiers = ModifierList::new_green(self.db, modifier_list);
1964 let name = self.parse_identifier();
1965 return Ok(PatternIdentifier::new_green(self.db, modifiers, name).into());
1966 };
1967
1968 Ok(match self.peek().kind {
1970 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
1971 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
1972 SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
1973 SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
1974 SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore>().into(),
1975 SyntaxKind::TerminalIdentifier => {
1976 let path = self.parse_path();
1979 match self.peek().kind {
1980 SyntaxKind::TerminalLBrace => {
1981 let lbrace = self.take::<TerminalLBrace>();
1982 let params = PatternStructParamList::new_green(
1983 self.db,
1984 self.parse_separated_list::<
1985 PatternStructParam,
1986 TerminalComma,
1987 PatternStructParamListElementOrSeparatorGreen>
1988 (
1989 Self::try_parse_pattern_struct_param,
1990 is_of_kind!(rparen, block, rbrace, module_item_kw),
1991 "struct pattern parameter",
1992 ),
1993 );
1994 let rbrace = self.parse_token::<TerminalRBrace>();
1995 PatternStruct::new_green(self.db, path, lbrace, params, rbrace).into()
1996 }
1997 SyntaxKind::TerminalLParen => {
1998 let lparen = self.take::<TerminalLParen>();
2000 let pattern = self.parse_pattern();
2001 let rparen = self.parse_token::<TerminalRParen>();
2002 let inner_pattern =
2003 PatternEnumInnerPattern::new_green(self.db, lparen, pattern, rparen);
2004 PatternEnum::new_green(self.db, path, inner_pattern.into()).into()
2005 }
2006 _ => {
2007 let green_node = path.0.lookup_intern(self.db);
2008 let children = match &green_node.details {
2009 GreenNodeDetails::Node { children, width: _ } => children,
2010 _ => return Err(TryParseFailure::SkipToken),
2011 };
2012 match children.len() {
2017 1 => path.into(),
2019 _ => PatternEnum::new_green(
2020 self.db,
2021 path,
2022 OptionPatternEnumInnerPatternEmpty::new_green(self.db).into(),
2023 )
2024 .into(),
2025 }
2026 }
2027 }
2028 }
2029 SyntaxKind::TerminalLParen => {
2030 let lparen = self.take::<TerminalLParen>();
2031 let patterns = PatternList::new_green(self.db, self.parse_separated_list::<
2032 Pattern,
2033 TerminalComma,
2034 PatternListElementOrSeparatorGreen>
2035 (
2036 Self::try_parse_pattern,
2037 is_of_kind!(rparen, block, rbrace, module_item_kw),
2038 "pattern",
2039 ));
2040 let rparen = self.parse_token::<TerminalRParen>();
2041 PatternTuple::new_green(self.db, lparen, patterns, rparen).into()
2042 }
2043 SyntaxKind::TerminalLBrack => {
2044 let lbrack = self.take::<TerminalLBrack>();
2045 let patterns = PatternList::new_green(self.db, self.parse_separated_list::<
2046 Pattern,
2047 TerminalComma,
2048 PatternListElementOrSeparatorGreen>
2049 (
2050 Self::try_parse_pattern,
2051 is_of_kind!(rbrack, block, rbrace, module_item_kw),
2052 "pattern",
2053 ));
2054 let rbrack = self.parse_token::<TerminalRBrack>();
2055 PatternFixedSizeArray::new_green(self.db, lbrack, patterns, rbrack).into()
2056 }
2057 _ => return Err(TryParseFailure::SkipToken),
2058 })
2059 }
2060 fn parse_pattern(&mut self) -> PatternGreen {
2063 match self.try_parse_pattern() {
2065 Ok(pattern) => pattern,
2066 Err(_) => self.create_and_report_missing_terminal::<TerminalUnderscore>().into(),
2067 }
2068 }
2069
2070 fn try_parse_pattern_struct_param(&mut self) -> TryParseResult<PatternStructParamGreen> {
2073 Ok(match self.peek().kind {
2074 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
2075 _ => {
2076 let modifier_list = self.parse_modifier_list();
2077 let name = if modifier_list.is_empty() {
2078 self.try_parse_identifier()?
2079 } else {
2080 self.parse_identifier()
2081 };
2082 let modifiers = ModifierList::new_green(self.db, modifier_list);
2083 if self.peek().kind == SyntaxKind::TerminalColon {
2084 let colon = self.take::<TerminalColon>();
2085 let pattern = self.parse_pattern();
2086 PatternStructParamWithExpr::new_green(self.db, modifiers, name, colon, pattern)
2087 .into()
2088 } else {
2089 PatternIdentifier::new_green(self.db, modifiers, name).into()
2090 }
2091 }
2092 })
2093 }
2094
2095 pub fn try_parse_statement(&mut self) -> TryParseResult<StatementGreen> {
2100 let maybe_attributes = self.try_parse_attribute_list("Statement");
2101 let (has_attrs, attributes) = match maybe_attributes {
2102 Ok(attributes) => (true, attributes),
2103 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
2104 };
2105 match self.peek().kind {
2106 SyntaxKind::TerminalLet => {
2107 let let_kw = self.take::<TerminalLet>();
2108 let pattern = self.parse_pattern();
2109 let type_clause = self.parse_option_type_clause();
2110 let eq = self.parse_token::<TerminalEq>();
2111 let rhs = self.parse_expr();
2112 let semicolon = self.parse_token::<TerminalSemicolon>();
2113 Ok(StatementLet::new_green(
2114 self.db,
2115 attributes,
2116 let_kw,
2117 pattern,
2118 type_clause,
2119 eq,
2120 rhs,
2121 semicolon,
2122 )
2123 .into())
2124 }
2125 SyntaxKind::TerminalContinue => {
2126 let continue_kw = self.take::<TerminalContinue>();
2127 let semicolon = self.parse_token::<TerminalSemicolon>();
2128 Ok(StatementContinue::new_green(self.db, attributes, continue_kw, semicolon).into())
2129 }
2130 SyntaxKind::TerminalReturn => {
2131 let return_kw = self.take::<TerminalReturn>();
2132 let expr = self.parse_option_expression_clause();
2133 let semicolon = self.parse_token::<TerminalSemicolon>();
2134 Ok(StatementReturn::new_green(self.db, attributes, return_kw, expr, semicolon)
2135 .into())
2136 }
2137 SyntaxKind::TerminalBreak => {
2138 let break_kw = self.take::<TerminalBreak>();
2139 let expr = self.parse_option_expression_clause();
2140 let semicolon = self.parse_token::<TerminalSemicolon>();
2141 Ok(StatementBreak::new_green(self.db, attributes, break_kw, expr, semicolon).into())
2142 }
2143 SyntaxKind::TerminalConst => {
2144 let const_kw = self.take::<TerminalConst>();
2145 Ok(StatementItem::new_green(
2146 self.db,
2147 self.expect_item_const(
2148 attributes,
2149 VisibilityDefault::new_green(self.db).into(),
2150 const_kw,
2151 )
2152 .into(),
2153 )
2154 .into())
2155 }
2156 SyntaxKind::TerminalUse => Ok(StatementItem::new_green(
2157 self.db,
2158 self.expect_item_use(attributes, VisibilityDefault::new_green(self.db).into())
2159 .into(),
2160 )
2161 .into()),
2162 SyntaxKind::TerminalType => Ok(StatementItem::new_green(
2163 self.db,
2164 self.expect_item_type_alias(
2165 attributes,
2166 VisibilityDefault::new_green(self.db).into(),
2167 )
2168 .into(),
2169 )
2170 .into()),
2171 _ => match self.try_parse_expr() {
2172 Ok(expr) => {
2173 let optional_semicolon = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2174 self.take::<TerminalSemicolon>().into()
2175 } else {
2176 OptionTerminalSemicolonEmpty::new_green(self.db).into()
2177 };
2178 Ok(StatementExpr::new_green(self.db, attributes, expr, optional_semicolon)
2179 .into())
2180 }
2181 Err(_) if has_attrs => Ok(self.skip_taken_node_and_return_missing::<Statement>(
2182 attributes,
2183 ParserDiagnosticKind::AttributesWithoutStatement,
2184 )),
2185 Err(err) => Err(err),
2186 },
2187 }
2188 }
2189
2190 fn parse_option_type_clause(&mut self) -> OptionTypeClauseGreen {
2193 match self.try_parse_type_clause() {
2194 Some(green) => green.into(),
2195 None => OptionTypeClauseEmpty::new_green(self.db).into(),
2196 }
2197 }
2198
2199 fn parse_type_clause(&mut self, error_recovery: ErrorRecovery) -> TypeClauseGreen {
2201 match self.try_parse_type_clause() {
2202 Some(green) => green,
2203 None => {
2204 let res = self.create_and_report_missing::<TypeClause>(
2205 ParserDiagnosticKind::MissingTypeClause,
2206 );
2207 self.skip_until(error_recovery.should_stop).ok();
2208 res
2209 }
2210 }
2211 }
2212 fn try_parse_type_clause(&mut self) -> Option<TypeClauseGreen> {
2213 if self.peek().kind == SyntaxKind::TerminalColon {
2214 let colon = self.take::<TerminalColon>();
2215 let ty = self.parse_type_expr();
2216 Some(TypeClause::new_green(self.db, colon, ty))
2217 } else {
2218 None
2219 }
2220 }
2221
2222 fn parse_option_return_type_clause(&mut self) -> OptionReturnTypeClauseGreen {
2225 if self.peek().kind == SyntaxKind::TerminalArrow {
2226 let arrow = self.take::<TerminalArrow>();
2227 let return_type = self.parse_type_expr();
2228 ReturnTypeClause::new_green(self.db, arrow, return_type).into()
2229 } else {
2230 OptionReturnTypeClauseEmpty::new_green(self.db).into()
2231 }
2232 }
2233
2234 fn parse_option_implicits_clause(&mut self) -> OptionImplicitsClauseGreen {
2237 if self.peek().kind == SyntaxKind::TerminalImplicits {
2238 let implicits_kw = self.take::<TerminalImplicits>();
2239 let lparen = self.parse_token::<TerminalLParen>();
2240 let implicits = ImplicitsList::new_green(
2241 self.db,
2242 self.parse_separated_list::<ExprPath, TerminalComma, ImplicitsListElementOrSeparatorGreen>(
2243 Self::try_parse_path,
2244 is_of_kind!(rparen, lbrace, rbrace),
2246 "implicit type",
2247 ),
2248 );
2249 let rparen = self.parse_token::<TerminalRParen>();
2250 ImplicitsClause::new_green(self.db, implicits_kw, lparen, implicits, rparen).into()
2251 } else {
2252 OptionImplicitsClauseEmpty::new_green(self.db).into()
2253 }
2254 }
2255
2256 fn parse_param_list(&mut self) -> ParamListGreen {
2258 ParamList::new_green(
2259 self.db,
2260 self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2261 Self::try_parse_param,
2262 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2263 "parameter",
2264 ),
2265 )
2266 }
2267
2268 fn parse_closure_param_list(&mut self) -> ParamListGreen {
2270 ParamList::new_green(
2271 self.db,
2272 self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2273 Self::try_parse_closure_param,
2274 is_of_kind!(or, block, lbrace, rbrace, module_item_kw),
2275 "parameter",
2276 ),
2277 )
2278 }
2279
2280 fn try_parse_modifier(&mut self) -> Option<ModifierGreen> {
2283 match self.peek().kind {
2284 SyntaxKind::TerminalRef => Some(self.take::<TerminalRef>().into()),
2285 SyntaxKind::TerminalMut => Some(self.take::<TerminalMut>().into()),
2286 _ => None,
2287 }
2288 }
2289
2290 fn parse_modifier_list(&mut self) -> Vec<ModifierGreen> {
2292 let mut modifier_list = vec![];
2293
2294 while let Some(modifier) = self.try_parse_modifier() {
2295 modifier_list.push(modifier);
2296 }
2297 modifier_list
2298 }
2299
2300 fn try_parse_param(&mut self) -> TryParseResult<ParamGreen> {
2303 let modifier_list = self.parse_modifier_list();
2304 let name = if modifier_list.is_empty() {
2305 self.try_parse_identifier()?
2306 } else {
2307 self.parse_identifier()
2309 };
2310
2311 let type_clause = self
2312 .parse_type_clause(ErrorRecovery {
2313 should_stop: is_of_kind!(comma, rparen, module_item_kw),
2314 })
2315 .into();
2316 Ok(Param::new_green(
2317 self.db,
2318 ModifierList::new_green(self.db, modifier_list),
2319 name,
2320 type_clause,
2321 ))
2322 }
2323
2324 fn try_parse_closure_param(&mut self) -> TryParseResult<ParamGreen> {
2327 let modifier_list = self.parse_modifier_list();
2328 let name = if modifier_list.is_empty() {
2329 self.try_parse_identifier()?
2330 } else {
2331 self.parse_identifier()
2333 };
2334
2335 let type_clause = self.parse_option_type_clause();
2336 Ok(Param::new_green(
2337 self.db,
2338 ModifierList::new_green(self.db, modifier_list),
2339 name,
2340 type_clause,
2341 ))
2342 }
2343
2344 fn parse_member_list(&mut self) -> MemberListGreen {
2346 MemberList::new_green(
2347 self.db,
2348 self.parse_separated_list::<Member, TerminalComma, MemberListElementOrSeparatorGreen>(
2349 Self::try_parse_member,
2350 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2351 "member or variant",
2352 ),
2353 )
2354 }
2355
2356 fn try_parse_member(&mut self) -> TryParseResult<MemberGreen> {
2359 let attributes = self.try_parse_attribute_list("Struct member");
2360 let visibility = self.parse_visibility();
2361 let (name, attributes) = match attributes {
2362 Ok(attributes) => (self.parse_identifier(), attributes),
2363 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, vec![])),
2364 };
2365 let type_clause = self.parse_type_clause(ErrorRecovery {
2366 should_stop: is_of_kind!(comma, rbrace, module_item_kw),
2367 });
2368 Ok(Member::new_green(self.db, attributes, visibility, name, type_clause))
2369 }
2370
2371 fn parse_variant_list(&mut self) -> VariantListGreen {
2373 VariantList::new_green(
2374 self.db,
2375 self.parse_separated_list::<Variant, TerminalComma, VariantListElementOrSeparatorGreen>(
2376 Self::try_parse_variant,
2377 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2378 "variant",
2379 ),
2380 )
2381 }
2382
2383 fn try_parse_variant(&mut self) -> TryParseResult<VariantGreen> {
2386 let attributes = self.try_parse_attribute_list("Enum variant");
2387 let (name, attributes) = match attributes {
2388 Ok(attributes) => (self.parse_identifier(), attributes),
2389 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, vec![])),
2390 };
2391
2392 let type_clause = self.parse_option_type_clause();
2393 Ok(Variant::new_green(self.db, attributes, name, type_clause))
2394 }
2395
2396 fn parse_path(&mut self) -> ExprPathGreen {
2399 let mut children: Vec<ExprPathElementOrSeparatorGreen> = vec![];
2400 loop {
2401 let (segment, optional_separator) = self.parse_path_segment();
2402 children.push(segment.into());
2403
2404 if let Some(separator) = optional_separator {
2405 children.push(separator.into());
2406 continue;
2407 }
2408 break;
2409 }
2410
2411 ExprPath::new_green(self.db, children)
2412 }
2413 fn try_parse_path(&mut self) -> TryParseResult<ExprPathGreen> {
2415 if self.is_peek_identifier_like() {
2416 Ok(self.parse_path())
2417 } else {
2418 Err(TryParseFailure::SkipToken)
2419 }
2420 }
2421
2422 fn parse_type_path(&mut self) -> ExprPathGreen {
2426 let mut children: Vec<ExprPathElementOrSeparatorGreen> = vec![];
2427 loop {
2428 let (segment, optional_separator) = self.parse_type_path_segment();
2429 children.push(segment.into());
2430
2431 if let Some(separator) = optional_separator {
2432 children.push(separator.into());
2433 continue;
2434 }
2435 break;
2436 }
2437
2438 ExprPath::new_green(self.db, children)
2439 }
2440
2441 fn parse_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
2443 let identifier = match self.try_parse_identifier() {
2444 Ok(identifier) => identifier,
2445 Err(_) => {
2446 return (
2447 self.create_and_report_missing::<PathSegment>(
2448 ParserDiagnosticKind::MissingPathSegment,
2449 ),
2450 None,
2452 );
2453 }
2454 };
2455 match self.try_parse_token::<TerminalColonColon>() {
2456 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
2457 PathSegmentWithGenericArgs::new_green(
2458 self.db,
2459 identifier,
2460 separator.into(),
2461 self.expect_generic_args(),
2462 )
2463 .into(),
2464 self.try_parse_token::<TerminalColonColon>().ok(),
2465 ),
2466 optional_separator => {
2467 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
2468 }
2469 }
2470 }
2471
2472 fn parse_type_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
2475 let identifier = match self.try_parse_identifier() {
2476 Ok(identifier) => identifier,
2477 Err(_) => {
2478 return (
2479 self.create_and_report_missing::<PathSegment>(
2480 ParserDiagnosticKind::MissingPathSegment,
2481 ),
2482 None,
2484 );
2485 }
2486 };
2487 match self.try_parse_token::<TerminalColonColon>() {
2488 Err(_) if self.peek().kind == SyntaxKind::TerminalLT => (
2489 PathSegmentWithGenericArgs::new_green(
2490 self.db,
2491 identifier,
2492 OptionTerminalColonColonEmpty::new_green(self.db).into(),
2493 self.expect_generic_args(),
2494 )
2495 .into(),
2496 None,
2497 ),
2498 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
2501 PathSegmentWithGenericArgs::new_green(
2502 self.db,
2503 identifier,
2504 separator.into(),
2505 self.expect_generic_args(),
2506 )
2507 .into(),
2508 self.try_parse_token::<TerminalColonColon>().ok(),
2509 ),
2510 optional_separator => {
2511 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
2512 }
2513 }
2514 }
2515
2516 fn take_terminal_literal_number(&mut self) -> TerminalLiteralNumberGreen {
2518 let text = self.peek().text.clone();
2519 let green = self.take::<TerminalLiteralNumber>();
2520 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2521
2522 validate_literal_number(self.diagnostics, text, span, self.file_id);
2523 green
2524 }
2525
2526 fn take_terminal_short_string(&mut self) -> TerminalShortStringGreen {
2528 let text = self.peek().text.clone();
2529 let green = self.take::<TerminalShortString>();
2530 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2531
2532 validate_short_string(self.diagnostics, text, span, self.file_id);
2533 green
2534 }
2535
2536 fn take_terminal_string(&mut self) -> TerminalStringGreen {
2538 let text = self.peek().text.clone();
2539 let green = self.take::<TerminalString>();
2540 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2541
2542 validate_string(self.diagnostics, text, span, self.file_id);
2543 green
2544 }
2545
2546 fn try_parse_generic_arg(&mut self) -> TryParseResult<GenericArgGreen> {
2550 if self.peek().kind == SyntaxKind::TerminalUnderscore {
2551 let underscore = self.take::<TerminalUnderscore>().into();
2552 return Ok(GenericArgUnnamed::new_green(self.db, underscore).into());
2553 }
2554
2555 let expr = match self.peek().kind {
2556 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
2557 SyntaxKind::TerminalMinus => {
2558 let op = self.take::<TerminalMinus>().into();
2559 let expr = self.parse_token::<TerminalLiteralNumber>().into();
2560 ExprUnary::new_green(self.db, op, expr).into()
2561 }
2562 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
2563 SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
2564 SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
2565 SyntaxKind::TerminalLBrace => self.parse_block().into(),
2566 _ => self.try_parse_type_expr()?,
2567 };
2568
2569 if self.peek().kind == SyntaxKind::TerminalColon {
2572 if let Some(argname) = self.try_extract_identifier(expr) {
2573 let colon = self.take::<TerminalColon>();
2574 let expr = if self.peek().kind == SyntaxKind::TerminalUnderscore {
2575 self.take::<TerminalUnderscore>().into()
2576 } else {
2577 let expr = self.parse_type_expr();
2578 GenericArgValueExpr::new_green(self.db, expr).into()
2579 };
2580 return Ok(GenericArgNamed::new_green(self.db, argname, colon, expr).into());
2581 }
2582 }
2583 Ok(GenericArgUnnamed::new_green(
2584 self.db,
2585 GenericArgValueExpr::new_green(self.db, expr).into(),
2586 )
2587 .into())
2588 }
2589
2590 fn expect_generic_args(&mut self) -> GenericArgsGreen {
2593 let langle = self.take::<TerminalLT>();
2594 let generic_args = GenericArgList::new_green(
2595 self.db,
2596 self.parse_separated_list::<GenericArg, TerminalComma, GenericArgListElementOrSeparatorGreen>(
2597 Self::try_parse_generic_arg,
2598 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
2599 "generic arg",
2600 ),
2601 );
2602 let rangle = self.parse_token::<TerminalGT>();
2603 GenericArgs::new_green(self.db, langle, generic_args, rangle)
2604 }
2605
2606 fn expect_generic_params(&mut self) -> WrappedGenericParamListGreen {
2609 let langle = self.take::<TerminalLT>();
2610 let generic_params = GenericParamList::new_green(
2611 self.db,
2612 self.parse_separated_list::<GenericParam, TerminalComma, GenericParamListElementOrSeparatorGreen>(
2613 Self::try_parse_generic_param,
2614 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
2615 "generic param",
2616 ),
2617 );
2618 let rangle = self.parse_token::<TerminalGT>();
2619 WrappedGenericParamList::new_green(self.db, langle, generic_params, rangle)
2620 }
2621
2622 fn parse_optional_generic_params(&mut self) -> OptionWrappedGenericParamListGreen {
2623 if self.peek().kind != SyntaxKind::TerminalLT {
2624 return OptionWrappedGenericParamListEmpty::new_green(self.db).into();
2625 }
2626 self.expect_generic_params().into()
2627 }
2628
2629 fn try_parse_generic_param(&mut self) -> TryParseResult<GenericParamGreen> {
2630 match self.peek().kind {
2631 SyntaxKind::TerminalConst => {
2632 let const_kw = self.take::<TerminalConst>();
2633 let name = self.parse_identifier();
2634 let colon = self.parse_token::<TerminalColon>();
2635 let ty = self.parse_type_expr();
2636 Ok(GenericParamConst::new_green(self.db, const_kw, name, colon, ty).into())
2637 }
2638 SyntaxKind::TerminalImpl => {
2639 let impl_kw = self.take::<TerminalImpl>();
2640 let name = self.parse_identifier();
2641 let colon = self.parse_token::<TerminalColon>();
2642 let trait_path = self.parse_type_path();
2643 let associated_item_constraints = self.parse_optional_associated_item_constraints();
2644 Ok(GenericParamImplNamed::new_green(
2645 self.db,
2646 impl_kw,
2647 name,
2648 colon,
2649 trait_path,
2650 associated_item_constraints,
2651 )
2652 .into())
2653 }
2654 SyntaxKind::TerminalPlus => {
2655 let plus = self.take::<TerminalPlus>();
2656 let trait_path = self.parse_type_path();
2657 let associated_item_constraints = self.parse_optional_associated_item_constraints();
2658 Ok(GenericParamImplAnonymous::new_green(
2659 self.db,
2660 plus,
2661 trait_path,
2662 associated_item_constraints,
2663 )
2664 .into())
2665 }
2666 SyntaxKind::TerminalMinus => {
2667 let minus = self.take::<TerminalMinus>();
2668 let trait_path = self.parse_type_path();
2669 Ok(GenericParamNegativeImpl::new_green(self.db, minus, trait_path).into())
2670 }
2671 _ => Ok(GenericParamType::new_green(self.db, self.try_parse_identifier()?).into()),
2672 }
2673 }
2674
2675 fn expect_associated_item_constraints(&mut self) -> AssociatedItemConstraintsGreen {
2678 let lbrack = self.take::<TerminalLBrack>();
2679 let associated_item_constraints_list = AssociatedItemConstraintList::new_green(
2680 self.db,
2681 self.parse_separated_list::<AssociatedItemConstraint, TerminalComma, AssociatedItemConstraintListElementOrSeparatorGreen>(
2682 Self::try_parse_associated_item_constraint,
2683 is_of_kind!(rbrack,rangle, rparen, block, lbrace, rbrace, module_item_kw),
2684 "associated type argument",
2685 ),
2686 );
2687 let rangle = self.parse_token::<TerminalRBrack>();
2688 AssociatedItemConstraints::new_green(
2689 self.db,
2690 lbrack,
2691 associated_item_constraints_list,
2692 rangle,
2693 )
2694 }
2695
2696 fn parse_optional_associated_item_constraints(
2697 &mut self,
2698 ) -> OptionAssociatedItemConstraintsGreen {
2699 if self.peek().kind != SyntaxKind::TerminalLBrack {
2700 return OptionAssociatedItemConstraintsEmpty::new_green(self.db).into();
2701 }
2702 self.expect_associated_item_constraints().into()
2703 }
2704
2705 fn try_parse_associated_item_constraint(
2708 &mut self,
2709 ) -> TryParseResult<AssociatedItemConstraintGreen> {
2710 let ident = self.try_parse_identifier()?;
2711 let colon = self.parse_token::<TerminalColon>();
2712 let ty = self.parse_type_expr();
2713 Ok(AssociatedItemConstraint::new_green(self.db, ident, colon, ty))
2714 }
2715
2716 fn parse_list<ElementGreen>(
2728 &mut self,
2729 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
2730 should_stop: fn(SyntaxKind) -> bool,
2731 expected_element: &str,
2732 ) -> Vec<ElementGreen> {
2733 let mut children: Vec<ElementGreen> = Vec::new();
2734 loop {
2735 let parse_result = try_parse_list_element(self);
2736 match parse_result {
2737 Ok(element_green) => {
2738 children.push(element_green);
2739 }
2740 Err(err) => {
2741 if should_stop(self.peek().kind) {
2742 break;
2743 }
2744 if err == TryParseFailure::SkipToken {
2745 self.skip_token(ParserDiagnosticKind::SkippedElement {
2746 element_name: expected_element.into(),
2747 });
2748 }
2749 }
2750 }
2751 }
2752 children
2753 }
2754
2755 fn parse_attributed_list<ElementGreen>(
2766 &mut self,
2767 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
2768 should_stop: fn(SyntaxKind) -> bool,
2769 expected_element: &str,
2770 ) -> Vec<ElementGreen> {
2771 self.parse_list::<ElementGreen>(
2772 try_parse_list_element,
2773 should_stop,
2774 &or_an_attribute!(expected_element),
2775 )
2776 }
2777
2778 fn parse_separated_list_inner<
2795 Element: TypedSyntaxNode,
2796 Separator: syntax::node::Terminal,
2797 ElementOrSeparatorGreen,
2798 >(
2799 &mut self,
2800 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
2801 should_stop: fn(SyntaxKind) -> bool,
2802 expected_element: &'static str,
2803 forbid_trailing_separator: Option<ParserDiagnosticKind>,
2804 ) -> Vec<ElementOrSeparatorGreen>
2805 where
2806 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
2807 {
2808 let mut children: Vec<ElementOrSeparatorGreen> = Vec::new();
2809 loop {
2810 match try_parse_list_element(self) {
2811 Err(_) if should_stop(self.peek().kind) => {
2812 if let (Some(diagnostic_kind), true) =
2813 (forbid_trailing_separator, !children.is_empty())
2814 {
2815 self.add_diagnostic(
2816 diagnostic_kind,
2817 TextSpan { start: self.offset, end: self.offset },
2818 );
2819 }
2820 break;
2821 }
2822 Err(_) => {
2823 self.skip_token(ParserDiagnosticKind::SkippedElement {
2824 element_name: expected_element.into(),
2825 });
2826 continue;
2827 }
2828 Ok(element) => {
2829 children.push(element.into());
2830 }
2831 };
2832
2833 let separator = match self.try_parse_token::<Separator>() {
2834 Err(_) if should_stop(self.peek().kind) => {
2835 break;
2836 }
2837 Err(_) => self.create_and_report_missing::<Separator>(
2838 ParserDiagnosticKind::MissingToken(Separator::KIND),
2839 ),
2840 Ok(separator) => separator,
2841 };
2842 children.push(separator.into());
2843 }
2844 children
2845 }
2846 fn parse_separated_list<
2848 Element: TypedSyntaxNode,
2849 Separator: syntax::node::Terminal,
2850 ElementOrSeparatorGreen,
2851 >(
2852 &mut self,
2853 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
2854 should_stop: fn(SyntaxKind) -> bool,
2855 expected_element: &'static str,
2856 ) -> Vec<ElementOrSeparatorGreen>
2857 where
2858 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
2859 {
2860 self.parse_separated_list_inner::<Element, Separator, ElementOrSeparatorGreen>(
2861 try_parse_list_element,
2862 should_stop,
2863 expected_element,
2864 None,
2865 )
2866 }
2867
2868 fn peek(&self) -> &LexerTerminal {
2870 &self.next_terminal
2871 }
2872
2873 fn take_raw(&mut self) -> LexerTerminal {
2875 self.offset = self.offset.add_width(self.current_width);
2876 self.current_width = self.next_terminal.width(self.db);
2877 self.last_trivia_length = trivia_total_width(self.db, &self.next_terminal.trailing_trivia);
2878
2879 let next_terminal = self.lexer.next().unwrap();
2880 std::mem::replace(&mut self.next_terminal, next_terminal)
2881 }
2882
2883 fn skip_token(&mut self, diagnostic_kind: ParserDiagnosticKind) {
2887 if self.peek().kind == SyntaxKind::TerminalEndOfFile {
2888 self.add_diagnostic(diagnostic_kind, TextSpan { start: self.offset, end: self.offset });
2889 return;
2890 }
2891 let terminal = self.take_raw();
2892 self.append_skipped_token_to_pending_trivia(terminal, diagnostic_kind);
2893 }
2894
2895 fn append_skipped_token_to_pending_trivia(
2898 &mut self,
2899 terminal: LexerTerminal,
2900 diagnostic_kind: ParserDiagnosticKind,
2901 ) {
2902 let orig_offset = self.offset;
2903 let diag_start =
2904 self.offset.add_width(trivia_total_width(self.db, &terminal.leading_trivia));
2905 let diag_end = diag_start.add_width(TextWidth::from_str(&terminal.text));
2906
2907 self.pending_trivia.extend(terminal.leading_trivia.clone());
2909 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
2910 self.pending_trivia.extend(terminal.trailing_trivia.clone());
2911 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
2912 kind: diagnostic_kind,
2913 span: TextSpan { start: diag_start, end: diag_end },
2914 leading_trivia_start: orig_offset,
2915 trailing_trivia_end: diag_end
2916 .add_width(trivia_total_width(self.db, &terminal.trailing_trivia)),
2917 });
2918 }
2919
2920 fn skip_taken_node_from_current_offset(
2923 &mut self,
2924 node_to_skip: impl Into<SkippedNodeGreen>,
2925 diagnostic_kind: ParserDiagnosticKind,
2926 ) {
2927 self.skip_taken_node_with_offset(
2928 node_to_skip,
2929 diagnostic_kind,
2930 self.offset.add_width(self.current_width),
2931 )
2932 }
2933
2934 fn skip_taken_node_with_offset(
2940 &mut self,
2941 node_to_skip: impl Into<SkippedNodeGreen>,
2942 diagnostic_kind: ParserDiagnosticKind,
2943 end_of_node_offset: TextOffset,
2944 ) {
2945 let trivium_green = TriviumSkippedNode::new_green(self.db, node_to_skip.into()).into();
2946
2947 self.pending_trivia.push(trivium_green);
2949
2950 let start_of_node_offset = end_of_node_offset.sub_width(trivium_green.0.width(self.db));
2951 let diag_pos = end_of_node_offset
2952 .sub_width(trailing_trivia_width(self.db, trivium_green.0).unwrap_or_default());
2953
2954 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
2955 kind: diagnostic_kind,
2956 span: TextSpan { start: diag_pos, end: diag_pos },
2957 leading_trivia_start: start_of_node_offset,
2958 trailing_trivia_end: end_of_node_offset,
2959 });
2960 }
2961
2962 fn skip_token_and_return_missing<ExpectedTerminal: syntax::node::Terminal>(
2965 &mut self,
2966 diagnostic: ParserDiagnosticKind,
2967 ) -> ExpectedTerminal::Green {
2968 self.skip_token(diagnostic);
2969 ExpectedTerminal::missing(self.db)
2970 }
2971
2972 fn skip_taken_node_and_return_missing<ExpectedNode: TypedSyntaxNode>(
2975 &mut self,
2976 node_to_skip: impl Into<SkippedNodeGreen>,
2977 diagnostic_kind: ParserDiagnosticKind,
2978 ) -> ExpectedNode::Green {
2979 self.skip_taken_node_from_current_offset(node_to_skip, diagnostic_kind);
2980 ExpectedNode::missing(self.db)
2981 }
2982
2983 fn skip_until(&mut self, should_stop: fn(SyntaxKind) -> bool) -> Result<(), SkippedError> {
2987 let mut diag_start = None;
2988 let mut diag_end = None;
2989 while !should_stop(self.peek().kind) {
2990 let terminal = self.take_raw();
2991 diag_start.get_or_insert(self.offset);
2992 diag_end = Some(self.offset.add_width(TextWidth::from_str(&terminal.text)));
2993
2994 self.pending_trivia.extend(terminal.leading_trivia);
2995 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
2996 self.pending_trivia.extend(terminal.trailing_trivia);
2997 }
2998 if let (Some(diag_start), Some(diag_end)) = (diag_start, diag_end) {
2999 Err(SkippedError(TextSpan { start: diag_start, end: diag_end }))
3000 } else {
3001 Ok(())
3002 }
3003 }
3004
3005 fn add_trivia_to_terminal<Terminal: syntax::node::Terminal>(
3008 &mut self,
3009 lexer_terminal: LexerTerminal,
3010 ) -> Terminal::Green {
3011 let LexerTerminal { text, kind: _, leading_trivia, trailing_trivia } = lexer_terminal;
3012 let token = Terminal::TokenType::new_green(self.db, text);
3013 let mut new_leading_trivia = mem::take(&mut self.pending_trivia);
3014
3015 self.consume_pending_skipped_diagnostics();
3016
3017 new_leading_trivia.extend(leading_trivia);
3018 Terminal::new_green(
3019 self.db,
3020 Trivia::new_green(self.db, new_leading_trivia),
3021 token,
3022 Trivia::new_green(self.db, trailing_trivia),
3023 )
3024 }
3025
3026 fn consume_pending_skipped_diagnostics(&mut self) {
3029 let mut pending_skipped = self.pending_skipped_token_diagnostics.drain(..);
3030 let Some(first) = pending_skipped.next() else {
3031 return;
3032 };
3033
3034 let mut current_diag = first;
3035
3036 for diag in pending_skipped {
3037 if diag.kind == current_diag.kind
3038 && current_diag.trailing_trivia_end == diag.leading_trivia_start
3039 {
3040 current_diag = PendingParserDiagnostic {
3042 span: TextSpan { start: current_diag.span.start, end: diag.span.end },
3043 kind: diag.kind,
3044 leading_trivia_start: current_diag.leading_trivia_start,
3045 trailing_trivia_end: diag.trailing_trivia_end,
3046 };
3047 } else {
3048 self.diagnostics.add(ParserDiagnostic {
3051 file_id: self.file_id,
3052 span: current_diag.span,
3053 kind: current_diag.kind,
3054 });
3055 current_diag = diag;
3056 }
3057 }
3058 self.add_diagnostic(current_diag.kind, current_diag.span);
3060 }
3061
3062 fn take<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
3065 let token = self.take_raw();
3066 assert_eq!(token.kind, Terminal::KIND);
3067 self.add_trivia_to_terminal::<Terminal>(token)
3068 }
3069
3070 fn take_doc(&mut self) -> Option<ItemHeaderDocGreen> {
3074 let mut has_header_doc = false;
3078 let mut split_index = 0;
3079 for trivium in self.next_terminal.leading_trivia.iter() {
3080 match trivium.0.lookup_intern(self.db).kind {
3081 SyntaxKind::TokenSingleLineComment | SyntaxKind::TokenSingleLineInnerComment => {
3082 has_header_doc = true;
3083 }
3084 SyntaxKind::TokenSingleLineDocComment => {
3085 break;
3086 }
3087 _ => {}
3088 }
3089 split_index += 1;
3090 }
3091 if !has_header_doc {
3092 return None;
3093 }
3094 let leading_trivia = self.next_terminal.leading_trivia.clone();
3096 let (header_doc, rest) = leading_trivia.split_at(split_index);
3097 self.next_terminal.leading_trivia = rest.to_vec();
3098 let empty_lexer_terminal = LexerTerminal {
3099 text: "".into(),
3100 kind: SyntaxKind::TerminalEmpty,
3101 leading_trivia: header_doc.to_vec(),
3102 trailing_trivia: vec![],
3103 };
3104 self.offset = self.offset.add_width(empty_lexer_terminal.width(self.db));
3105
3106 let empty_terminal = self.add_trivia_to_terminal::<TerminalEmpty>(empty_lexer_terminal);
3107 Some(ItemHeaderDoc::new_green(self.db, empty_terminal))
3108 }
3109
3110 fn try_parse_token<Terminal: syntax::node::Terminal>(
3115 &mut self,
3116 ) -> TryParseResult<Terminal::Green> {
3117 if Terminal::KIND == self.peek().kind {
3118 Ok(self.take::<Terminal>())
3119 } else {
3120 Err(TryParseFailure::SkipToken)
3121 }
3122 }
3123
3124 fn parse_token<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
3130 self.parse_token_ex::<Terminal>(true)
3131 }
3132
3133 fn parse_token_ex<Terminal: syntax::node::Terminal>(
3135 &mut self,
3136 report_diagnostic: bool,
3137 ) -> Terminal::Green {
3138 match self.try_parse_token::<Terminal>() {
3139 Ok(green) => green,
3140 Err(_) => {
3141 if report_diagnostic {
3142 self.create_and_report_missing_terminal::<Terminal>()
3143 } else {
3144 Terminal::missing(self.db)
3145 }
3146 }
3147 }
3148 }
3149}
3150
3151#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3160enum LbraceAllowed {
3161 Forbid,
3162 Allow,
3163}
3164
3165struct SkippedError(TextSpan);
3167
3168struct ErrorRecovery {
3170 should_stop: fn(SyntaxKind) -> bool,
3173}
3174
3175enum ExternItem {
3176 Function(ItemExternFunctionGreen),
3177 Type(ItemExternTypeGreen),
3178}
3179
3180#[derive(Debug)]
3181enum ImplItemOrAlias {
3182 Item(ItemImplGreen),
3183 Alias(ItemImplAliasGreen),
3184}
3185
3186pub struct PendingParserDiagnostic {
3189 pub span: TextSpan,
3190 pub kind: ParserDiagnosticKind,
3191 pub leading_trivia_start: TextOffset,
3192 pub trailing_trivia_end: TextOffset,
3193}
3194
3195fn trivia_total_width(db: &dyn SyntaxGroup, trivia: &[TriviumGreen]) -> TextWidth {
3197 trivia.iter().map(|trivium| trivium.0.width(db)).sum::<TextWidth>()
3198}
3199
3200fn trailing_trivia_width(db: &dyn SyntaxGroup, green_id: GreenId) -> Option<TextWidth> {
3202 let node = green_id.lookup_intern(db);
3203 if node.kind == SyntaxKind::Trivia {
3204 return Some(node.width());
3205 }
3206 match &node.details {
3207 GreenNodeDetails::Token(_) => Some(TextWidth::default()),
3208 GreenNodeDetails::Node { children, .. } => {
3209 for child in children.iter().rev() {
3210 if let Some(width) = trailing_trivia_width(db, *child) {
3211 return Some(width);
3212 }
3213 }
3214 None
3215 }
3216 }
3217}